001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.kernel.config;
019    
020    import java.util.Collection;
021    
022    import org.apache.geronimo.kernel.Kernel;
023    import org.apache.geronimo.kernel.GBeanNotFoundException;
024    import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
025    import org.apache.geronimo.kernel.repository.Artifact;
026    import org.apache.geronimo.kernel.repository.ArtifactResolver;
027    import org.apache.geronimo.kernel.repository.ArtifactManager;
028    import org.apache.geronimo.kernel.management.State;
029    import org.apache.geronimo.gbean.GBeanData;
030    import org.apache.geronimo.gbean.GBeanInfo;
031    import org.apache.geronimo.gbean.GBeanInfoBuilder;
032    import org.apache.geronimo.gbean.AbstractName;
033    
034    /**
035     * Standard implementation of an editable ConfigurationManager.
036     *
037     * @version $Rev:386276 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
038     */
039    public class EditableKernelConfigurationManager extends KernelConfigurationManager implements EditableConfigurationManager {
040        public EditableKernelConfigurationManager(Kernel kernel,
041                Collection stores,
042                ManageableAttributeStore attributeStore,
043                PersistentConfigurationList configurationList,
044                ArtifactManager artifactManager,
045                ArtifactResolver artifactResolver,
046                Collection repositories,
047                Collection watchers,
048                ClassLoader classLoader) {
049            super(kernel, stores, attributeStore, configurationList, artifactManager, artifactResolver, repositories, watchers, classLoader);
050        }
051    
052        public void addGBeanToConfiguration(Artifact configurationId, GBeanData gbean, boolean start) throws InvalidConfigException {
053            Configuration configuration = getConfiguration(configurationId);
054    
055            try {
056                // add the gbean to the configuration
057                configuration.addGBean(gbean);
058            } catch (GBeanAlreadyExistsException e) {
059                throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e);
060            }
061    
062            addGBeanToConfiguration(configuration, gbean, start);
063        }
064    
065        public void addGBeanToConfiguration(Artifact configurationId, String name, GBeanData gbean, boolean start) throws InvalidConfigException {
066            Configuration configuration = getConfiguration(configurationId);
067    
068            try {
069                // add the gbean to the configuration
070                configuration.addGBean(name, gbean);
071            } catch (GBeanAlreadyExistsException e) {
072                throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configurationId, e);
073            }
074    
075            addGBeanToConfiguration(configuration, gbean, start);
076        }
077    
078        private void addGBeanToConfiguration(Configuration configuration, GBeanData gbean, boolean start) throws InvalidConfigException {
079            ClassLoader configurationClassLoader = configuration.getConfigurationClassLoader();
080            ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
081            try {
082                Thread.currentThread().setContextClassLoader(configurationClassLoader);
083    
084                log.trace("Registering GBean " + gbean.getAbstractName());
085    
086    
087                // preprocess the gbean data before loading it into the kernel
088                ConfigurationUtil.preprocessGBeanData(configuration.getAbstractName(), configuration, gbean);
089    
090                // register the bean with the kernel
091                kernel.loadGBean(gbean, configurationClassLoader);
092    
093                // start the configuration
094                if (start) {
095                    try {
096                        kernel.startRecursiveGBean(gbean.getAbstractName());
097                    } catch (GBeanNotFoundException e) {
098                        throw new InvalidConfigException("How could we not find a GBean that we just loaded ('" + gbean.getAbstractName() + "')?");
099                    }
100                }
101    
102            } catch(Exception e) {
103                // clean up failed gbean
104                try {
105                    configuration.removeGBean(gbean.getAbstractName());
106                } catch (GBeanNotFoundException e1) {
107                    // this is good
108                }
109                try {
110                    kernel.stopGBean(gbean.getAbstractName());
111                } catch (GBeanNotFoundException e1) {
112                    // this is good
113                }
114                try {
115                    kernel.unloadGBean(gbean.getAbstractName());
116                } catch (GBeanNotFoundException e1) {
117                    // this is good
118                }
119    
120                if (e instanceof InvalidConfigException) {
121                    throw (InvalidConfigException) e;
122                }
123                throw new InvalidConfigException("Cound not add GBean " + gbean.getAbstractName() + " to configuration " + configuration.getId(), e);
124            } finally {
125                Thread.currentThread().setContextClassLoader(oldCl);
126            }
127    
128            if (attributeStore != null) {
129                attributeStore.addGBean(configuration.getId(), gbean);
130            }
131        }
132    
133        public void removeGBeanFromConfiguration(Artifact configurationId, AbstractName gbeanName) throws GBeanNotFoundException, InvalidConfigException {
134            Configuration configuration = getConfiguration(configurationId);
135            if (!configuration.containsGBean(gbeanName)) {
136                throw new GBeanNotFoundException(gbeanName);
137            }
138            configuration.removeGBean(gbeanName);
139    
140            try {
141                if (kernel.getGBeanState(gbeanName) == State.RUNNING_INDEX) {
142                    kernel.stopGBean(gbeanName);
143                }
144                kernel.unloadGBean(gbeanName);
145            } catch (GBeanNotFoundException e) {
146                // Bean is no longer loaded
147            }
148    
149            // Make sure it's not loaded next time the configuration is loaded
150            if (attributeStore != null) {
151                attributeStore.setShouldLoad(configurationId, gbeanName, false);
152            }
153        }
154    
155        public static final GBeanInfo GBEAN_INFO;
156    
157        static {
158            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(EditableKernelConfigurationManager.class, KernelConfigurationManager.GBEAN_INFO, "ConfigurationManager");
159            infoFactory.addInterface(EditableConfigurationManager.class);
160            infoFactory.setConstructor(new String[]{"kernel", "Stores", "AttributeStore", "PersistentConfigurationList", "ArtifactManager", "ArtifactResolver", "Repositories", "Watchers", "classLoader"});
161            GBEAN_INFO = infoFactory.getBeanInfo();
162        }
163    
164        public static GBeanInfo getGBeanInfo() {
165            return GBEAN_INFO;
166        }
167    }