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