001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.jbi.resolver;
018    
019    import javax.jbi.JBIException;
020    import javax.jbi.component.ComponentContext;
021    import javax.jbi.messaging.MessageExchange;
022    import javax.jbi.servicedesc.ServiceEndpoint;
023    
024    import org.apache.servicemix.jbi.api.EndpointFilter;
025    
026    /**
027     * A useful base class for {@link EndpointResolver} implementations.
028     *
029     * @version $Revision: 690190 $
030     */
031    public abstract class EndpointResolverSupport implements EndpointResolver {
032        private EndpointChooser chooser;
033        private boolean failIfUnavailable = true;
034    
035        public ServiceEndpoint resolveEndpoint(ComponentContext context, MessageExchange exchange, EndpointFilter filter) throws JBIException {
036            ServiceEndpoint[] endpoints = resolveAvailableEndpoints(context, exchange);
037            if (endpoints == null) {
038                return null;
039            }
040            if (endpoints.length > 0) {
041                endpoints = filterEndpoints(endpoints, exchange, filter);
042            }
043            if (endpoints.length == 0) {
044                if (failIfUnavailable) {
045                    throw createServiceUnavailableException();
046                } else {
047                    return null;
048                }
049            }
050            if (endpoints.length == 1) {
051                return endpoints[0];
052            }
053            return getChooser().chooseEndpoint(endpoints, context, exchange);
054        }
055    
056        public boolean isFailIfUnavailable() {
057            return failIfUnavailable;
058        }
059    
060        public void setFailIfUnavailable(boolean failIfUnavailable) {
061            this.failIfUnavailable = failIfUnavailable;
062        }
063    
064        public EndpointChooser getChooser() {
065            if (chooser == null) {
066                chooser = new FirstChoicePolicy();
067            }
068            return chooser;
069        }
070    
071        public void setChooser(EndpointChooser chooser) {
072            this.chooser = chooser;
073        }
074    
075        protected abstract JBIException createServiceUnavailableException();
076    
077        protected ServiceEndpoint[] filterEndpoints(ServiceEndpoint[] endpoints, MessageExchange exchange, EndpointFilter filter) {
078            int matches = 0;
079            for (int i = 0; i < endpoints.length; i++) {
080                ServiceEndpoint endpoint = endpoints[i];
081                if (filter.evaluate(endpoint, exchange)) {
082                    matches++;
083                }  else {
084                    endpoints[i] = null;
085                }
086            }
087            if (matches == endpoints.length) {
088                return endpoints;
089            } else {
090                ServiceEndpoint[] answer = new ServiceEndpoint[matches];
091                int j = 0;
092                for (int i = 0; i < endpoints.length; i++) {
093                    ServiceEndpoint endpoint = endpoints[i];
094                    if (endpoint != null) {
095                        answer[j++] = endpoints[i];
096                    }
097                }
098                return answer;
099            }
100        }
101    }