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 }