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 }