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 package org.apache.geronimo.j2ee.deployment; 018 019 import org.apache.geronimo.common.DeploymentException; 020 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; 021 import org.apache.geronimo.deployment.ModuleIDBuilder; 022 import org.apache.geronimo.gbean.GBeanInfo; 023 import org.apache.geronimo.gbean.GBeanInfoBuilder; 024 import org.apache.geronimo.gbean.ReferenceCollection; 025 import org.apache.geronimo.gbean.ReferenceCollectionEvent; 026 import org.apache.geronimo.gbean.ReferenceCollectionListener; 027 import org.apache.geronimo.gbean.AbstractName; 028 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 029 import org.apache.geronimo.kernel.repository.Environment; 030 import org.apache.geronimo.kernel.Naming; 031 import org.apache.geronimo.kernel.config.ConfigurationStore; 032 import org.apache.xmlbeans.XmlCursor; 033 import org.apache.xmlbeans.XmlException; 034 import org.apache.xmlbeans.XmlObject; 035 036 import java.io.File; 037 import java.io.IOException; 038 import java.net.URL; 039 import java.util.Collection; 040 import java.util.HashMap; 041 import java.util.Iterator; 042 import java.util.Map; 043 import java.util.jar.JarFile; 044 045 /** 046 * @version $Rev:386276 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ 047 */ 048 public class SwitchingModuleBuilder implements ModuleBuilder { 049 050 private final Map namespaceToBuilderMap = new HashMap(); 051 052 private String defaultNamespace; 053 054 public SwitchingModuleBuilder(Collection builders) { 055 ReferenceCollection buildersCollection = (ReferenceCollection) builders; 056 buildersCollection.addReferenceCollectionListener(new ReferenceCollectionListener() { 057 public void memberAdded(ReferenceCollectionEvent event) { 058 ModuleBuilder builder = (ModuleBuilder) event.getMember(); 059 String namespace = builder.getSchemaNamespace(); 060 namespaceToBuilderMap.put(namespace, builder); 061 } 062 063 public void memberRemoved(ReferenceCollectionEvent event) { 064 ModuleBuilder builder = (ModuleBuilder) event.getMember(); 065 String namespace = builder.getSchemaNamespace(); 066 namespaceToBuilderMap.remove(namespace); 067 } 068 }); 069 for (Iterator iterator = builders.iterator(); iterator.hasNext();) { 070 ModuleBuilder builder = (ModuleBuilder) iterator.next(); 071 String namespace = builder.getSchemaNamespace(); 072 namespaceToBuilderMap.put(namespace, builder); 073 } 074 075 } 076 077 public String getDefaultNamespace() { 078 return defaultNamespace; 079 } 080 081 public void setDefaultNamespace(String defaultNamespace) { 082 this.defaultNamespace = defaultNamespace; 083 } 084 085 public Module createModule(File plan, JarFile moduleFile, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException { 086 String namespace; 087 if (plan == null) { 088 namespace = defaultNamespace; 089 } else { 090 namespace = getNamespaceFromPlan(plan); 091 } 092 ModuleBuilder builder = getBuilderFromNamespace(namespace); 093 if (builder != null) { 094 return builder.createModule(plan, moduleFile, naming, idBuilder); 095 } else { 096 return null; 097 } 098 } 099 100 private String getNamespaceFromPlan(Object plan) throws DeploymentException { 101 XmlObject xmlObject; 102 if (plan instanceof File) { 103 try { 104 xmlObject = XmlBeansUtil.parse(((File) plan).toURL(), getClass().getClassLoader()); 105 } catch (IOException e) { 106 throw new DeploymentException("Could not read plan file", e); 107 } catch (XmlException e) { 108 throw new DeploymentException("Plan file does not contain well formed xml", e); 109 } 110 } else if (plan instanceof XmlObject) { 111 xmlObject = (XmlObject) plan; 112 } else { 113 return defaultNamespace; 114 } 115 XmlCursor cursor = xmlObject.newCursor(); 116 try { 117 while (cursor.hasNextToken()){ 118 if (cursor.isStart()) { 119 return cursor.getName().getNamespaceURI(); 120 } 121 cursor.toNextToken(); 122 } 123 } finally { 124 cursor.dispose(); 125 } 126 throw new DeploymentException("Cannot find namespace in xmlObject: " + xmlObject.xmlText()); 127 } 128 129 private ModuleBuilder getBuilderFromNamespace(String namespace) { 130 ModuleBuilder builder = (ModuleBuilder) namespaceToBuilderMap.get(namespace); 131 if (builder == null) { 132 builder = (ModuleBuilder) namespaceToBuilderMap.get(defaultNamespace); 133 } 134 if (builder == null && namespaceToBuilderMap.size() == 1) { 135 builder = (ModuleBuilder) namespaceToBuilderMap.values().iterator().next(); 136 } 137 return builder; 138 } 139 140 public Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException { 141 String namespace = getNamespaceFromPlan(plan); 142 ModuleBuilder builder = getBuilderFromNamespace(namespace); 143 if (builder != null) { 144 return builder.createModule(plan, moduleFile, targetPath, specDDUrl, environment, moduleContextInfo, earName, naming, idBuilder); 145 } else { 146 return null; 147 } 148 } 149 150 public void installModule(JarFile earFile, EARContext earContext, Module module, Collection configurationStores, ConfigurationStore targetConfigurationStore, Collection repositories) throws DeploymentException { 151 String namespace = module.getNamespace(); 152 ModuleBuilder builder = getBuilderFromNamespace(namespace); 153 builder.installModule(earFile, earContext, module, configurationStores, targetConfigurationStore, repositories); 154 } 155 156 public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException { 157 String namespace = module.getNamespace(); 158 ModuleBuilder builder = getBuilderFromNamespace(namespace); 159 builder.initContext(earContext, module, cl); 160 } 161 162 public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repositories) throws DeploymentException { 163 String namespace = module.getNamespace(); 164 ModuleBuilder builder = getBuilderFromNamespace(namespace); 165 builder.addGBeans(earContext, module, cl, repositories); 166 } 167 168 public String getSchemaNamespace() { 169 return null; 170 } 171 172 public static final GBeanInfo GBEAN_INFO; 173 174 static { 175 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(SwitchingModuleBuilder.class, NameFactory.MODULE_BUILDER); 176 infoBuilder.addAttribute("defaultNamespace", String.class, true, true); 177 infoBuilder.addReference("ModuleBuilders", ModuleBuilder.class, NameFactory.MODULE_BUILDER); 178 infoBuilder.addInterface(ModuleBuilder.class); 179 180 infoBuilder.setConstructor(new String[] {"ModuleBuilders"}); 181 GBEAN_INFO = infoBuilder.getBeanInfo(); 182 } 183 184 public static GBeanInfo getGBeanInfo() { 185 return GBEAN_INFO; 186 } 187 }