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