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.naming.deployment;
019    
020    import java.util.ArrayList;
021    import java.util.Collections;
022    import java.util.HashMap;
023    import java.util.HashSet;
024    import java.util.Iterator;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.Set;
028    
029    import javax.xml.namespace.QName;
030    
031    import org.apache.geronimo.common.DeploymentException;
032    import org.apache.geronimo.deployment.service.EnvironmentBuilder;
033    import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
034    import org.apache.geronimo.gbean.AbstractName;
035    import org.apache.geronimo.gbean.AbstractNameQuery;
036    import org.apache.geronimo.j2ee.annotation.Holder;
037    import org.apache.geronimo.j2ee.annotation.Injection;
038    import org.apache.geronimo.j2ee.deployment.Module;
039    import org.apache.geronimo.j2ee.deployment.NamingBuilder;
040    import org.apache.geronimo.kernel.config.Configuration;
041    import org.apache.geronimo.kernel.repository.Artifact;
042    import org.apache.geronimo.kernel.repository.Dependency;
043    import org.apache.geronimo.kernel.repository.Environment;
044    import org.apache.geronimo.kernel.repository.ImportType;
045    import org.apache.geronimo.schema.NamespaceElementConverter;
046    import org.apache.geronimo.xbeans.geronimo.naming.GerAbstractNamingEntryDocument;
047    import org.apache.geronimo.xbeans.geronimo.naming.GerPatternType;
048    import org.apache.geronimo.xbeans.javaee.InjectionTargetType;
049    import org.apache.geronimo.xbeans.javaee.XsdStringType;
050    import org.apache.xmlbeans.QNameSet;
051    import org.apache.xmlbeans.SchemaType;
052    import org.apache.xmlbeans.XmlCursor;
053    import org.apache.xmlbeans.XmlException;
054    import org.apache.xmlbeans.XmlObject;
055    
056    /**
057     * @version $Rev: 550523 $ $Date: 2007-06-25 11:02:09 -0400 (Mon, 25 Jun 2007) $
058     */
059    public abstract class AbstractNamingBuilder implements NamingBuilder {
060        protected static final String J2EE_NAMESPACE = "http://java.sun.com/xml/ns/j2ee";
061        protected static final String JEE_NAMESPACE = "http://java.sun.com/xml/ns/javaee";
062        protected static final NamespaceElementConverter J2EE_CONVERTER = new NamespaceElementConverter(J2EE_NAMESPACE);
063        protected static final NamespaceElementConverter JEE_CONVERTER = new NamespaceElementConverter(JEE_NAMESPACE);
064        protected static final NamespaceElementConverter NAMING_CONVERTER = new NamespaceElementConverter(GerAbstractNamingEntryDocument.type.getDocumentElementName().getNamespaceURI());
065    
066        private final Environment defaultEnvironment;
067    
068        protected AbstractNamingBuilder() {
069            defaultEnvironment = null;
070        }
071    
072        protected AbstractNamingBuilder(Environment defaultEnvironment) {
073            this.defaultEnvironment = defaultEnvironment;
074        }
075    
076        public Environment getEnvironment() {
077            return this.defaultEnvironment;
078        }
079    
080        public void buildEnvironment(XmlObject specDD, XmlObject plan, Environment environment) throws DeploymentException {
081            // TODO Currently this method is called before the xml is metadata complete, so will not contain all refs
082            // Just always call mergeEnvironment until this is fixed
083            //
084            // if (willMergeEnvironment(specDD, plan)) {
085            EnvironmentBuilder.mergeEnvironments(environment, defaultEnvironment);
086            // }
087        }
088    
089        protected boolean willMergeEnvironment(XmlObject specDD, XmlObject plan) throws DeploymentException {
090            return false;
091        }
092    
093        protected boolean matchesDefaultEnvironment(Environment environment) {
094            for (Iterator iterator = defaultEnvironment.getDependencies().iterator(); iterator.hasNext();) {
095                Dependency defaultDependency = (Dependency) iterator.next();
096                boolean matches = false;
097                for (Iterator iterator1 = environment.getDependencies().iterator(); iterator1.hasNext();) {
098                    Dependency actualDependency = (Dependency) iterator1.next();
099                    if (matches(defaultDependency, actualDependency)) {
100                        matches = true;
101                        break;
102                    }
103                }
104                if (!matches) {
105                    return false;
106                }
107            }
108            return true;
109        }
110    
111        private boolean matches(Dependency defaultDependency, Dependency actualDependency) {
112            if (defaultDependency.getArtifact().matches(actualDependency.getArtifact())
113                    || actualDependency.getArtifact().matches(defaultDependency.getArtifact())) {
114                return defaultDependency.getImportType() == actualDependency.getImportType()
115                        || actualDependency.getImportType() == ImportType.ALL;
116            }
117            return false;
118        }
119    
120        public void initContext(XmlObject specDD, XmlObject plan, Module module) throws DeploymentException {
121        }
122    
123        protected Map<String, Object> getJndiContextMap(Map sharedContext) {
124            return NamingBuilder.JNDI_KEY.get(sharedContext);
125        }
126    
127        protected AbstractName getGBeanName(Map sharedContext) {
128            return GBEAN_NAME_KEY.get(sharedContext);
129        }
130    
131        protected static QNameSet buildQNameSet(String[] eeNamespaces, String localPart) {
132            Set qnames = new HashSet(eeNamespaces.length);
133            for (int i = 0; i < eeNamespaces.length; i++) {
134                String namespace = eeNamespaces[i];
135                qnames.add(new QName(namespace, localPart));
136            }
137            //xmlbeans 2.0 has a bug so forArray doesn't work.  Don't know if it's fixed in later xmlbeans versions
138            //return QNameSet.forArray(qnames);
139            return QNameSet.forSets(null, Collections.EMPTY_SET, Collections.EMPTY_SET, qnames);
140        }
141    
142        /**
143         * @param xmlObjects
144         * @param converter
145         * @param type
146         * @return
147         * @throws DeploymentException
148         * @deprecated
149         */
150        protected static XmlObject[] convert(XmlObject[] xmlObjects, NamespaceElementConverter converter, SchemaType type) throws DeploymentException {
151            //bizarre ArrayStoreException if xmlObjects is loaded by the wrong classloader
152            XmlObject[] converted = new XmlObject[xmlObjects.length];
153            for (int i = 0; i < xmlObjects.length; i++) {
154                XmlObject xmlObject = xmlObjects[i].copy();
155                if (xmlObject.schemaType() != type) {
156                    converter.convertElement(xmlObject);
157                    converted[i] = xmlObject.changeType(type);
158                } else {
159                    converted[i] = xmlObject;
160                }
161                try {
162                    XmlBeansUtil.validateDD(converted[i]);
163                } catch (XmlException e) {
164                    throw new DeploymentException("Could not validate xmlObject of type " + type, e);
165                }
166            }
167            return converted;
168    
169        }
170    
171        protected static <T extends XmlObject> List<T> convert(XmlObject[] xmlObjects, NamespaceElementConverter converter, Class<T> c, SchemaType type) throws DeploymentException {
172            //there's probably a better way to say T extends XmlObject and get the type from that
173            List<T> result = new ArrayList<T>(xmlObjects.length);
174            for (XmlObject xmlObject : xmlObjects) {
175                xmlObject = convert(xmlObject, converter, type);
176                result.add((T) xmlObject);
177            }
178            return result;
179        }
180    
181        protected static XmlObject convert(XmlObject xmlObject, NamespaceElementConverter converter, SchemaType type) throws DeploymentException {
182            Map ns = new HashMap();
183            XmlCursor cursor = xmlObject.newCursor();
184            try {
185                cursor.getAllNamespaces(ns);
186            } finally {
187                cursor.dispose();
188            }
189            xmlObject = xmlObject.copy();
190            cursor = xmlObject.newCursor();
191            cursor.toNextToken();
192            try {
193                for (Object o : ns.entrySet()) {
194                    Map.Entry entry = (Map.Entry) o;
195                    cursor.insertNamespace((String) entry.getKey(), (String) entry.getValue());
196                }
197            } finally {
198                cursor.dispose();
199            }
200    
201            if (xmlObject.schemaType() != type) {
202                converter.convertElement(xmlObject);
203                xmlObject = xmlObject.changeType(type);
204            }
205            try {
206                XmlBeansUtil.validateDD(xmlObject);
207            } catch (XmlException e) {
208                throw new DeploymentException("Could not validate xmlObject of type " + type, e);
209            }
210            return xmlObject;
211        }
212    
213        protected static String getStringValue(org.apache.geronimo.xbeans.javaee.String string) {
214            if (string == null) {
215                return null;
216            }
217            String s = string.getStringValue();
218            return s == null ? null : s.trim();
219        }
220    
221        protected static String getStringValue(XsdStringType string) {
222            if (string == null) {
223                return null;
224            }
225            String s = string.getStringValue();
226            return s == null ? null : s.trim();
227        }
228    
229        public static AbstractNameQuery buildAbstractNameQuery(GerPatternType pattern, String type, String moduleType, Set interfaceTypes) {
230            String groupId = pattern.isSetGroupId() ? pattern.getGroupId().trim() : null;
231            String artifactid = pattern.isSetArtifactId() ? pattern.getArtifactId().trim() : null;
232            String version = pattern.isSetVersion() ? pattern.getVersion().trim() : null;
233            String module = pattern.isSetModule() ? pattern.getModule().trim() : null;
234            String name = pattern.getName().trim();
235    
236            Artifact artifact = artifactid != null ? new Artifact(groupId, artifactid, version, null) : null;
237            Map nameMap = new HashMap();
238            nameMap.put("name", name);
239            if (type != null) {
240                nameMap.put("j2eeType", type);
241            }
242            if (module != null && moduleType != null) {
243                nameMap.put(moduleType, module);
244            }
245            if (interfaceTypes != null) {
246                Set trimmed = new HashSet();
247                for (Iterator it = interfaceTypes.iterator(); it.hasNext();) {
248                    String intf = (String) it.next();
249                    trimmed.add(intf == null ? null : intf.trim());
250                }
251                interfaceTypes = trimmed;
252            }
253            return new AbstractNameQuery(artifact, nameMap, interfaceTypes);
254        }
255    
256        public static AbstractNameQuery buildAbstractNameQuery(Artifact configId, String module, String name, String type, String moduleType) {
257            Map nameMap = new HashMap();
258            nameMap.put("name", name);
259            if (type != null) {
260                nameMap.put("j2eeType", type);
261            }
262            if (module != null) {
263                nameMap.put(moduleType, module);
264            }
265            return new AbstractNameQuery(configId, nameMap);
266        }
267    
268        public static Class assureInterface(String interfaceName, String superInterfaceName, String interfaceType, ClassLoader cl) throws DeploymentException {
269            if (interfaceName == null || interfaceName.equals("")) {
270                throw new DeploymentException("interface name cannot be blank");
271            }
272            Class clazz;
273            try {
274                clazz = cl.loadClass(interfaceName);
275            } catch (ClassNotFoundException e) {
276                throw new DeploymentException(interfaceType + " interface class not found: " + interfaceName, e);
277            }
278            if (!clazz.isInterface()) {
279                throw new DeploymentException(interfaceType + " interface is not an interface: " + interfaceName);
280            }
281            Class superInterface;
282            try {
283                superInterface = cl.loadClass(superInterfaceName);
284            } catch (ClassNotFoundException e) {
285                throw new DeploymentException("Class " + superInterfaceName + " could not be loaded", e);
286            }
287            if (!superInterface.isAssignableFrom(clazz)) {
288                throw new DeploymentException(interfaceType + " interface does not extend " + superInterfaceName + ": " + interfaceName);
289            }
290            return clazz;
291        }
292    
293    
294        protected void addInjections(String jndiName, InjectionTargetType[] injectionTargetArray, Map sharedContext) {
295            Holder holder = NamingBuilder.INJECTION_KEY.get(sharedContext);
296            for (InjectionTargetType injectionTarget : injectionTargetArray) {
297                String targetName = injectionTarget.getInjectionTargetName().getStringValue().trim();
298                String targetClassName = injectionTarget.getInjectionTargetClass().getStringValue().trim();
299                holder.addInjection(targetClassName, new Injection(targetClassName, targetName, jndiName));
300            }
301        }
302    
303        protected static Artifact[] getConfigId(Configuration localConfiguration, Configuration earConfiguration) {
304            if (localConfiguration == earConfiguration) {
305                return new Artifact[] {earConfiguration.getId()};
306            }
307            return new Artifact[] {earConfiguration.getId(),localConfiguration.getId()};
308        }
309    
310    }
311    
312