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.deployment;
018    
019    import java.util.Collection;
020    import java.util.Collections;
021    
022    import javax.xml.namespace.QName;
023    
024    import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
025    import org.apache.geronimo.gbean.ReferenceCollection;
026    import org.apache.geronimo.gbean.ReferenceCollectionEvent;
027    import org.apache.geronimo.gbean.ReferenceCollectionListener;
028    import org.apache.xmlbeans.QNameSet;
029    
030    /**
031     * @version $Rev: 535381 $ $Date: 2007-05-04 17:04:18 -0400 (Fri, 04 May 2007) $
032     */
033    public abstract class AbstractBuilderCollection<T> {
034        protected final Collection<T> builders;
035        protected final QName basePlanElementName;
036        protected QNameSet specQNames = QNameSet.EMPTY;
037        protected QNameSet planQNames = QNameSet.EMPTY;
038    
039        protected AbstractBuilderCollection(Collection<T> builders, final QName basePlanElementName) {
040            this.builders = builders == null ? Collections.EMPTY_SET : builders;
041            this.basePlanElementName = basePlanElementName;
042            if (builders instanceof ReferenceCollection) {
043                ((ReferenceCollection) builders).addReferenceCollectionListener(new ReferenceCollectionListener() {
044    
045                    public void memberAdded(ReferenceCollectionEvent event) {
046                        addBuilder((T) event.getMember());
047                    }
048    
049                    public void memberRemoved(ReferenceCollectionEvent event) {
050                        T builder = (T) event.getMember();
051                        QNameSet builderSpecQNames = ((AbstractNamespaceBuilder) builder).getSpecQNameSet();
052                        specQNames = specQNames.intersect(builderSpecQNames.inverse());
053                        QNameSet builderPlanQNames = ((AbstractNamespaceBuilder) builder).getPlanQNameSet();
054                        planQNames = planQNames.intersect(builderPlanQNames.inverse());
055                        XmlBeansUtil.unregisterSubstitutionGroupElements(basePlanElementName, builderPlanQNames);
056                    }
057                });
058            }
059            for (T builder : this.builders) {
060                addBuilder(builder);
061            }
062        }
063    
064    
065        protected void addBuilder(T builder) {
066            QNameSet builderSpecQNames = ((AbstractNamespaceBuilder) builder).getSpecQNameSet();
067            QNameSet builderPlanQNames = ((AbstractNamespaceBuilder) builder).getPlanQNameSet();
068            if (builderSpecQNames == null) {
069                throw new IllegalStateException("Builder " + builder + " is missing spec qnames");
070            }
071            if (builderPlanQNames == null) {
072                throw new IllegalStateException("Builder " + builder + " is missing plan qnames");
073            }
074            if (!specQNames.isDisjoint(builderSpecQNames) && !planQNames.isDisjoint(builderPlanQNames)) {
075                throw new IllegalArgumentException("Duplicate builderSpecQNames in builder set: " + builderSpecQNames + " and duplicate builderPlanQNames in builder set: " + builderPlanQNames);
076            }
077            try {
078                specQNames = specQNames.union(builderSpecQNames);
079                planQNames = planQNames.union(builderPlanQNames);
080            } catch (NullPointerException e) {
081                throw (IllegalArgumentException) new IllegalArgumentException("could not merge qnamesets for builder " + builder).initCause(e);
082    
083            }
084            //really?
085            XmlBeansUtil.registerSubstitutionGroupElements(basePlanElementName, builderPlanQNames);
086        }
087    
088        public QNameSet getSpecQNameSet() {
089            return specQNames;
090        }
091    
092        public QNameSet getPlanQNameSet() {
093            return null;
094        }
095    }