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.geronimo.kernel.config;
018    
019    import java.util.Collection;
020    
021    import org.apache.geronimo.kernel.Kernel;
022    import org.apache.geronimo.kernel.GBeanNotFoundException;
023    import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
024    import org.apache.geronimo.kernel.repository.Artifact;
025    import org.apache.geronimo.kernel.repository.ArtifactResolver;
026    import org.apache.geronimo.kernel.repository.ArtifactManager;
027    import org.apache.geronimo.kernel.management.State;
028    import org.apache.geronimo.gbean.GBeanData;
029    import org.apache.geronimo.gbean.GBeanInfo;
030    import org.apache.geronimo.gbean.GBeanInfoBuilder;
031    import org.apache.geronimo.gbean.AbstractName;
032    
033    /**
034     * Standard implementation of an editable ConfigurationManager.
035     *
036     * @version $Rev:386276 $ $Date: 2007-07-13 09:39:25 -0400 (Fri, 13 Jul 2007) $
037     */
038    public class EditableKernelConfigurationManager extends KernelConfigurationManager implements EditableConfigurationManager {
039        public EditableKernelConfigurationManager(Kernel kernel,
040                Collection stores,
041                ManageableAttributeStore attributeStore,
042                PersistentConfigurationList configurationList,
043                ArtifactManager artifactManager,
044                ArtifactResolver artifactResolver,
045                Collection repositories,
046                Collection watchers,
047                ClassLoader classLoader) {
048            super(kernel, stores, attributeStore, configurationList, artifactManager, artifactResolver, repositories, watchers, classLoader);
049        }
050    
051        public void addGBeanToConfiguration(Artifact configurationId, GBeanData gbean, boolean start) throws InvalidConfigException {
052            Configuration configuration = getConfiguration(configurationId);
053    
054            try {
055                // add the gbean to the configuration
056                configuration.addGBean(gbean);
057            } catch (GBeanAlreadyExistsException e) {
058                throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e);
059            }
060    
061            addGBeanToConfiguration(configuration, gbean, start);
062        }
063    
064        public void addGBeanToConfiguration(Artifact configurationId, String name, GBeanData gbean, boolean start) throws InvalidConfigException {
065            Configuration configuration = getConfiguration(configurationId);
066    
067            try {
068                // add the gbean to the configuration
069                configuration.addGBean(name, gbean);
070            } catch (GBeanAlreadyExistsException e) {
071                throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e);
072            }
073    
074            addGBeanToConfiguration(configuration, gbean, start);
075        }
076    
077        private void addGBeanToConfiguration(Configuration configuration, GBeanData gbean, boolean start) throws InvalidConfigException {
078            ClassLoader configurationClassLoader = configuration.getConfigurationClassLoader();
079            ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
080            try {
081                Thread.currentThread().setContextClassLoader(configurationClassLoader);
082    
083                log.trace("Registering GBean " + gbean.getAbstractName());
084    
085    
086                // preprocess the gbean data before loading it into the kernel
087                ConfigurationUtil.preprocessGBeanData(configuration.getAbstractName(), configuration, gbean);
088    
089                // register the bean with the kernel
090                kernel.loadGBean(gbean, configurationClassLoader);
091    
092                // start the configuration
093                if (start) {
094                    try {
095                        kernel.startRecursiveGBean(gbean.getAbstractName());
096                    } catch (GBeanNotFoundException e) {
097                        throw new InvalidConfigException("How could we not find a GBean that we just loaded ('" + gbean.getAbstractName() + "')?", e);
098                    }
099                }
100    
101            } catch(Exception e) {
102                // clean up failed gbean
103                try {
104                    configuration.removeGBean(gbean.getAbstractName());
105                } catch (GBeanNotFoundException e1) {
106                    // this is good
107                }
108                try {
109                    kernel.stopGBean(gbean.getAbstractName());
110                } catch (GBeanNotFoundException e1) {
111                    // this is good
112                }
113                try {
114                    kernel.unloadGBean(gbean.getAbstractName());
115                } catch (GBeanNotFoundException e1) {
116                    // this is good
117                }
118    
119                if (e instanceof InvalidConfigException) {
120                    throw (InvalidConfigException) e;
121                }
122                throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configuration.getId(), e);
123            } finally {
124                Thread.currentThread().setContextClassLoader(oldCl);
125            }
126    
127            if (attributeStore != null) {
128                attributeStore.addGBean(configuration.getId(), gbean, configurationClassLoader);
129            }
130        }
131    
132        public void removeGBeanFromConfiguration(Artifact configurationId, AbstractName gbeanName) throws GBeanNotFoundException, InvalidConfigException {
133            Configuration configuration = getConfiguration(configurationId);
134            if (!configuration.containsGBean(gbeanName)) {
135                throw new GBeanNotFoundException(gbeanName);
136            }
137            configuration.removeGBean(gbeanName);
138    
139            try {
140                if (kernel.getGBeanState(gbeanName) == State.RUNNING_INDEX) {
141                    kernel.stopGBean(gbeanName);
142                }
143                kernel.unloadGBean(gbeanName);
144            } catch (GBeanNotFoundException e) {
145                // Bean is no longer loaded
146            }
147    
148            // Make sure it's not loaded next time the configuration is loaded
149            if (attributeStore != null) {
150                attributeStore.setShouldLoad(configurationId, gbeanName, false);
151            }
152        }
153    
154        public static final GBeanInfo GBEAN_INFO;
155    
156        static {
157            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(EditableKernelConfigurationManager.class, KernelConfigurationManager.GBEAN_INFO, "ConfigurationManager");
158            infoFactory.addInterface(EditableConfigurationManager.class);
159            infoFactory.setConstructor(new String[]{"kernel", "Stores", "AttributeStore", "PersistentConfigurationList", "ArtifactManager", "ArtifactResolver", "Repositories", "Watchers", "classLoader"});
160            GBEAN_INFO = infoFactory.getBeanInfo();
161        }
162    
163        public static GBeanInfo getGBeanInfo() {
164            return GBEAN_INFO;
165        }
166    }