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 }