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    
019    package org.apache.geronimo.j2ee.deployment;
020    
021    import java.util.Collection;
022    import java.util.Iterator;
023    import java.util.Collections;
024    import java.util.Map;
025    
026    import javax.xml.namespace.QName;
027    
028    import org.apache.geronimo.common.DeploymentException;
029    import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
030    import org.apache.geronimo.gbean.ReferenceCollection;
031    import org.apache.geronimo.gbean.ReferenceCollectionEvent;
032    import org.apache.geronimo.gbean.ReferenceCollectionListener;
033    import org.apache.geronimo.kernel.config.Configuration;
034    import org.apache.geronimo.kernel.repository.Environment;
035    import org.apache.xmlbeans.QNameSet;
036    import org.apache.xmlbeans.XmlObject;
037    
038    /**
039     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
040     */
041    public class NamingBuilderCollection implements NamingBuilder {
042    
043        private final Collection builders;
044        private final QName basePlanElementName;
045        private QNameSet specQNames = QNameSet.EMPTY;
046        private QNameSet planQNames = QNameSet.EMPTY;
047    
048        public NamingBuilderCollection(Collection builders, final QName basePlanElementName) {
049            this.builders = builders == null ? Collections.EMPTY_SET : builders;
050            this.basePlanElementName = basePlanElementName;
051            if (builders instanceof ReferenceCollection) {
052                ((ReferenceCollection) builders).addReferenceCollectionListener(new ReferenceCollectionListener() {
053    
054                    public void memberAdded(ReferenceCollectionEvent event) {
055                        addBuilder(event.getMember());
056                    }
057    
058                    public void memberRemoved(ReferenceCollectionEvent event) {
059                        Object builder = event.getMember();
060                        QNameSet builderSpecQNames = ((NamingBuilder) builder).getSpecQNameSet();
061                        specQNames = specQNames.intersect(builderSpecQNames.inverse());
062                        QNameSet builderPlanQNames = ((NamingBuilder) builder).getPlanQNameSet();
063                        planQNames = planQNames.intersect(builderPlanQNames.inverse());
064                        XmlBeansUtil.unregisterSubstitutionGroupElements(basePlanElementName, builderPlanQNames);
065                    }
066                });
067            }
068            for (Iterator iterator = this.builders.iterator(); iterator.hasNext();) {
069                Object builder = iterator.next();
070                addBuilder(builder);
071            }
072        }
073    
074        private void addBuilder(Object builder) {
075            QNameSet builderSpecQNames = ((NamingBuilder) builder).getSpecQNameSet();
076            QNameSet builderPlanQNames = ((NamingBuilder) builder).getPlanQNameSet();
077            if (builderSpecQNames == null) {
078                throw new IllegalStateException("Builder " + builder + " is missing spec qnames");
079            }
080            if (builderPlanQNames == null) {
081                throw new IllegalStateException("Builder " + builder + " is missing plan qnames");
082            }
083            if (!specQNames.isDisjoint(builderSpecQNames) && !planQNames.isDisjoint(builderPlanQNames)) {
084                throw new IllegalArgumentException("Duplicate builderSpecQNames in builder set: " + builderSpecQNames + " and duplicate builderPlanQNames in builder set: " + builderPlanQNames);
085            }
086            try {
087                specQNames = specQNames.union(builderSpecQNames);
088                planQNames = planQNames.union(builderPlanQNames);
089            } catch (NullPointerException e) {
090                throw (IllegalArgumentException) new IllegalArgumentException("could not merge qnamesets for builder " + builder).initCause(e);
091    
092            }
093            //really?
094            XmlBeansUtil.registerSubstitutionGroupElements(basePlanElementName, builderPlanQNames);
095        }
096    
097        public void buildEnvironment(XmlObject specDD, XmlObject plan, Environment environment) throws DeploymentException {
098            for (Iterator iterator = builders.iterator(); iterator.hasNext();) {
099                NamingBuilder namingBuilder = (NamingBuilder) iterator.next();
100                namingBuilder.buildEnvironment(specDD, plan, environment);
101            }
102        }
103    
104        public void initContext(XmlObject specDD, XmlObject plan, Configuration localConfiguration, Configuration remoteConfiguration, Module module) throws DeploymentException {
105            for (Iterator iterator = builders.iterator(); iterator.hasNext();) {
106                NamingBuilder namingBuilder = (NamingBuilder) iterator.next();
107                namingBuilder.initContext(specDD, plan, localConfiguration, remoteConfiguration, module);
108            }
109        }
110    
111        public void buildNaming(XmlObject specDD, XmlObject plan, Configuration localContext, Configuration remoteContext, Module module, Map componentContext) throws DeploymentException {
112            for (Iterator iterator = builders.iterator(); iterator.hasNext();) {
113                NamingBuilder namingBuilder = (NamingBuilder) iterator.next();
114                namingBuilder.buildNaming(specDD, plan, localContext, remoteContext, module, componentContext);
115            }
116        }
117    
118        public QNameSet getSpecQNameSet() {
119            return specQNames;
120        }
121    
122        public QNameSet getPlanQNameSet() {
123            return null;
124        }
125    }