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