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.common.osgi;
018    
019    import java.util.Map;
020    import java.util.concurrent.ConcurrentHashMap;
021    
022    import javax.jbi.management.DeploymentException;
023    
024    import org.apache.servicemix.common.Endpoint;
025    import org.apache.servicemix.common.DefaultComponent;
026    import org.apache.servicemix.common.DefaultServiceUnit;
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    
030    public class EndpointTracker {
031    
032        private static final Log LOGGER = LogFactory.getLog(EndpointTracker.class);
033    
034        protected DefaultComponent component;
035        protected Map<EndpointWrapper, OsgiServiceUnit> endpoints = new ConcurrentHashMap<EndpointWrapper, OsgiServiceUnit>();
036    
037        public DefaultComponent getComponent() {
038            return component;
039        }
040    
041        public void setComponent(DefaultComponent component) {
042            this.component = component;
043        }
044    
045        public void register(EndpointWrapper wrapper, Map properties) throws Exception {
046            if (LOGGER.isDebugEnabled()) {
047                LOGGER.debug("[" + component.getComponentName() + "] Endpoint registered with properties: " + properties);
048            }
049            Endpoint endpoint = wrapper.getEndpoint();
050            if (component.isKnownEndpoint(endpoint)) {
051                if (LOGGER.isDebugEnabled()) {
052                    LOGGER.debug("[" + component.getComponentName() + "] Endpoint recognized");
053                }
054                OsgiServiceUnit su = new OsgiServiceUnit(component, endpoint, wrapper.getClassLoader());
055                endpoints.put(wrapper, su);
056                component.getRegistry().registerServiceUnit(su);
057            }
058        }
059    
060        public void unregister(EndpointWrapper wrapper, Map properties) throws Exception {
061            if (LOGGER.isDebugEnabled()) {
062                LOGGER.debug("[" + component.getComponentName() + "] Endpoint unregistered with properties: " + properties);
063            }
064            // Do not access the wrapper using wrapper.getEndpoint(), has the osgi context may already be shut down
065            OsgiServiceUnit su = endpoints.remove(wrapper);
066            if (su != null && component.isKnownEndpoint(su.getEndpoint())) {
067                if (LOGGER.isDebugEnabled()) {
068                    LOGGER.debug("[" + component.getComponentName() + "] Endpoint recognized");
069                }
070                component.getRegistry().unregisterServiceUnit(su);
071            }
072        }
073    
074        public static class OsgiServiceUnit extends DefaultServiceUnit {
075            private final Endpoint endpoint;
076            private final ClassLoader classLoader;
077            public OsgiServiceUnit(DefaultComponent component, Endpoint endpoint, ClassLoader classLoader) throws DeploymentException {
078                this.component = component;
079                this.endpoint = endpoint;
080                this.classLoader = classLoader;
081                this.endpoint.setServiceUnit(this);
082                this.endpoint.validate();
083                this.name = endpoint.getKey();
084                addEndpoint(this.endpoint);
085            }
086            public Endpoint getEndpoint() {
087                return endpoint;
088            }
089            public ClassLoader  getConfigurationClassLoader() {
090                if (classLoader != null) {
091                    return classLoader;
092                } else {
093                    return super.getConfigurationClassLoader();
094                }
095            }
096        }
097    
098    }