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.framework;
018    
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.Collections;
022    import java.util.Iterator;
023    import java.util.LinkedHashMap;
024    import java.util.List;
025    import java.util.Map;
026    
027    import javax.jbi.JBIException;
028    import javax.jbi.component.Component;
029    
030    /**
031     * Registry for Components
032     *
033     * @version $Revision: 564374 $
034     */
035    public class ComponentRegistry {
036        
037        private Map<ComponentNameSpace, ComponentMBeanImpl> idMap = new LinkedHashMap<ComponentNameSpace, ComponentMBeanImpl>();
038        private boolean runningStateInitialized;
039        private Registry registry;
040        
041        
042        protected ComponentRegistry(Registry reg) {
043            this.registry = reg;
044        }
045        /**
046         * Register a Component
047         * @param name
048         * @param description
049         * @param component
050         * @param dc
051         * @param binding
052         * @param service
053         * @return an associated ComponentConnector or null if it already exists
054         */
055        public synchronized ComponentMBeanImpl registerComponent(
056                        ComponentNameSpace name, 
057                        String description, 
058                        Component component,
059                        boolean binding, 
060                        boolean service,
061                        String[] sharedLibraries) {
062            ComponentMBeanImpl result = null;
063            if (!idMap.containsKey(name)) {
064                result = new ComponentMBeanImpl(registry.getContainer(), name, description, component, binding, service, sharedLibraries);
065                idMap.put(name, result);
066            }
067            return result;
068        }
069        
070        /**
071         * start components
072         * @throws JBIException
073         */
074        public synchronized void start() throws JBIException {
075            if (!setInitialRunningStateFromStart()) {
076                for (Iterator<ComponentMBeanImpl> i = getComponents().iterator(); i.hasNext();) {
077                    ComponentMBeanImpl lcc = i.next();
078                    lcc.doStart();
079                }
080            }
081        }
082    
083        /**
084         * stop components
085         * @throws JBIException 
086         * 
087         * @throws JBIException
088         */
089        public synchronized void stop() throws JBIException  {
090            for (Iterator<ComponentMBeanImpl> i = getReverseComponents().iterator(); i.hasNext();) {
091                ComponentMBeanImpl lcc = i.next();
092                lcc.doStop();
093            }
094            runningStateInitialized = false;
095        }
096        
097        /**
098         * shutdown all Components
099         * 
100         * @throws JBIException
101         */
102        public synchronized void shutDown() throws JBIException {
103            for (Iterator<ComponentMBeanImpl> i = getReverseComponents().iterator(); i.hasNext();) {
104                ComponentMBeanImpl lcc = i.next();
105                lcc.persistRunningState();
106                lcc.doShutDown();
107            }
108        }
109        
110        private Collection<ComponentMBeanImpl> getReverseComponents() {
111            synchronized (idMap) {
112                List<ComponentMBeanImpl> l = new ArrayList<ComponentMBeanImpl>(idMap.values());
113                Collections.reverse(l);
114                return l;
115            }
116        }
117    
118        
119        /**
120         * Deregister a Component
121         * @param component
122         * @return the deregistered component
123         */
124        public synchronized void deregisterComponent(ComponentMBeanImpl component) {
125            idMap.remove(component.getComponentNameSpace());
126        }
127        
128        /**
129         * Get a registered ComponentConnector from it's id
130         * @param id
131         * @return the ComponentConnector or null
132         */
133        public ComponentMBeanImpl getComponent(ComponentNameSpace id) {
134            synchronized (idMap) {
135                return idMap.get(id);
136            }
137        }
138        
139        /**
140         * 
141         * @return Collection of ComponentConnectors held by the registry
142         */
143        public Collection<ComponentMBeanImpl> getComponents() {
144            synchronized (idMap) {
145                return new ArrayList<ComponentMBeanImpl>(idMap.values());
146            }
147        }
148    
149        private boolean setInitialRunningStateFromStart() throws JBIException {
150            boolean result = !runningStateInitialized;
151            if (!runningStateInitialized) {
152                runningStateInitialized = true;
153                for (Iterator<ComponentMBeanImpl> i = getComponents().iterator(); i.hasNext();) {
154                    ComponentMBeanImpl lcc = i.next();
155                    if (!lcc.isPojo() && !registry.isContainerEmbedded()) {
156                        lcc.setInitialRunningState();
157                    } else {
158                        lcc.doStart();
159                    }
160                }
161            }
162            return result;
163        }
164    }