1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.geronimo.j2ee.deployment;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URI;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Iterator;
32 import java.util.LinkedHashMap;
33 import java.util.LinkedHashSet;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.jar.JarFile;
39 import java.util.zip.ZipEntry;
40
41 import javax.xml.namespace.QName;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45 import org.apache.geronimo.common.DeploymentException;
46 import org.apache.geronimo.deployment.ConfigurationBuilder;
47 import org.apache.geronimo.deployment.DeploymentContext;
48 import org.apache.geronimo.deployment.ModuleIDBuilder;
49 import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
50 import org.apache.geronimo.deployment.NamespaceDrivenBuilderCollection;
51 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
52 import org.apache.geronimo.deployment.util.DeploymentUtil;
53 import org.apache.geronimo.deployment.util.NestedJarFile;
54 import org.apache.geronimo.deployment.xbeans.ArtifactType;
55 import org.apache.geronimo.deployment.xbeans.EnvironmentType;
56 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
57 import org.apache.geronimo.gbean.AbstractName;
58 import org.apache.geronimo.gbean.AbstractNameQuery;
59 import org.apache.geronimo.gbean.GBeanData;
60 import org.apache.geronimo.gbean.GBeanInfo;
61 import org.apache.geronimo.gbean.GBeanInfoBuilder;
62 import org.apache.geronimo.gbean.ReferencePatterns;
63 import org.apache.geronimo.gbean.SingleElementCollection;
64 import org.apache.geronimo.j2ee.ApplicationInfo;
65 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
66 import org.apache.geronimo.j2ee.management.impl.J2EEApplicationImpl;
67 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
68 import org.apache.geronimo.kernel.Kernel;
69 import org.apache.geronimo.kernel.Naming;
70 import org.apache.geronimo.kernel.config.ConfigurationAlreadyExistsException;
71 import org.apache.geronimo.kernel.config.ConfigurationData;
72 import org.apache.geronimo.kernel.config.ConfigurationManager;
73 import org.apache.geronimo.kernel.config.ConfigurationModuleType;
74 import org.apache.geronimo.kernel.config.ConfigurationStore;
75 import org.apache.geronimo.kernel.config.ConfigurationUtil;
76 import org.apache.geronimo.kernel.config.SimpleConfigurationManager;
77 import org.apache.geronimo.kernel.repository.Artifact;
78 import org.apache.geronimo.kernel.repository.ArtifactResolver;
79 import org.apache.geronimo.kernel.repository.Environment;
80 import org.apache.geronimo.kernel.repository.Repository;
81 import org.apache.geronimo.management.J2EEResource;
82 import org.apache.geronimo.management.J2EEServer;
83 import org.apache.geronimo.schema.SchemaConversionUtils;
84 import org.apache.geronimo.xbeans.geronimo.j2ee.GerApplicationDocument;
85 import org.apache.geronimo.xbeans.geronimo.j2ee.GerApplicationType;
86 import org.apache.geronimo.xbeans.geronimo.j2ee.GerExtModuleType;
87 import org.apache.geronimo.xbeans.geronimo.j2ee.GerModuleType;
88 import org.apache.geronimo.xbeans.j2ee.ApplicationType;
89 import org.apache.geronimo.xbeans.j2ee.ModuleType;
90 import org.apache.geronimo.xbeans.j2ee.ApplicationDocument;
91 import org.apache.xmlbeans.XmlException;
92 import org.apache.xmlbeans.XmlObject;
93 import org.apache.xmlbeans.XmlCursor;
94
95 /**
96 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
97 */
98 public class EARConfigBuilder implements ConfigurationBuilder, CorbaGBeanNameSource {
99
100 private static final Log log = LogFactory.getLog(EARConfigBuilder.class);
101 private static final String LINE_SEP = System.getProperty("line.separator");
102
103 private final static QName APPLICATION_QNAME = GerApplicationDocument.type.getDocumentElementName();
104
105 private final ConfigurationManager configurationManager;
106 private final Collection repositories;
107 private final SingleElementCollection ejbConfigBuilder;
108 private final SingleElementCollection webConfigBuilder;
109 private final SingleElementCollection connectorConfigBuilder;
110 private final SingleElementCollection appClientConfigBuilder;
111 private final SingleElementCollection resourceReferenceBuilder;
112 private final NamespaceDrivenBuilderCollection securityBuilders;
113 private final NamespaceDrivenBuilderCollection serviceBuilders;
114
115 private final Environment defaultEnvironment;
116 private final AbstractNameQuery serverName;
117 private final AbstractNameQuery transactionManagerObjectName;
118 private final AbstractNameQuery connectionTrackerObjectName;
119 private final AbstractNameQuery transactionalTimerObjectName;
120 private final AbstractNameQuery nonTransactionalTimerObjectName;
121 private final AbstractNameQuery corbaGBeanObjectName;
122 private final Naming naming;
123
124 public EARConfigBuilder(Environment defaultEnvironment,
125 AbstractNameQuery transactionManagerAbstractName,
126 AbstractNameQuery connectionTrackerAbstractName,
127 AbstractNameQuery transactionalTimerAbstractName,
128 AbstractNameQuery nonTransactionalTimerAbstractName,
129 AbstractNameQuery corbaGBeanAbstractName,
130 AbstractNameQuery serverName,
131 Collection repositories,
132 Collection ejbConfigBuilder,
133 Collection webConfigBuilder,
134 Collection connectorConfigBuilder,
135 Collection resourceReferenceBuilder,
136 Collection appClientConfigBuilder,
137 Collection securityBuilders,
138 Collection serviceBuilders,
139 Kernel kernel) {
140 this(defaultEnvironment,
141 transactionManagerAbstractName,
142 connectionTrackerAbstractName,
143 transactionalTimerAbstractName,
144 nonTransactionalTimerAbstractName,
145 corbaGBeanAbstractName,
146 serverName,
147 ConfigurationUtil.getConfigurationManager(kernel),
148 repositories,
149 new SingleElementCollection(ejbConfigBuilder),
150 new SingleElementCollection(webConfigBuilder),
151 new SingleElementCollection(connectorConfigBuilder),
152 new SingleElementCollection(resourceReferenceBuilder),
153 new SingleElementCollection(appClientConfigBuilder),
154 securityBuilders,
155 serviceBuilders,
156 kernel.getNaming());
157 }
158 public EARConfigBuilder(Environment defaultEnvironment,
159 AbstractNameQuery transactionManagerAbstractName,
160 AbstractNameQuery connectionTrackerAbstractName,
161 AbstractNameQuery transactionalTimerAbstractName,
162 AbstractNameQuery nonTransactionalTimerAbstractName,
163 AbstractNameQuery corbaGBeanAbstractName,
164 AbstractNameQuery serverName,
165 Collection repositories,
166 ModuleBuilder ejbConfigBuilder,
167 ModuleBuilder webConfigBuilder,
168 ModuleBuilder connectorConfigBuilder,
169 ActivationSpecInfoLocator activationSpecInfoLocator,
170 ModuleBuilder appClientConfigBuilder,
171 NamespaceDrivenBuilder securityBuilder,
172 NamespaceDrivenBuilder serviceBuilder,
173 Naming naming) {
174 this(defaultEnvironment,
175 transactionManagerAbstractName,
176 connectionTrackerAbstractName,
177 transactionalTimerAbstractName,
178 nonTransactionalTimerAbstractName,
179 corbaGBeanAbstractName,
180 serverName,
181 null,
182 repositories,
183 new SingleElementCollection(ejbConfigBuilder),
184 new SingleElementCollection(webConfigBuilder),
185 new SingleElementCollection(connectorConfigBuilder),
186 new SingleElementCollection(activationSpecInfoLocator),
187 new SingleElementCollection(appClientConfigBuilder),
188 securityBuilder == null? Collections.EMPTY_SET: Collections.singleton(securityBuilder),
189 serviceBuilder == null? Collections.EMPTY_SET: Collections.singleton(serviceBuilder),
190 naming);
191 }
192
193 private EARConfigBuilder(Environment defaultEnvironment,
194 AbstractNameQuery transactionManagerAbstractName,
195 AbstractNameQuery connectionTrackerAbstractName,
196 AbstractNameQuery transactionalTimerAbstractName,
197 AbstractNameQuery nonTransactionalTimerAbstractName,
198 AbstractNameQuery corbaGBeanAbstractName,
199 AbstractNameQuery serverName,
200 ConfigurationManager configurationManager,
201 Collection repositories,
202 SingleElementCollection ejbConfigBuilder,
203 SingleElementCollection webConfigBuilder,
204 SingleElementCollection connectorConfigBuilder,
205 SingleElementCollection resourceReferenceBuilder,
206 SingleElementCollection appClientConfigBuilder,
207 Collection securityBuilders,
208 Collection serviceBuilders,
209 Naming naming) {
210 this.configurationManager = configurationManager;
211 this.repositories = repositories;
212 this.defaultEnvironment = defaultEnvironment;
213
214 this.ejbConfigBuilder = ejbConfigBuilder;
215 this.resourceReferenceBuilder = resourceReferenceBuilder;
216 this.webConfigBuilder = webConfigBuilder;
217 this.connectorConfigBuilder = connectorConfigBuilder;
218 this.appClientConfigBuilder = appClientConfigBuilder;
219 this.securityBuilders = new NamespaceDrivenBuilderCollection(securityBuilders);
220 this.serviceBuilders = new NamespaceDrivenBuilderCollection(serviceBuilders);
221
222 this.transactionManagerObjectName = transactionManagerAbstractName;
223 this.connectionTrackerObjectName = connectionTrackerAbstractName;
224 this.transactionalTimerObjectName = transactionalTimerAbstractName;
225 this.nonTransactionalTimerObjectName = nonTransactionalTimerAbstractName;
226 this.corbaGBeanObjectName = corbaGBeanAbstractName;
227 this.serverName = serverName;
228 this.naming = naming;
229 }
230
231
232 public AbstractNameQuery getCorbaGBeanName() {
233 return corbaGBeanObjectName;
234 }
235
236 private ModuleBuilder getEjbConfigBuilder() {
237 return (ModuleBuilder) ejbConfigBuilder.getElement();
238 }
239
240 private ModuleBuilder getWebConfigBuilder() {
241 return (ModuleBuilder) webConfigBuilder.getElement();
242 }
243
244 private ModuleBuilder getConnectorConfigBuilder() {
245 return (ModuleBuilder) connectorConfigBuilder.getElement();
246 }
247
248 private ModuleBuilder getAppClientConfigBuilder() {
249 return (ModuleBuilder) appClientConfigBuilder.getElement();
250 }
251
252 private ActivationSpecInfoLocator getResourceReferenceBuilder() {
253 return (ActivationSpecInfoLocator) resourceReferenceBuilder.getElement();
254 }
255
256 public Object getDeploymentPlan(File planFile, JarFile jarFile, ModuleIDBuilder idBuilder) throws DeploymentException {
257 if (planFile == null && jarFile == null) {
258 return null;
259 }
260 ApplicationInfo plan = getEarPlan(planFile, jarFile, idBuilder);
261 if (plan != null) {
262 return plan;
263 }
264
265 if (jarFile == null) {
266 return null;
267 }
268
269
270 Module module = null;
271 if (getWebConfigBuilder() != null) {
272 module = getWebConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
273 }
274 if (module == null && getEjbConfigBuilder() != null) {
275 module = getEjbConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
276 }
277 if (module == null && getConnectorConfigBuilder() != null) {
278 module = getConnectorConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
279 }
280 if (module == null && getAppClientConfigBuilder() != null) {
281 module = getAppClientConfigBuilder().createModule(planFile, jarFile, naming, idBuilder);
282 }
283 if (module == null) {
284 return null;
285 }
286
287 return new ApplicationInfo(module.getType(),
288 module.getEnvironment(),
289 module.getModuleName(),
290 null,
291 null,
292 new LinkedHashSet(Collections.singleton(module)),
293 Collections.EMPTY_SET,
294 null);
295 }
296
297 private ApplicationInfo getEarPlan(File planFile, JarFile earFile, ModuleIDBuilder idBuilder) throws DeploymentException {
298 String specDD;
299 ApplicationType application = null;
300 if (earFile != null) {
301 try {
302 URL applicationXmlUrl = DeploymentUtil.createJarURL(earFile, "META-INF/application.xml");
303 specDD = DeploymentUtil.readAll(applicationXmlUrl);
304 } catch (Exception e) {
305
306 return null;
307 }
308
309 try {
310 XmlObject xmlObject = XmlBeansUtil.parse(specDD);
311 application = convertToApplicationSchema(xmlObject).getApplication();
312 } catch (XmlException e) {
313 throw new DeploymentException("Could not parse application.xml", e);
314 }
315 }
316
317 GerApplicationType gerApplication = null;
318 try {
319
320 XmlObject rawPlan;
321 try {
322 if (planFile != null) {
323 rawPlan = XmlBeansUtil.parse(planFile.toURL(), getClass().getClassLoader());
324 gerApplication = (GerApplicationType) SchemaConversionUtils.fixGeronimoSchema(rawPlan, APPLICATION_QNAME, GerApplicationType.type);
325 if (gerApplication == null) {
326 return null;
327 }
328 } else {
329 URL path = DeploymentUtil.createJarURL(earFile, "META-INF/geronimo-application.xml");
330 rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
331 gerApplication = (GerApplicationType) SchemaConversionUtils.fixGeronimoSchema(rawPlan, APPLICATION_QNAME, GerApplicationType.type);
332 }
333 } catch (IOException e) {
334
335 }
336
337
338 if (gerApplication == null) {
339 gerApplication = createDefaultPlan(application, earFile);
340 }
341 } catch (XmlException e) {
342 throw new DeploymentException(e);
343 }
344
345 EnvironmentType environmentType = gerApplication.getEnvironment();
346 Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
347 idBuilder.resolve(environment, earFile == null ? planFile.getName() : new File(earFile.getName()).getName(), "ear");
348
349 idBuilder.setDefaultGroup(environment.getConfigId().getGroupId());
350 idBuilder.setDefaultVersion(environment.getConfigId().getVersion());
351
352 Artifact artifact = environment.getConfigId();
353 AbstractName earName = naming.createRootName(artifact, artifact.toString(), NameFactory.J2EE_APPLICATION);
354
355
356
357
358 Set moduleLocations = new HashSet();
359 LinkedHashSet modules = new LinkedHashSet();
360 try {
361 addModules(earFile, application, gerApplication, moduleLocations, modules, environment, earName, idBuilder);
362 } catch (Throwable e) {
363
364 for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
365 Module module = (Module) iterator.next();
366 module.close();
367 }
368
369 if (e instanceof DeploymentException) {
370 throw (DeploymentException) e;
371 } else if (e instanceof RuntimeException) {
372 throw (RuntimeException) e;
373 } else if (e instanceof Error) {
374 throw (Error) e;
375 }
376 throw new DeploymentException(e);
377 }
378
379 return new ApplicationInfo(ConfigurationModuleType.EAR,
380 environment,
381 earName,
382 application,
383 gerApplication,
384 modules,
385 moduleLocations,
386 application == null ? null : application.toString());
387 }
388
389
390 private GerApplicationType createDefaultPlan(ApplicationType application, JarFile module) {
391
392 GerApplicationType gerApplication = GerApplicationType.Factory.newInstance();
393 EnvironmentType environmentType = gerApplication.addNewEnvironment();
394 ArtifactType artifactType = environmentType.addNewModuleId();
395
396 artifactType.setGroupId(Artifact.DEFAULT_GROUP_ID);
397
398
399 String id = application.getId();
400 if (id == null) {
401 File fileName = new File(module.getName());
402 id = fileName.getName();
403 if (id.endsWith(".ear")) {
404 id = id.substring(0, id.length() - 4);
405 }
406 if (id.endsWith("/")) {
407 id = id.substring(0, id.length() - 1);
408 }
409 }
410
411 artifactType.setArtifactId(id);
412 artifactType.setVersion("" + System.currentTimeMillis());
413 artifactType.setType("car");
414 return gerApplication;
415 }
416
417 static ApplicationDocument convertToApplicationSchema(XmlObject xmlObject) throws XmlException {
418 if (ApplicationDocument.type.equals(xmlObject.schemaType())) {
419 XmlBeansUtil.validateDD(xmlObject);
420 return (ApplicationDocument) xmlObject;
421 }
422 XmlCursor cursor = xmlObject.newCursor();
423 XmlCursor moveable = xmlObject.newCursor();
424 String schemaLocationURL = "http://java.sun.com/xml/ns/j2ee/application_1_4.xsd";
425 String version = "1.4";
426 try {
427 SchemaConversionUtils.convertToSchema(cursor, SchemaConversionUtils.J2EE_NAMESPACE, schemaLocationURL, version);
428 cursor.toStartDoc();
429 cursor.toChild(SchemaConversionUtils.J2EE_NAMESPACE, "application");
430 cursor.toFirstChild();
431 SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.J2EE_NAMESPACE, cursor, moveable);
432 } finally {
433 cursor.dispose();
434 moveable.dispose();
435 }
436 XmlObject result = xmlObject.changeType(ApplicationDocument.type);
437 if (result != null) {
438 XmlBeansUtil.validateDD(result);
439 return (ApplicationDocument) result;
440 }
441 XmlBeansUtil.validateDD(xmlObject);
442 return (ApplicationDocument) xmlObject;
443 }
444
445 public Artifact getConfigurationID(Object plan, JarFile module, ModuleIDBuilder idBuilder) throws IOException, DeploymentException {
446 ApplicationInfo applicationInfo = (ApplicationInfo) plan;
447 Artifact test = applicationInfo.getEnvironment().getConfigId();
448 if(!test.isResolved()) {
449 throw new IllegalStateException("Module ID should be fully resolved by now (not "+test+")");
450 }
451 return test;
452 }
453
454 public DeploymentContext buildConfiguration(boolean inPlaceDeployment, Artifact configId, Object plan, JarFile earFile, Collection configurationStores, ArtifactResolver artifactResolver, ConfigurationStore targetConfigurationStore) throws IOException, DeploymentException {
455 assert plan != null;
456 ApplicationInfo applicationInfo = (ApplicationInfo) plan;
457
458 EARContext earContext = null;
459 ConfigurationModuleType applicationType = applicationInfo.getType();
460 applicationInfo.getEnvironment().setConfigId(configId);
461 File configurationDir;
462 try {
463 configurationDir = targetConfigurationStore.createNewConfigurationDir(configId);
464 } catch (ConfigurationAlreadyExistsException e) {
465 throw new DeploymentException(e);
466 }
467
468 ConfigurationManager configurationManager = this.configurationManager;
469 if (configurationManager == null) {
470 configurationManager = new SimpleConfigurationManager(configurationStores, artifactResolver, repositories);
471 }
472 try {
473
474 earContext = new EARContext(configurationDir,
475 inPlaceDeployment ? DeploymentUtil.toFile(earFile) : null,
476 applicationInfo.getEnvironment(),
477 applicationType,
478 naming,
479 configurationManager,
480 repositories,
481 serverName,
482 applicationInfo.getBaseName(),
483 transactionManagerObjectName,
484 connectionTrackerObjectName,
485 transactionalTimerObjectName,
486 nonTransactionalTimerObjectName,
487 corbaGBeanObjectName
488 );
489
490
491 Set moduleLocations = applicationInfo.getModuleLocations();
492 if (ConfigurationModuleType.EAR == applicationType && earFile != null) {
493 for (Enumeration e = earFile.entries(); e.hasMoreElements();) {
494 ZipEntry entry = (ZipEntry) e.nextElement();
495 String entryName = entry.getName();
496 boolean addEntry = true;
497 for (Iterator iter = moduleLocations.iterator(); iter.hasNext();) {
498 String location = (String) iter.next();
499 if (entryName.startsWith(location)) {
500 addEntry = false;
501 break;
502 }
503 }
504 if (addEntry) {
505 earContext.addFile(URI.create(entry.getName()), earFile, entry);
506 }
507 }
508 }
509
510 GerApplicationType geronimoApplication = (GerApplicationType) applicationInfo.getVendorDD();
511
512
513 LinkedHashSet modules = applicationInfo.getModules();
514 for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
515 Module module = (Module) iterator.next();
516 getBuilder(module).installModule(earFile, earContext, module, configurationStores, targetConfigurationStore, repositories);
517 }
518
519 earContext.flush();
520
521
522 ClassLoader cl = earContext.getClassLoader();
523 for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
524 Module module = (Module) iterator.next();
525 getBuilder(module).initContext(earContext, module, cl);
526 }
527
528
529 if (geronimoApplication != null) {
530 securityBuilders.build(geronimoApplication, earContext, earContext);
531 serviceBuilders.build(geronimoApplication, earContext, earContext);
532 }
533
534
535 if (ConfigurationModuleType.EAR == applicationType) {
536 GBeanData gbeanData = new GBeanData(earContext.getModuleName(), J2EEApplicationImpl.GBEAN_INFO);
537 try {
538 String originalSpecDD = applicationInfo.getOriginalSpecDD();
539 if (originalSpecDD == null) {
540 originalSpecDD = "Synthetic EAR";
541 }
542 gbeanData.setAttribute("deploymentDescriptor", originalSpecDD);
543 } catch (Exception e) {
544 throw new DeploymentException("Error initializing J2EEApplication managed object");
545 }
546 gbeanData.setReferencePatterns("Server", new ReferencePatterns(new AbstractNameQuery(J2EEServer.class.getName())));
547
548 Map thisApp = Collections.singletonMap(NameFactory.J2EE_APPLICATION, earContext.getModuleName().getNameProperty(NameFactory.J2EE_NAME));
549 LinkedHashSet resourcePatterns = new LinkedHashSet();
550 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JAVA_MAIL_RESOURCE), J2EEResource.class.getName()));
551 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JCA_CONNECTION_FACTORY), J2EEResource.class.getName()));
552 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JDBC_RESOURCE), J2EEResource.class.getName()));
553 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JDBC_DRIVER), J2EEResource.class.getName()));
554 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JMS_RESOURCE), J2EEResource.class.getName()));
555 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JNDI_RESOURCE), J2EEResource.class.getName()));
556 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.JTA_RESOURCE), J2EEResource.class.getName()));
557 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.RMI_IIOP_RESOURCE), J2EEResource.class.getName()));
558 resourcePatterns.add(new AbstractNameQuery(null, filter(thisApp, NameFactory.J2EE_TYPE, NameFactory.URL_RESOURCE), J2EEResource.class.getName()));
559 gbeanData.setReferencePatterns("Resources", resourcePatterns);
560
561 gbeanData.setReferencePatterns("AppClientModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.AppClientModule.class.getName())));
562 gbeanData.setReferencePatterns("EJBModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.EJBModule.class.getName())));
563 gbeanData.setReferencePatterns("ResourceAdapterModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.geronimo.ResourceAdapterModule.class.getName())));
564 gbeanData.setReferencePatterns("WebModules", new ReferencePatterns(new AbstractNameQuery(null, thisApp, org.apache.geronimo.management.geronimo.WebModule.class.getName())));
565 earContext.addGBean(gbeanData);
566 }
567
568
569 for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
570 Module module = (Module) iterator.next();
571 getBuilder(module).addGBeans(earContext, module, cl, repositories);
572 }
573
574
575 return earContext;
576 } catch (GBeanAlreadyExistsException e) {
577 cleanupContext(earContext, configurationDir);
578 throw new DeploymentException(e);
579 } catch (IOException e) {
580 cleanupContext(earContext, configurationDir);
581 throw e;
582 } catch (DeploymentException e) {
583 cleanupContext(earContext, configurationDir);
584 throw e;
585 } catch(RuntimeException e) {
586 cleanupContext(earContext, configurationDir);
587 throw e;
588 } catch(Error e) {
589 cleanupContext(earContext, configurationDir);
590 throw e;
591 } finally {
592 Set modules = applicationInfo.getModules();
593 for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
594 Module module = (Module) iterator.next();
595 module.close();
596 }
597 }
598 }
599
600 private void cleanupContext(EARContext earContext, File configurationDir) {
601 List configurations = new ArrayList();
602 if (earContext != null) {
603 configurations.addAll(earContext.getAdditionalDeployment());
604 try {
605 earContext.close();
606 } catch (IOException ioe) {
607
608 } catch (DeploymentException de) {
609
610 }
611 }
612
613 if (configurationDir != null) {
614 cleanupConfigurationDir(configurationDir);
615 }
616
617 for (Iterator iterator = configurations.iterator(); iterator.hasNext();) {
618 ConfigurationData configurationData = (ConfigurationData) iterator.next();
619 cleanupConfigurationDir(configurationData.getConfigurationDir());
620 }
621 }
622
623 private boolean cleanupConfigurationDir(File configurationDir)
624 {
625 LinkedList cannotBeDeletedList = new LinkedList();
626
627 if (!DeploymentUtil.recursiveDelete(configurationDir,cannotBeDeletedList)) {
628
629 log.warn("Unable to delete " + cannotBeDeletedList.size() +
630 " files while recursively deleting directory "
631 + configurationDir + LINE_SEP +
632 "The first file that could not be deleted was:" + LINE_SEP + " "+
633 ( !cannotBeDeletedList.isEmpty() ? cannotBeDeletedList.getFirst() : "") );
634 return false;
635 }
636 return true;
637 }
638
639 private static Map filter(Map original, String key, String value) {
640 LinkedHashMap filter = new LinkedHashMap(original);
641 filter.put(key, value);
642 return filter;
643 }
644
645 private void addModules(JarFile earFile, ApplicationType application, GerApplicationType gerApplication, Set moduleLocations, LinkedHashSet modules, Environment environment, AbstractName earName, ModuleIDBuilder idBuilder) throws DeploymentException {
646 Map altVendorDDs = new HashMap();
647 try {
648 if (earFile != null) {
649 ModuleType[] moduleTypes = application.getModuleArray();
650
651 Set paths = new HashSet();
652 for (int i = 0; i < moduleTypes.length; i++) {
653 ModuleType type = moduleTypes[i];
654 if (type.isSetEjb()) {
655 paths.add(type.getEjb().getStringValue());
656 } else if (type.isSetWeb()) {
657 paths.add(type.getWeb().getWebUri().getStringValue());
658 } else if (type.isSetConnector()) {
659 paths.add(type.getConnector().getStringValue());
660 } else if (type.isSetJava()) {
661 paths.add(type.getJava().getStringValue());
662 }
663 }
664
665
666 GerModuleType gerModuleTypes[] = gerApplication.getModuleArray();
667 for (int i = 0; i < gerModuleTypes.length; i++) {
668 GerModuleType gerModule = gerModuleTypes[i];
669 String path = null;
670 if (gerModule.isSetEjb()) {
671 path = gerModule.getEjb().getStringValue();
672 } else if (gerModule.isSetWeb()) {
673 path = gerModule.getWeb().getStringValue();
674 } else if (gerModule.isSetConnector()) {
675 path = gerModule.getConnector().getStringValue();
676 } else if (gerModule.isSetJava()) {
677 path = gerModule.getJava().getStringValue();
678 }
679 if (!paths.contains(path)) {
680 throw new DeploymentException("Geronimo deployment plan refers to module '" + path + "' but that was not defined in the META-INF/application.xml");
681 }
682
683 if (gerModule.isSetAltDd()) {
684
685 try {
686 altVendorDDs.put(path, DeploymentUtil.toTempFile(earFile, gerModule.getAltDd().getStringValue()));
687 } catch (IOException e) {
688 throw new DeploymentException("Invalid alt vendor dd url: " + gerModule.getAltDd().getStringValue(), e);
689 }
690 } else {
691
692 XmlObject[] anys = gerModule.selectChildren(GerModuleType.type.qnameSetForWildcardElements());
693 if (anys.length != 1) {
694 throw new DeploymentException("Unexpected count of xs:any elements in embedded vendor plan " + anys.length + " qnameset: " + GerModuleType.type.qnameSetForWildcardElements());
695 }
696 altVendorDDs.put(path, anys[0]);
697 }
698 }
699
700
701 for (int i = 0; i < moduleTypes.length; i++) {
702 ModuleType moduleXml = moduleTypes[i];
703
704 String modulePath;
705 ModuleBuilder builder;
706
707 Object moduleContextInfo = null;
708 String moduleTypeName;
709 if (moduleXml.isSetEjb()) {
710 modulePath = moduleXml.getEjb().getStringValue();
711 builder = getEjbConfigBuilder();
712 if (builder == null) {
713 throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + modulePath);
714 }
715 moduleTypeName = "an EJB";
716 } else if (moduleXml.isSetWeb()) {
717 modulePath = moduleXml.getWeb().getWebUri().getStringValue();
718 if (getWebConfigBuilder() == null) {
719 throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + modulePath);
720 }
721 builder = getWebConfigBuilder();
722 moduleTypeName = "a war";
723 moduleContextInfo = moduleXml.getWeb().getContextRoot().getStringValue().trim();
724 } else if (moduleXml.isSetConnector()) {
725 modulePath = moduleXml.getConnector().getStringValue();
726 if (getConnectorConfigBuilder() == null) {
727 throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + modulePath);
728 }
729 builder = getConnectorConfigBuilder();
730 moduleTypeName = "a connector";
731 } else if (moduleXml.isSetJava()) {
732 modulePath = moduleXml.getJava().getStringValue();
733 if (getAppClientConfigBuilder() == null) {
734 throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + modulePath);
735 }
736 builder = getAppClientConfigBuilder();
737 moduleTypeName = "an application client";
738 } else {
739 throw new DeploymentException("Could not find a module builder for module: " + moduleXml);
740 }
741
742 moduleLocations.add(modulePath);
743
744 URL altSpecDD = null;
745 if (moduleXml.isSetAltDd()) {
746 try {
747 altSpecDD = DeploymentUtil.createJarURL(earFile, moduleXml.getAltDd().getStringValue());
748 } catch (MalformedURLException e) {
749 throw new DeploymentException("Invalid alt sped dd url: " + moduleXml.getAltDd().getStringValue(), e);
750 }
751 }
752
753 NestedJarFile moduleFile;
754 try {
755 moduleFile = new NestedJarFile(earFile, modulePath);
756 } catch (IOException e) {
757 throw new DeploymentException("Invalid moduleFile: " + modulePath, e);
758 }
759
760 Module module = builder.createModule(altVendorDDs.get(modulePath),
761 moduleFile,
762 modulePath,
763 altSpecDD,
764 environment,
765 moduleContextInfo,
766 earName,
767 naming, idBuilder);
768
769 if (module == null) {
770 throw new DeploymentException("Module was not " + moduleTypeName + ": " + modulePath);
771 }
772
773 modules.add(module);
774 }
775 }
776
777
778 GerExtModuleType gerExtModuleTypes[] = gerApplication.getExtModuleArray();
779 for (int i = 0; i < gerExtModuleTypes.length; i++) {
780 GerExtModuleType gerExtModule = gerExtModuleTypes[i];
781 String moduleName;
782 ModuleBuilder builder;
783 Object moduleContextInfo = null;
784 String moduleTypeName;
785
786 if (gerExtModule.isSetEjb()) {
787 moduleName = gerExtModule.getEjb().getStringValue();
788 builder = getEjbConfigBuilder();
789 if (builder == null) {
790 throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + moduleName);
791 }
792 moduleTypeName = "an EJB";
793 } else if (gerExtModule.isSetWeb()) {
794 moduleName = gerExtModule.getWeb().getStringValue();
795 if (getWebConfigBuilder() == null) {
796 throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + moduleName);
797 }
798 builder = getWebConfigBuilder();
799 moduleTypeName = "a war";
800
801
802 } else if (gerExtModule.isSetConnector()) {
803 moduleName = gerExtModule.getConnector().getStringValue();
804 if (getConnectorConfigBuilder() == null) {
805 throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + moduleName);
806 }
807 builder = getConnectorConfigBuilder();
808 moduleTypeName = "a connector";
809 } else if (gerExtModule.isSetJava()) {
810 moduleName = gerExtModule.getJava().getStringValue();
811 if (getAppClientConfigBuilder() == null) {
812 throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + moduleName);
813 }
814 builder = getAppClientConfigBuilder();
815 moduleTypeName = "an application client";
816 } else {
817 throw new DeploymentException("Could not find a module builder for module: " + gerExtModule);
818 }
819
820 XmlObject[] anys = gerExtModule.selectChildren(GerExtModuleType.type.qnameSetForWildcardElements());
821 if (anys.length != 1) {
822 throw new DeploymentException("Unexpected count of xs:any elements in embedded vendor plan " + anys.length + " qnameset: " + GerExtModuleType.type.qnameSetForWildcardElements());
823 }
824 Object vendorDD = anys[0];
825
826 JarFile moduleFile;
827 if (gerExtModule.isSetInternalPath()) {
828 String modulePath = gerExtModule.getInternalPath().trim();
829 moduleLocations.add(modulePath);
830 try {
831 moduleFile = new NestedJarFile(earFile, modulePath);
832 } catch (IOException e) {
833 throw new DeploymentException("Invalid moduleFile: " + modulePath, e);
834 }
835 } else {
836 String path = gerExtModule.getExternalPath().trim();
837 Artifact artifact = Artifact.create(path);
838 File location = null;
839 for (Iterator iterator = repositories.iterator(); iterator.hasNext();) {
840 Repository repository = (Repository) iterator.next();
841 if (repository.contains(artifact)) {
842 location = repository.getLocation(artifact);
843 break;
844 }
845 }
846 if (location == null) {
847 throw new DeploymentException(moduleTypeName + " is missing in repositories: " + path);
848 }
849 try {
850 moduleFile = new JarFile(location);
851 } catch (IOException e) {
852 throw new DeploymentException("Could not access contents of " + moduleTypeName, e);
853 }
854
855 }
856
857
858 URL altSpecDD = null;
859
860
861
862
863
864
865
866
867
868
869 Module module = builder.createModule(vendorDD,
870 moduleFile,
871 moduleName,
872 altSpecDD,
873 environment,
874 moduleContextInfo,
875 earName,
876 naming, idBuilder);
877
878 if (module == null) {
879 throw new DeploymentException("Module was not " + moduleTypeName + ": " + moduleName);
880 }
881
882 modules.add(module);
883 }
884
885
886 } finally {
887
888 for (Iterator iterator = altVendorDDs.values().iterator(); iterator.hasNext();) {
889 Object altVendorDD = iterator.next();
890 if (altVendorDD instanceof File) {
891 ((File) altVendorDD).delete();
892 }
893 }
894 }
895 }
896
897 private ModuleBuilder getBuilder(Module module) throws DeploymentException {
898 if (module instanceof EJBModule) {
899 if (getEjbConfigBuilder() == null) {
900 throw new DeploymentException("Cannot deploy ejb application; No ejb deployer defined: " + module.getModuleURI());
901 }
902 return getEjbConfigBuilder();
903 } else if (module instanceof WebModule) {
904 if (getWebConfigBuilder() == null) {
905 throw new DeploymentException("Cannot deploy web application; No war deployer defined: " + module.getModuleURI());
906 }
907 return getWebConfigBuilder();
908 } else if (module instanceof ConnectorModule) {
909 if (getConnectorConfigBuilder() == null) {
910 throw new DeploymentException("Cannot deploy resource adapter; No rar deployer defined: " + module.getModuleURI());
911 }
912 return getConnectorConfigBuilder();
913 } else if (module instanceof AppClientModule) {
914 if (getAppClientConfigBuilder() == null) {
915 throw new DeploymentException("Cannot deploy app client; No app client deployer defined: " + module.getModuleURI());
916 }
917 return getAppClientConfigBuilder();
918 }
919 throw new IllegalArgumentException("Unknown module type: " + module.getClass().getName());
920 }
921
922 public static final GBeanInfo GBEAN_INFO;
923
924 static {
925 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(EARConfigBuilder.class, NameFactory.CONFIG_BUILDER);
926 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
927 infoBuilder.addAttribute("transactionManagerAbstractName", AbstractNameQuery.class, true);
928 infoBuilder.addAttribute("connectionTrackerAbstractName", AbstractNameQuery.class, true);
929 infoBuilder.addAttribute("transactionalTimerAbstractName", AbstractNameQuery.class, true);
930 infoBuilder.addAttribute("nonTransactionalTimerAbstractName", AbstractNameQuery.class, true);
931 infoBuilder.addAttribute("corbaGBeanAbstractName", AbstractNameQuery.class, true);
932 infoBuilder.addAttribute("serverName", AbstractNameQuery.class, true);
933
934 infoBuilder.addReference("Repositories", Repository.class, "Repository");
935 infoBuilder.addReference("EJBConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
936 infoBuilder.addReference("WebConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
937 infoBuilder.addReference("ConnectorConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
938 infoBuilder.addReference("ActivationSpecInfoLocator", ActivationSpecInfoLocator.class, NameFactory.MODULE_BUILDER);
939 infoBuilder.addReference("AppClientConfigBuilder", ModuleBuilder.class, NameFactory.MODULE_BUILDER);
940 infoBuilder.addReference("SecurityBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
941 infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
942
943 infoBuilder.addAttribute("kernel", Kernel.class, false);
944
945 infoBuilder.addInterface(ConfigurationBuilder.class);
946
947 infoBuilder.setConstructor(new String[]{
948 "defaultEnvironment",
949 "transactionManagerAbstractName",
950 "connectionTrackerAbstractName",
951 "transactionalTimerAbstractName",
952 "nonTransactionalTimerAbstractName",
953 "corbaGBeanAbstractName",
954 "serverName",
955 "Repositories",
956 "EJBConfigBuilder",
957 "WebConfigBuilder",
958 "ConnectorConfigBuilder",
959 "ActivationSpecInfoLocator",
960 "AppClientConfigBuilder",
961 "SecurityBuilders",
962 "ServiceBuilders",
963 "kernel"
964 });
965
966 GBEAN_INFO = infoBuilder.getBeanInfo();
967 }
968
969 public static GBeanInfo getGBeanInfo() {
970 return GBEAN_INFO;
971 }
972
973 }