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.deployment.service;
020    
021    import java.util.Map;
022    import java.util.HashMap;
023    import java.util.Collection;
024    import java.beans.PropertyEditorManager;
025    
026    import javax.xml.namespace.QName;
027    
028    import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
029    import org.apache.geronimo.deployment.DeploymentContext;
030    import org.apache.geronimo.deployment.ConfigurationBuilder;
031    import org.apache.geronimo.deployment.xbeans.GbeanType;
032    import org.apache.geronimo.deployment.xbeans.AttributeType;
033    import org.apache.geronimo.deployment.xbeans.XmlAttributeType;
034    import org.apache.geronimo.deployment.xbeans.ReferenceType;
035    import org.apache.geronimo.deployment.xbeans.ReferencesType;
036    import org.apache.geronimo.deployment.xbeans.PatternType;
037    import org.apache.geronimo.deployment.xbeans.ServiceDocument;
038    import org.apache.geronimo.deployment.xbeans.GbeanDocument;
039    import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
040    import org.apache.geronimo.common.DeploymentException;
041    import org.apache.geronimo.gbean.AbstractName;
042    import org.apache.geronimo.gbean.GBeanInfo;
043    import org.apache.geronimo.gbean.GBeanData;
044    import org.apache.geronimo.gbean.ReferenceMap;
045    import org.apache.geronimo.gbean.GBeanInfoBuilder;
046    import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
047    import org.apache.geronimo.kernel.Kernel;
048    import org.apache.geronimo.kernel.repository.Environment;
049    import org.apache.geronimo.kernel.repository.Repository;
050    import org.apache.xmlbeans.XmlObject;
051    import org.apache.xmlbeans.QNameSet;
052    
053    /**
054     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
055     */
056    public class GBeanBuilder implements NamespaceDrivenBuilder {
057        protected Map attrRefMap;
058        protected Map refRefMap;
059        private static final QName SERVICE_QNAME = ServiceDocument.type.getDocumentElementName();
060        private static final QName GBEAN_QNAME = GbeanDocument.type.getDocumentElementName();
061        private static final QNameSet GBEAN_QNAME_SET = QNameSet.singleton(GBEAN_QNAME);
062    
063        public GBeanBuilder(Collection xmlAttributeBuilders, Collection xmlReferenceBuilders) {
064            if (xmlAttributeBuilders != null) {
065                ReferenceMap.Key key = new ReferenceMap.Key() {
066    
067                    public Object getKey(Object object) {
068                        return ((XmlAttributeBuilder) object).getNamespace();
069                    }
070                };
071                attrRefMap = new ReferenceMap(xmlAttributeBuilders, new HashMap(), key);
072            } else {
073                attrRefMap = new HashMap();
074            }
075    
076            if (xmlReferenceBuilders != null) {
077                ReferenceMap.Key key = new ReferenceMap.Key() {
078    
079                    public Object getKey(Object object) {
080                        return ((XmlReferenceBuilder) object).getNamespace();
081                    }
082                };
083                refRefMap = new ReferenceMap(xmlReferenceBuilders, new HashMap(), key);
084            }
085            EnvironmentBuilder environmentBuilder = new EnvironmentBuilder();
086            attrRefMap.put(environmentBuilder.getNamespace(), environmentBuilder);
087        }
088    
089        public void buildEnvironment(XmlObject container, Environment environment) throws DeploymentException {
090        }
091    
092        public void build(XmlObject container, DeploymentContext applicationContext, DeploymentContext moduleContext) throws DeploymentException {
093            XmlObject[] items = container.selectChildren(GBEAN_QNAME_SET);
094            GbeanType[] gbeans = new GbeanType[items.length];
095            for (int i = 0; i < items.length; i++) {
096                XmlObject any = items[i];
097                gbeans[i] = (GbeanType) any.copy().changeType(GbeanType.type);
098            }
099            for (int i1 = 0; i1 < gbeans.length; i1++) {
100                addGBeanData(gbeans[i1], moduleContext.getModuleName(), moduleContext.getClassLoader(), moduleContext);
101            }
102        }
103    
104        public String getNamespace() {
105            XmlBeansUtil.registerSubstitutionGroupElements(SERVICE_QNAME, QNameSet.singleton(GBEAN_QNAME));
106            return GBEAN_QNAME.getLocalPart();
107        }
108    
109        private AbstractName addGBeanData(GbeanType gbean, AbstractName moduleName, ClassLoader cl, DeploymentContext context) throws DeploymentException {
110            GBeanInfo gBeanInfo = GBeanInfo.getGBeanInfo(gbean.getClass1(), cl);
111            String namePart = gbean.getName();
112            String j2eeType = gBeanInfo.getJ2eeType();
113            AbstractName abstractName = context.getNaming().createChildName(moduleName, namePart, j2eeType);
114            SingleGBeanBuilder builder = new SingleGBeanBuilder(abstractName, gBeanInfo, cl, context, moduleName, attrRefMap , refRefMap);
115    
116            // set up attributes
117            AttributeType[] attributeArray = gbean.getAttributeArray();
118            if (attributeArray != null) {
119                for (int j = 0; j < attributeArray.length; j++) {
120                    builder.setAttribute(attributeArray[j].getName().trim(), attributeArray[j].getType(), attributeArray[j].getStringValue());
121                }
122            }
123    
124            XmlAttributeType[] xmlAttributeArray = gbean.getXmlAttributeArray();
125            if (xmlAttributeArray != null) {
126                for (int i = 0; i < xmlAttributeArray.length; i++) {
127                    XmlAttributeType xmlAttributeType = xmlAttributeArray[i];
128                    String name = xmlAttributeType.getName().trim();
129                    XmlObject[] anys = xmlAttributeType.selectChildren(XmlAttributeType.type.qnameSetForWildcardElements());
130                    if (anys.length != 1) {
131                        throw new DeploymentException("Unexpected count of xs:any elements in xml-attribute " + anys.length + " qnameset: " + XmlAttributeType.type.qnameSetForWildcardElements());
132                    }
133                    builder.setXmlAttribute(name, anys[0]);
134                }
135            }
136    
137            // set up all single pattern references
138            ReferenceType[] referenceArray = gbean.getReferenceArray();
139            if (referenceArray != null) {
140                for (int j = 0; j < referenceArray.length; j++) {
141                    builder.setReference(referenceArray[j].getName2(), referenceArray[j], moduleName);
142                }
143            }
144    
145            // set up app multi-patterned references
146            ReferencesType[] referencesArray = gbean.getReferencesArray();
147            if (referencesArray != null) {
148                for (int j = 0; j < referencesArray.length; j++) {
149                    builder.setReference(referencesArray[j].getName(), referencesArray[j].getPatternArray(), moduleName);
150                }
151            }
152    
153            XmlAttributeType[] xmlReferenceArray = gbean.getXmlReferenceArray();
154            if (xmlReferenceArray != null) {
155                for (int i = 0; i < xmlReferenceArray.length; i++) {
156                    XmlAttributeType xmlAttributeType = xmlReferenceArray[i];
157                    String name = xmlAttributeType.getName().trim();
158                    XmlObject[] anys = xmlAttributeType.selectChildren(XmlAttributeType.type.qnameSetForWildcardElements());
159                    if (anys.length != 1) {
160                        throw new DeploymentException("Unexpected count of xs:any elements in xml-attribute " + anys.length + " qnameset: " + XmlAttributeType.type.qnameSetForWildcardElements());
161                    }
162                    builder.setXmlReference(name, anys[0]);
163                }
164            }
165    
166            PatternType[] dependencyArray = gbean.getDependencyArray();
167            if (dependencyArray != null) {
168                for (int i = 0; i < dependencyArray.length; i++) {
169                    PatternType patternType = dependencyArray[i];
170                    builder.addDependency(patternType);
171                }
172            }
173    
174            GBeanData gbeanData = builder.getGBeanData();
175            try {
176                context.addGBean(gbeanData);
177            } catch (GBeanAlreadyExistsException e) {
178                throw new DeploymentException(e);
179            }
180            return abstractName;
181        }
182    
183        public static final GBeanInfo GBEAN_INFO;
184    
185        static {
186            PropertyEditorManager.registerEditor(Environment.class, EnvironmentBuilder.class);
187    
188            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(GBeanBuilder.class, "ModuleBuilder");
189    
190            infoBuilder.addInterface(NamespaceDrivenBuilder.class);
191    
192            infoBuilder.addReference("XmlAttributeBuilders", XmlAttributeBuilder.class, "XmlAttributeBuilder");
193            infoBuilder.addReference("XmlReferenceBuilders", XmlReferenceBuilder.class, "XmlReferenceBuilder");
194    
195            infoBuilder.setConstructor(new String[]{"XmlAttributeBuilders", "XmlReferenceBuilders"});
196    
197            GBEAN_INFO = infoBuilder.getBeanInfo();
198        }
199    
200        public static GBeanInfo getGBeanInfo() {
201            return GBEAN_INFO;
202        }
203    
204    }