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.beans.PropertyEditor;
022    import java.util.Collections;
023    import java.util.HashMap;
024    import java.util.HashSet;
025    import java.util.Iterator;
026    import java.util.Map;
027    import java.util.Set;
028    
029    import org.apache.geronimo.common.DeploymentException;
030    import org.apache.geronimo.common.propertyeditor.PropertyEditors;
031    import org.apache.geronimo.deployment.DeploymentContext;
032    import org.apache.geronimo.deployment.xbeans.PatternType;
033    import org.apache.geronimo.deployment.xbeans.ReferenceType;
034    import org.apache.geronimo.gbean.AbstractName;
035    import org.apache.geronimo.gbean.AbstractNameQuery;
036    import org.apache.geronimo.gbean.GAttributeInfo;
037    import org.apache.geronimo.gbean.GBeanData;
038    import org.apache.geronimo.gbean.GBeanInfo;
039    import org.apache.geronimo.gbean.GReferenceInfo;
040    import org.apache.geronimo.gbean.ReferencePatterns;
041    import org.apache.geronimo.kernel.repository.Artifact;
042    import org.apache.xmlbeans.XmlObject;
043    
044    /**
045     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
046     */
047    public class SingleGBeanBuilder {
048        private final GBeanData gbean;
049        private final ClassLoader classLoader;
050        private final DeploymentContext context;
051        private final AbstractName moduleName;
052        private final Map xmlAttributeBuilderMap;
053        private final Map xmlReferenceBuilderMap;
054    
055        SingleGBeanBuilder(AbstractName abstractName, GBeanInfo gBeanInfo, ClassLoader classLoader, DeploymentContext context, AbstractName moduleName, Map xmlAttributeBuilderMap, Map xmlReferenceBuilderMap) {
056    
057            this.classLoader = classLoader;
058            this.context = context;
059            this.moduleName = moduleName;
060            this.gbean = new GBeanData(abstractName, gBeanInfo);
061            this.xmlAttributeBuilderMap = xmlAttributeBuilderMap;
062            this.xmlReferenceBuilderMap = xmlReferenceBuilderMap;
063        }
064    
065        public void setAttribute(String name, String type, String text) throws DeploymentException {
066            if (text != null) {
067                text = text.trim(); // avoid formatting errors due to extra whitespace in XML configuration file
068            }
069            try {
070                // @todo we should not need all of common just for this
071                if (type == null) {
072                    GAttributeInfo attribute = gbean.getGBeanInfo().getAttribute(name);
073                    if (attribute == null) {
074                        throw new DeploymentException("Unknown attribute " + name + " on " + gbean.getAbstractName());
075                    }
076                    type = attribute.getType();
077                }
078    
079                PropertyEditor editor = PropertyEditors.findEditor(type, classLoader);
080                if (editor == null) {
081                    throw new DeploymentException("Unable to find PropertyEditor for " + type);
082                }
083                editor.setAsText(text);
084                Object value = editor.getValue();
085                gbean.setAttribute(name, value);
086            } catch (DeploymentException e) {
087                throw e;
088            } catch (ClassNotFoundException e) {
089                throw new DeploymentException("Unable to find PropertyEditor for " + type, e);
090            } catch (Exception e) {
091                throw new DeploymentException("Unable to set attribute " + name + " to " + text, e);
092            }
093        }
094    
095        public void setXmlAttribute(String name, XmlObject xmlObject) throws DeploymentException {
096            String namespace = xmlObject.getDomNode().getNamespaceURI();
097            XmlAttributeBuilder builder = (XmlAttributeBuilder) xmlAttributeBuilderMap.get(namespace);
098            if (builder == null) {
099                throw new DeploymentException("No attribute builder deployed for namespace: " + namespace);
100            }
101            GAttributeInfo attribute = gbean.getGBeanInfo().getAttribute(name);
102            if (attribute == null) {
103                throw new DeploymentException("Unknown attribute " + name + " on " + gbean.getAbstractName());
104            }
105            String type = attribute.getType();
106            Object value = builder.getValue(xmlObject, type, classLoader);
107            gbean.setAttribute(name, value);
108        }
109    
110        public void setXmlReference(String name, XmlObject xmlObject) throws DeploymentException {
111            String namespace = xmlObject.getDomNode().getNamespaceURI();
112            XmlReferenceBuilder builder = (XmlReferenceBuilder) xmlReferenceBuilderMap.get(namespace);
113            if (builder == null) {
114                throw new DeploymentException("No reference builder deployed for namespace: " + namespace);
115            }
116            ReferencePatterns references = builder.getReferences(xmlObject, context, moduleName, classLoader);
117            if (references != null) {
118                gbean.setReferencePatterns(name, references);
119            }
120        }
121    
122        public void setReference(String name, ReferenceType pattern, AbstractName parentName) throws DeploymentException {
123            setReference(name, new PatternType[]{pattern}, parentName);
124        }
125    
126        public void setReference(String name, PatternType[] patterns, AbstractName parentName) throws DeploymentException {
127            Set patternNames = new HashSet(patterns.length);
128            for (int i = 0; i < patterns.length; i++) {
129                patternNames.add(buildAbstractNameQuery(name, patterns[i]));
130            }
131            gbean.setReferencePatterns(name, patternNames);
132        }
133    
134        public void addDependency(PatternType patternType) throws DeploymentException {
135            AbstractNameQuery refInfo = buildAbstractNameQuery(patternType, null);
136            gbean.addDependency(refInfo);
137        }
138    
139        private AbstractNameQuery buildAbstractNameQuery(String refName, PatternType pattern) throws DeploymentException {
140    //        if (refName == null) {
141    //            throw new DeploymentException("No type specified in dependency pattern " + pattern + " for gbean " + gbean.getName());
142    //        }
143            assert refName != null;
144            GReferenceInfo referenceInfo = null;
145            Set referenceInfos = gbean.getGBeanInfo().getReferences();
146            for (Iterator iterator = referenceInfos.iterator(); iterator.hasNext();) {
147                GReferenceInfo testReferenceInfo = (GReferenceInfo) iterator.next();
148                String testRefName = testReferenceInfo.getName();
149                if (testRefName.equals(refName)) {
150                    referenceInfo = testReferenceInfo;
151                }
152            }
153            if (referenceInfo == null) {
154                throw new DeploymentException("No reference named " + refName + " in gbean " + gbean.getAbstractName());
155            }
156    
157            return buildAbstractNameQuery(pattern, referenceInfo);
158        }
159    
160        public static AbstractNameQuery buildAbstractNameQuery(PatternType pattern, GReferenceInfo referenceInfo) {
161            String groupId = pattern.isSetGroupId() ? pattern.getGroupId().trim() : null;
162            String artifactid = pattern.isSetArtifactId() ? pattern.getArtifactId().trim() : null;
163            String version = pattern.isSetVersion() ? pattern.getVersion().trim() : null;
164            String module = pattern.isSetModule() ? pattern.getModule().trim() : null;
165            String type = pattern.isSetType() ? pattern.getType().trim() : null;
166            String name = pattern.isSetName() ? pattern.getName().trim() : null;
167    
168            Artifact artifact = artifactid != null? new Artifact(groupId, artifactid, version, "car"): null;
169            //get the type from the gbean info if not supplied explicitly
170            if (type == null && referenceInfo != null) {
171                type = referenceInfo.getNameTypeName();
172            }
173            Map nameMap = new HashMap();
174            if (name != null) {
175                nameMap.put("name", name);
176            }
177            if (type != null) {
178                nameMap.put("j2eeType", type);
179            }
180            if (module != null) {
181                nameMap.put("J2EEModule", module);
182            }
183            Set interfaceTypes = referenceInfo == null? null: Collections.singleton(referenceInfo.getReferenceType());
184            return new AbstractNameQuery(artifact, nameMap, interfaceTypes);
185        }
186    
187        public GBeanData getGBeanData() {
188            return gbean;
189        }
190    
191    }