0001: /**
0002: * JOnAS: Java(TM) Open Application Server
0003: * Copyright (C) 1999-2007 Bull S.A.S.
0004: * Contact: jonas-team@objectweb.org
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2.1 of the License, or any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Lesser General Public
0017: * License along with this library; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
0019: * USA
0020: *
0021: * --------------------------------------------------------------------------
0022: * $Id: EjbDeploymentDescManager.java 10277 2007-04-24 11:52:58Z benoitf $
0023: * --------------------------------------------------------------------------
0024: */package org.objectweb.jonas_ejb.deployment.lib;
0025:
0026: import java.io.File;
0027: import java.io.FileInputStream;
0028: import java.io.FileNotFoundException;
0029: import java.io.IOException;
0030: import java.io.InputStream;
0031: import java.io.InputStreamReader;
0032: import java.io.Reader;
0033: import java.net.MalformedURLException;
0034: import java.net.URL;
0035: import java.net.URLClassLoader;
0036: import java.util.Enumeration;
0037: import java.util.Hashtable;
0038: import java.util.List;
0039: import java.util.StringTokenizer;
0040: import java.util.Vector;
0041: import java.util.zip.ZipEntry;
0042: import java.util.zip.ZipFile;
0043:
0044: import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
0045: import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
0046: import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb1_1;
0047: import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
0048: import org.objectweb.jonas_ejb.deployment.api.EjbjarDTDs;
0049: import org.objectweb.jonas_ejb.deployment.api.EjbjarSchemas;
0050: import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
0051: import org.objectweb.jonas_ejb.deployment.api.JonasEjbjarDTDs;
0052: import org.objectweb.jonas_ejb.deployment.api.JonasEjbjarSchemas;
0053: import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
0054: import org.objectweb.jonas_ejb.deployment.api.SessionDesc;
0055: import org.objectweb.jonas_ejb.deployment.rules.EjbJarRuleSet;
0056: import org.objectweb.jonas_ejb.deployment.rules.JonasEjbJarRuleSet;
0057: import org.objectweb.jonas_ejb.deployment.xml.EjbJar;
0058: import org.objectweb.jonas_ejb.deployment.xml.JonasEjbJar;
0059: import org.objectweb.jonas_ejb.lib.BeanNaming;
0060:
0061: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
0062: import org.objectweb.jonas_lib.deployment.api.EjbLocalRefDesc;
0063: import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
0064: import org.objectweb.jonas_lib.deployment.api.JndiEnvRefsGroup;
0065: import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc;
0066: import org.objectweb.jonas_lib.deployment.digester.JDigester;
0067: import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
0068: import org.objectweb.jonas_lib.deployment.xml.JonasMessageDestination;
0069:
0070: import org.objectweb.jonas_ws.deployment.api.PortComponentDesc;
0071: import org.objectweb.jonas_ws.deployment.api.PortComponentRefDesc;
0072: import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc;
0073: import org.objectweb.jonas_ws.deployment.api.WSDeploymentDescException;
0074: import org.objectweb.jonas_ws.deployment.lib.WSDeploymentDescManager;
0075:
0076: import org.objectweb.jonas.common.Log;
0077:
0078: import org.objectweb.util.monolog.api.BasicLevel;
0079: import org.objectweb.util.monolog.api.Logger;
0080:
0081: /**
0082: * This class provide a way for managing the EjbDeploymentDesc.
0083: * Note that there is an intance of the EjbDeploymentDescManager on each JOnAS
0084: * server.
0085: * @author Ludovic Bert
0086: * @author Florent Benoit
0087: * @author Nicolas Van Caneghem <nicolas.vancaneghem@openpricer.com>
0088: * Allow the deployment of an exploded ear
0089: * Contributors:<br>
0090: * JOnAS 4.0 Adriana Danes: keep deployement descriptors is a Stringified format
0091: * for management support.
0092: */
0093: public class EjbDeploymentDescManager extends AbsDeploymentDescManager {
0094:
0095: /**
0096: * ejb-jar.xml filename
0097: */
0098: public static final String EJB_JAR_FILE_NAME = "META-INF/ejb-jar.xml";
0099:
0100: /**
0101: * jonas-ejb-jar.xml filename
0102: */
0103: public static final String JONAS_EJB_JAR_FILE_NAME = "META-INF/jonas-ejb-jar.xml";
0104:
0105: /**
0106: * Flag for parser validation
0107: */
0108: private static boolean parsingWithValidation = true;
0109:
0110: /**
0111: * The unique instance of the EjbDeploymentDescManager.
0112: */
0113: private static EjbDeploymentDescManager unique;
0114:
0115: /**
0116: * Digester used to parse ejb-jar.xml
0117: */
0118: private static JDigester ejbjarDigester = null;
0119:
0120: /**
0121: * Digester use to parse jonas-ejb-ja.xml
0122: */
0123: private static JDigester jonasEjbjarDigester = null;
0124:
0125: /**
0126: * Rules to parse the application-client.xml
0127: */
0128: private static EjbJarRuleSet ejbjarRuleSet = new EjbJarRuleSet();
0129:
0130: /**
0131: * Rules to parse the jonas-client.xml
0132: */
0133: private static JonasEjbJarRuleSet jonasEjbjarRuleSet = new JonasEjbJarRuleSet();
0134:
0135: /**
0136: * Reference on the WSDeploymentDescManager.
0137: */
0138: private WSDeploymentDescManager wsDDManager = null;
0139:
0140: /**
0141: * Associates an URL of an ejb-jar to its ejb deployment descriptor.
0142: * It's the cache.
0143: */
0144: private Hashtable urlJarBindings;
0145:
0146: /**
0147: * Associates an URL to an ear classloader. (ear only)
0148: */
0149: private Hashtable urlEarCLBindings;
0150:
0151: /**
0152: * Associates an URL to an ejb classloader. (ear only)
0153: */
0154: private Hashtable urlEjbCLBindings;
0155:
0156: /**
0157: * Associates an URL to an alternate DDesc file.
0158: */
0159: private Hashtable urlAltDDBindings = null;
0160:
0161: /**
0162: * Associates an ear classloader to a list of URLs. It is used to know if
0163: * the ejb-link or message-destination-link is authorised. An ejb-link or
0164: * mesage-destination is authorized only in the same ear.
0165: */
0166: private Hashtable earCLEjbLinkJar;
0167:
0168: /**
0169: * Logger for the deployment desc manager.
0170: */
0171: private static Logger logger = Log
0172: .getLogger("org.objectweb.jonas_ejb.dd");
0173:
0174: /**
0175: * cache used for WsGen (multiple calls)
0176: */
0177: private static Hashtable staticCache = new Hashtable();
0178:
0179: /**
0180: * Xml content of the standard deployement descriptor file
0181: */
0182: private static String xmlContent = "";
0183:
0184: /**
0185: * Xml content of the JOnAS deployement descriptor file
0186: */
0187: private static String jonasXmlContent = "";
0188:
0189: /**
0190: * Contructs a unique new EjbDeploymentDescManager.
0191: */
0192: private EjbDeploymentDescManager() {
0193: urlJarBindings = new Hashtable();
0194: urlEarCLBindings = new Hashtable();
0195: urlEjbCLBindings = new Hashtable();
0196: earCLEjbLinkJar = new Hashtable();
0197: urlAltDDBindings = new Hashtable();
0198: }
0199:
0200: /**
0201: * Get an instance of the EjbDeploymentDescManager.
0202: * @return the instance of the EjbDeploymentDescManager.
0203: */
0204: public static EjbDeploymentDescManager getInstance() {
0205: if (unique == null) {
0206: unique = new EjbDeploymentDescManager();
0207: }
0208: return unique;
0209: }
0210:
0211: /**
0212: * Factory method using the ejb-jar file name.
0213: * Used by GenIC/GenIDL/WsGen.
0214: * @param ejbjar ejbjar file name
0215: * @param ejbLoader classloader used to load bean classes.
0216: * @return instance of the corresponding DeploymentDesc
0217: * @exception DeploymentDescException when DeploymentDesc cannot be created with
0218: * given ejb-jar file.
0219: */
0220: public static DeploymentDesc getDeploymentDesc(String ejbjar,
0221: ClassLoader ejbLoader) throws DeploymentDescException {
0222: if (!staticCache.containsKey(ejbjar)) {
0223: return getDeploymentDescriptor(ejbjar, ejbLoader,
0224: (String) null);
0225: } else {
0226: return (DeploymentDesc) staticCache.get(ejbjar);
0227: }
0228: }
0229:
0230: /**
0231: * Get the specified ejb deployment descriptor and put it in the cache
0232: * if it is not in.
0233: * Called by createContainer & WebDeploymentDescManager
0234: * @param url the url where to load xml deployment descriptors.
0235: * @param ejbLoader classloader used to load bean classes.
0236: * @param earLoader the parent classloader (the ear classloader). Null if
0237: * there in the case of an ejb-jar application.
0238: * @return DeploymentDesc the ejb deployment descriptor. (This method is
0239: * used for the ear applications).
0240: * @throws DeploymentDescException when DeploymentDesc cannot be created
0241: * with the given files.
0242: */
0243: public synchronized DeploymentDesc getDeploymentDesc(URL url,
0244: ClassLoader ejbLoader, ClassLoader earLoader)
0245: throws DeploymentDescException {
0246: // load an instance of the WebService Manager
0247: if (wsDDManager == null) {
0248: wsDDManager = WSDeploymentDescManager.getInstance();
0249: }
0250:
0251: // Check in the ejb-link is allowed : the ejb-link must be done
0252: // on an ejb-jar defined in the ear application.
0253: if (earLoader != null) {
0254: checkEjbLinkAvailable(earLoader, url);
0255: }
0256:
0257: DeploymentDesc dd = (DeploymentDesc) urlJarBindings.get(url
0258: .getFile());
0259: if (dd == null) {
0260: // dd not in cache => load the deployment descriptor.
0261: dd = loadDeploymentDesc(url, ejbLoader, earLoader);
0262: }
0263: return dd;
0264: }
0265:
0266: /**
0267: * Get the deployment descriptor of the ejb-link of the specified url.
0268: * @param currentUrl the URL of the component (web or bean)
0269: * that do an ejb-link.
0270: * @param urlToLoad the URL of the bean to get the deployment descriptor.
0271: * @return the deployment descriptor of the specified bean.
0272: * @throws DeploymentDescException when DeploymentDesc cannot be created
0273: * with the given files.
0274: */
0275: private DeploymentDesc getDeploymentDesc(URL currentUrl,
0276: URL urlToLoad) throws DeploymentDescException {
0277: DeploymentDesc ejbLinkDD = (DeploymentDesc) urlJarBindings
0278: .get(urlToLoad.getFile());
0279: if (ejbLinkDD == null) {
0280:
0281: // URL to load is a valid file ?
0282: if (!new File(urlToLoad.getFile()).exists()) {
0283: throw new DeploymentDescException(
0284: "There is an ejb-link from the '"
0285: + currentUrl
0286: + "' URL to the '"
0287: + urlToLoad
0288: + "' URL but the last file does not exist. Check ejb-link in the first file");
0289: }
0290:
0291: // ejbLinkDD not in cache => load the deployment descriptor.
0292: String url = currentUrl.getFile();
0293: URLClassLoader earLoader = (URLClassLoader) urlEarCLBindings
0294: .get(url);
0295: if (new File(url).isFile()) {
0296: if (!url.toLowerCase().endsWith(".jar")) {
0297: String err = "File '" + url + "' is not a jar file";
0298: throw new DeploymentDescException(err);
0299: }
0300: }
0301:
0302: if (earLoader != null) {
0303: // In the case of an ear application.
0304:
0305: // Check in the ejb-link is allowed : the ejb-link must be done
0306: // on an ejb-jar defined in the ear application.
0307: checkEjbLinkAvailable(earLoader, urlToLoad);
0308:
0309: // get the loader for classes (ejb classloader).
0310: URLClassLoader loaderForCls = (URLClassLoader) urlEjbCLBindings
0311: .get(url);
0312:
0313: // Build a default classloader
0314: if (loaderForCls == null) {
0315: loaderForCls = new URLClassLoader(
0316: new URL[] { urlToLoad });
0317: }
0318:
0319: // get the ear classloader.
0320: URLClassLoader loader = (URLClassLoader) urlEarCLBindings
0321: .get(url);
0322: ejbLinkDD = loadDeploymentDesc(urlToLoad, loaderForCls,
0323: loader);
0324: } else {
0325: // In the case of a non ear application.
0326: if (!currentUrl.getFile().equals(urlToLoad)) {
0327: String err = "In '"
0328: + url
0329: + "' ejb-link is not allowed outside the ejb-jar if you are not in an ear application.";
0330: throw new DeploymentDescException(err);
0331: }
0332: // else nothing to do.
0333: }
0334: }
0335: return ejbLinkDD;
0336: }
0337:
0338: /**
0339: * Load the specified ejb deployment descriptor and
0340: * put it in cache.
0341: * @param url where to load xml deployment descriptors.
0342: * @param ejbLoader classloader used to load bean classes.
0343: * @param earLoader the parent classloader (the ear classloader). Null when
0344: * not in the case of an ear application.
0345: * @return DeploymentDesc the ejb deployment descriptor.
0346: * @throws DeploymentDescException when DeploymentDesc cannot be created
0347: * with the given files.
0348: */
0349: private DeploymentDesc loadDeploymentDesc(URL url,
0350: ClassLoader ejbLoader, ClassLoader earLoader)
0351: throws DeploymentDescException {
0352: // Check if the ejb-jar exists.
0353: String filename = url.getFile();
0354: File f = new File(filename);
0355: if (!f.exists()) {
0356: throw new DeploymentDescException(filename + " not found");
0357: }
0358:
0359: // Get the instance of the DeploymentDesc.
0360: DeploymentDesc dd = null;
0361: if (f.isDirectory()) {
0362: dd = getDeploymentDescriptor(filename + EJB_JAR_FILE_NAME,
0363: BeanNaming.getJonasXmlName(filename
0364: + EJB_JAR_FILE_NAME), ejbLoader, f
0365: .getAbsolutePath());
0366:
0367: } else if (filename.toLowerCase().endsWith(".xml")) {
0368: // This is an XML file name: Treat it for upward compatibility
0369: // f is the ejb-jar.xml file, jonas specific is colocated to this file.
0370: File parent = f.getParentFile();
0371: dd = getDeploymentDescriptor(filename, BeanNaming
0372: .getJonasXmlName(filename), ejbLoader, parent
0373: .getAbsolutePath());
0374: } else {
0375: // This is an ejb-jar
0376: // Check if there is an altenate DD for this URL (ear only)
0377: String altname = null;
0378: URL altDDUrl = (URL) urlAltDDBindings.get(url.getFile());
0379: if (altDDUrl != null) {
0380: altname = altDDUrl.getFile();
0381: }
0382: dd = getDeploymentDescriptor(filename, ejbLoader, altname);
0383: }
0384:
0385: // Put it in the cache in case of ear.
0386: if (earLoader != null) {
0387: urlEjbCLBindings.put(filename, ejbLoader);
0388: urlEarCLBindings.put(filename, earLoader);
0389: }
0390:
0391: BeanDesc[] bd = dd.getBeanDesc();
0392: for (int j = 0; j < bd.length; j++) {
0393:
0394: // Resolve the ejb-link for ejb-ref
0395: EjbRefDesc[] ejbRef = bd[j].getEjbRefDesc();
0396: for (int i = 0; i < ejbRef.length; i++) {
0397: String jndiName = ejbRef[i].getJndiName();
0398: String ejbLink = ejbRef[i].getEjbLink();
0399: String ejbRefType = ejbRef[i].getEjbRefType();
0400: if (ejbLink != null && jndiName == null) {
0401: String ejbName = getJndiName(url, ejbLink,
0402: earLoader, ejbRefType, dd, true);
0403: ejbRef[i].setJndiName(ejbName);
0404: }
0405: }
0406:
0407: // Resolve the ejb-link for ejb-local-ref
0408: EjbLocalRefDesc[] ejbLocalRef = bd[j].getEjbLocalRefDesc();
0409: for (int i = 0; i < ejbLocalRef.length; i++) {
0410: String ejblink = ejbLocalRef[i].getEjbLink();
0411: if (ejblink == null) {
0412: String err = "Ejb-link must be specified for ejb-local-ref "
0413: + ejbLocalRef[i].getEjbRefName();
0414: throw new DeploymentDescException(err);
0415: }
0416: String ejbRefType = ejbLocalRef[i].getEjbRefType();
0417: String ejbName = getJndiName(url, ejblink, earLoader,
0418: ejbRefType, dd, false);
0419: ejbLocalRef[i].setJndiLocalName(ejbName);
0420: }
0421:
0422: // Resolve the port-component-link for service-ref
0423: ServiceRefDesc[] serviceRef = bd[j].getServiceRefDesc();
0424:
0425: for (int i = 0; i < serviceRef.length; i++) {
0426: List pcRefs = serviceRef[i].getPortComponentRefs();
0427:
0428: for (int k = 0; k < pcRefs.size(); k++) {
0429: // for each service portComponents : resolve links
0430: PortComponentRefDesc pcr = (PortComponentRefDesc) pcRefs
0431: .get(k);
0432: String pclink = pcr.getPortComponentLink();
0433: if (pclink != null) {
0434: // a pc link is defined, we resolve it
0435: PortComponentDesc pcDesc = getPCDesc(url,
0436: pclink, ejbLoader, earLoader);
0437: pcr.setPortComponentDesc(pcDesc);
0438: }
0439: }
0440: }
0441:
0442: // Resolve the message-destination-link for message-destination-ref
0443: MessageDestinationRefDesc[] mdRef = bd[j]
0444: .getMessageDestinationRefDesc();
0445: for (int i = 0; i < mdRef.length; i++) {
0446: String jndiName = mdRef[i].getJndiName();
0447: String mdLink = mdRef[i].getMessageDestinationLink();
0448: String mdType = mdRef[i].getMessageDestinationType();
0449: String mdUsage = mdRef[i].getMessageDestinationUsage();
0450: if (logger.isLoggable(BasicLevel.DEBUG)) {
0451: logger.log(BasicLevel.DEBUG, "" + jndiName + " "
0452: + mdLink + " " + mdType + " " + mdUsage);
0453: }
0454: if (mdLink != null && jndiName == null) {
0455: String mdName = getMDJndiName(url, mdLink, mdType,
0456: mdUsage, dd);
0457: mdRef[i].setJndiName(mdName);
0458: }
0459: }
0460:
0461: }
0462:
0463: // ... and put it in cache if ear case.
0464: if (earLoader != null) {
0465: // case of ear application.
0466: urlJarBindings.put(filename, dd);
0467: }
0468:
0469: return dd;
0470: }
0471:
0472: /**
0473: * Return the port component desc from the pcLink string.
0474: * pcLink format : filename.[jar or war]#portComponentName in the same Ear File
0475: * portComponentName
0476: *
0477: * @param ejbjarURL the url of the ejbjar being parsed. This is needed
0478: * because pcLink is relative. With the url and the pcLink, we can
0479: * know where the file is located.
0480: * @param pcLink the pcLink tag of an port-component-ref.
0481: * @param earLoader the classloader of the ear.
0482: * @param moduleLoader the classloader of the current module
0483: *
0484: * @return the pcLink portComponent.
0485: *
0486: * @throws WSDeploymentDescException when it failed
0487: */
0488: private PortComponentDesc getPCDesc(URL ejbjarURL, String pcLink,
0489: ClassLoader moduleLoader, ClassLoader earLoader)
0490: throws WSDeploymentDescException {
0491:
0492: // now ask WS Manager for port-component-desc
0493: return wsDDManager.getPortComponentDesc(ejbjarURL, pcLink,
0494: moduleLoader, earLoader);
0495: }
0496:
0497: /**
0498: * Return the JNDI name from the ejbLink string.
0499: * ejbLink format : filename.jar#beanName in the same Ear File
0500: * beanName in the same ejb-jar file.
0501: * @param currentFile the url of the jar being parsed. This is needed because
0502: * ejbLink is relative. With the url and the ejbLink, we can know where
0503: * the file is locate.
0504: * @param ejbLink the ejbLink tag of an ejb-ref
0505: * @param earCl optionnal classloader
0506: * @param ejbType the type of the referenced ejb in the ejb-ref tag.
0507: * @param deploymentDesc the deployment descriptor of the parsed deploymentDesc.
0508: * @param isEjbRef true if the jndi name to resolve is an ejb-ref
0509: * @return the JNDI name if found, null otherwise
0510: * @throws DeploymentDescException when it failed
0511: */
0512: public String getJndiName(URL currentFile, String ejbLink,
0513: ClassLoader earCl, String ejbType,
0514: DeploymentDesc deploymentDesc, boolean isEjbRef)
0515: throws DeploymentDescException {
0516: // Extract from the ejb link
0517: // - the name of the file
0518: // - the name of the bean
0519: String ejbJarLink = null;
0520: String beanNameLink = null;
0521:
0522: //Same jar ?
0523: if (ejbLink.indexOf(LINK_SEPARATOR) == -1) {
0524: BeanDesc bd = null;
0525: //Link to a bean inside the same ejb-jar file.
0526: if (earCl == null && deploymentDesc == null) {
0527: throw new DeploymentDescException(
0528: "Deployment desc for file ejb-jar '"
0529: + currentFile.getFile() + "' not found");
0530: }
0531: // Read in its own deployment descriptor if not null
0532: if (deploymentDesc != null) {
0533: bd = deploymentDesc.getBeanDesc(ejbLink);
0534: }
0535: String url = currentFile.getFile();
0536: URLClassLoader earClassLoader = null;
0537: // get the loader for classes (ejb classloader).
0538: URLClassLoader ejbLoader = (URLClassLoader) urlEjbCLBindings
0539: .get(url);
0540: if (earCl != null) {
0541: earClassLoader = (URLClassLoader) earCl;
0542: //Add it
0543: urlEarCLBindings.put(url, earCl);
0544: } else {
0545: earClassLoader = (URLClassLoader) urlEarCLBindings
0546: .get(url);
0547: }
0548:
0549: //ejb standalone case
0550: if ((earClassLoader == null) && (bd == null)) {
0551: String err = "Ejb-link " + ejbLink
0552: + " not found inside the file "
0553: + currentFile.getFile()
0554: + ". The bean doesn't exists.";
0555: throw new DeploymentDescException(err);
0556: }
0557:
0558: // ear case, search in all ejbjars
0559: if (bd == null) {
0560: if (logger.isLoggable(BasicLevel.DEBUG)) {
0561: logger
0562: .log(
0563: BasicLevel.DEBUG,
0564: "The bean '"
0565: + ejbLink
0566: + "' was not found in the current ejbjar, searching on all the ejbjars.");
0567: }
0568: Vector v = (Vector) earCLEjbLinkJar.get(earClassLoader);
0569: DeploymentDesc lookupDD = null;
0570: String fileName = null;
0571: URL urlRead = null;
0572: String urlReadString = null;
0573: boolean found = false;
0574: BeanDesc bdtmp = null;
0575: for (Enumeration e = v.elements(); e.hasMoreElements();) {
0576: urlReadString = (String) e.nextElement();
0577: File f = new File(urlReadString);
0578: try {
0579: urlRead = f.toURL();
0580: } catch (Exception ue) {
0581: throw new DeploymentDescException(
0582: "Cannot make an url with the argument'"
0583: + urlReadString + "'.");
0584: }
0585: // Classloader is null ? try to get it
0586: if (ejbLoader == null) {
0587: ejbLoader = (URLClassLoader) urlEjbCLBindings
0588: .get(urlReadString);
0589: }
0590: // if it is still null, fails
0591: if (ejbLoader == null) {
0592: throw new DeploymentDescException(
0593: "Error while resolving ejb-link. The ejb classloader is not found for url '"
0594: + urlReadString + "'.");
0595: }
0596:
0597: // Add it
0598: urlEjbCLBindings.put(urlReadString, ejbLoader);
0599:
0600: fileName = urlRead.getFile();
0601: //do not analyse current file
0602: if (!fileName.equals(url)) {
0603: //Need to load deployment desc without any resolving link
0604: // Get the instance of the DeploymentDesc.
0605: if (f.isDirectory()) {
0606: lookupDD = getDeploymentDescriptor(fileName
0607: + EJB_JAR_FILE_NAME, BeanNaming
0608: .getJonasXmlName(fileName
0609: + EJB_JAR_FILE_NAME),
0610: ejbLoader, f.getAbsolutePath());
0611: } else if (fileName.toLowerCase().endsWith(
0612: ".xml")) {
0613: // This is an XML file name: Treat it for upward compatibility
0614: // f is the ejb-jar.xml file, first paretn is the META-INF directory, and second parent is the root directory of the module
0615: File parent = f.getParentFile()
0616: .getParentFile();
0617: lookupDD = getDeploymentDescriptor(
0618: fileName, BeanNaming
0619: .getJonasXmlName(fileName),
0620: ejbLoader, parent.getAbsolutePath());
0621: } else {
0622: // This is an ejb-jar
0623: // Check if there is an altenate DD for this URL (ear only)
0624: String altname = null;
0625: URL altDDUrl = (URL) urlAltDDBindings
0626: .get(url);
0627: if (altDDUrl != null) {
0628: altname = altDDUrl.getFile();
0629: }
0630: lookupDD = getDeploymentDescriptor(
0631: fileName, ejbLoader, altname);
0632: }
0633:
0634: if (lookupDD != null) {
0635: bdtmp = lookupDD.getBeanDesc(ejbLink);
0636: if (bdtmp != null) {
0637: if (logger.isLoggable(BasicLevel.DEBUG)) {
0638: logger.log(BasicLevel.DEBUG,
0639: "Found a BeanDesc in the Deployment Desc."
0640: + urlRead);
0641: }
0642: //ejblink was found ?
0643: if (found) {
0644: String err = "There are more than one bean with the name '"
0645: + ejbLink
0646: + "' which were found in all the ejbjars of this EAR.";
0647: throw new DeploymentDescException(
0648: err);
0649: } else {
0650: found = true;
0651: bd = bdtmp;
0652: }
0653: } else {
0654: if (logger.isLoggable(BasicLevel.DEBUG)) {
0655: logger.log(BasicLevel.DEBUG,
0656: "No BeanDesc found in the Deployment Desc."
0657: + urlRead);
0658: }
0659: }
0660: }
0661: }
0662: }
0663: if (!found) {
0664: String err = "No ejblink was found for '" + ejbLink
0665: + "' in all the ejbjars of this EAR.";
0666: throw new DeploymentDescException(err);
0667: }
0668: }
0669:
0670: if (logger.isLoggable(BasicLevel.DEBUG)) {
0671: logger.log(BasicLevel.DEBUG, "BeanDesc found = "
0672: + bd.getEjbName());
0673: }
0674: //Check if the type of the ejb-ref is correct.
0675: checkType(currentFile, ejbType, bd);
0676:
0677: if (bd == null) {
0678: String err = "Ejb-link " + ejbLink
0679: + " not found inside the file "
0680: + currentFile.getFile()
0681: + ". The bean doesn't exists.";
0682: throw new DeploymentDescException(err);
0683: }
0684:
0685: String jndiname;
0686: if (isEjbRef) {
0687: jndiname = bd.getJndiName();
0688: } else {
0689: jndiname = bd.getJndiLocalName();
0690: }
0691: return jndiname;
0692: }
0693:
0694: if (earCl != null) {
0695: String url = currentFile.getFile();
0696: //Add it
0697: urlEarCLBindings.put(url, earCl);
0698: }
0699:
0700: //Ejb-link not in the same ejb-jar file.
0701: StringTokenizer st = new StringTokenizer(ejbLink,
0702: LINK_SEPARATOR);
0703:
0704: // We must have only two elements after this step, one for the fileName
0705: // before the # and the name of the bean after the # char
0706: if (st.countTokens() != 2 || ejbLink.startsWith(LINK_SEPARATOR)
0707: || ejbLink.endsWith(LINK_SEPARATOR)) {
0708:
0709: String err = "Ejb link "
0710: + ejbLink
0711: + " has a bad format. Correct format : filename.jar#beanName.";
0712: throw new DeploymentDescException(err);
0713: }
0714:
0715: //Get the token
0716: ejbJarLink = st.nextToken();
0717: beanNameLink = st.nextToken();
0718:
0719: //Check if ejbJarLink is a jar or not
0720: if (!ejbJarLink.endsWith(".jar")) {
0721: String err = "Ejbjar filename "
0722: + ejbJarLink
0723: + " from the ejb-link "
0724: + ejbLink
0725: + " has a bad format. Correct format : filename.jar";
0726: throw new DeploymentDescException(err);
0727: }
0728:
0729: // Now construct the URL from the absolute path from the url ejbJar and
0730: // the relative path from ejbJarLink
0731: URL ejbJarLinkUrl = null;
0732: try {
0733: ejbJarLinkUrl = new File(new File(currentFile.getFile())
0734: .getParent()
0735: + File.separator + ejbJarLink).getCanonicalFile()
0736: .toURL();
0737: } catch (MalformedURLException mue) {
0738: String err = "Error when creating an url for the ejb jar filename. Error :"
0739: + mue.getMessage();
0740: throw new DeploymentDescException(err);
0741: } catch (IOException ioe) {
0742: String err = "Error when creating/accessing a file. Error :"
0743: + ioe.getMessage();
0744: throw new DeploymentDescException(err);
0745: }
0746:
0747: // We've got the url
0748: BeanDesc bd = null;
0749: // The ejb-link with .jar#beanName could reference the current jar file
0750: if (currentFile.getPath().equalsIgnoreCase(
0751: ejbJarLinkUrl.getPath())) {
0752: if (logger.isLoggable(BasicLevel.DEBUG)) {
0753: logger.log(BasicLevel.DEBUG,
0754: "ejblink jar#bean reference our current file");
0755: }
0756:
0757: // Read in its own deployment descriptor if not null
0758: if (deploymentDesc != null) {
0759: bd = deploymentDesc.getBeanDesc(beanNameLink);
0760: } else {
0761: if (logger.isLoggable(BasicLevel.DEBUG)) {
0762: logger
0763: .log(BasicLevel.DEBUG,
0764: "DD = null, cannot return bean in the current DD");
0765: }
0766: }
0767:
0768: } else {
0769: //Another file :
0770:
0771: // Now, We can ask the Deployment Descriptor of this url
0772: DeploymentDesc dd = getDeploymentDesc(currentFile,
0773: ejbJarLinkUrl);
0774:
0775: // JndiName resolve.
0776: bd = dd.getBeanDesc(beanNameLink);
0777: }
0778:
0779: if (bd == null) {
0780: String err = "Ejb-link " + ejbLink
0781: + " not found inside the file "
0782: + currentFile.getFile()
0783: + ". The bean doesn't exists";
0784: throw new DeploymentDescException(err);
0785: }
0786:
0787: //Check if the type of the ejb-ref is correct.
0788: checkType(currentFile, ejbType, bd);
0789:
0790: String jndiname;
0791: if (isEjbRef) {
0792: jndiname = bd.getJndiName();
0793: } else {
0794: jndiname = bd.getJndiLocalName();
0795: }
0796: return jndiname;
0797: }
0798:
0799: /**
0800: * Return the JNDI name from the messageDestinationLink string.
0801: * messageDestinationLink format : filename.jar#beanName in the same Ear File
0802: * beanName in the same ejb-jar file.
0803: * @param ejbJar the url of the jar being parsed. This is needed because
0804: * mdLink is relative. With the url and the mdLink, we can know where
0805: * the file is locate.
0806: * @param mdLink the mdLink tag of a message-destination-ref
0807: * @param mdType the type of the referenced mdb in the message-destination-ref tag.
0808: * @param mdUsage the usage of the referenced mdb in the message-destination-ref tag.
0809: * @param deploymentDesc the deployment descriptor of the parsed deploymentDesc.
0810: * @return the JNDI name if found, null otherwise
0811: * @throws DeploymentDescException when it failed
0812: */
0813: private String getMDJndiName(URL ejbJar, String mdLink,
0814: String mdType, String mdUsage, DeploymentDesc deploymentDesc)
0815: throws DeploymentDescException {
0816:
0817: if (logger.isLoggable(BasicLevel.DEBUG)) {
0818: logger.log(BasicLevel.DEBUG, "" + ejbJar + " " + mdLink
0819: + " " + mdType + " " + mdUsage);
0820: }
0821: // Extract from the mdb link
0822: // - the name of the file
0823: // - the name of the destination
0824: String ejbJarLink = null;
0825: DeploymentDesc dd = deploymentDesc;
0826:
0827: //Different jar ?
0828: if (mdLink.indexOf(LINK_SEPARATOR) != -1) {
0829: //Message-destination-link not in the same ejb-jar file.
0830: StringTokenizer st = new StringTokenizer(mdLink,
0831: LINK_SEPARATOR);
0832:
0833: // We must have only two elements after this step, one for the fileName
0834: // before the # and the name of the message-destination after the # char
0835: if (st.countTokens() != 2
0836: || mdLink.startsWith(LINK_SEPARATOR)
0837: || mdLink.endsWith(LINK_SEPARATOR)) {
0838:
0839: String err = "Message-destination-link "
0840: + mdLink
0841: + " has a bad format. Correct format : filename.jar#messageDestinationName.";
0842: throw new DeploymentDescException(err);
0843: }
0844:
0845: //Get the token
0846: ejbJarLink = st.nextToken();
0847:
0848: //Check if ejbJarLink is a jar or not
0849: if (!ejbJarLink.endsWith(".jar")) {
0850: String err = "Ejbjar filename "
0851: + ejbJarLink
0852: + " from the message-destination-link "
0853: + mdLink
0854: + " has a bad format. Correct format : filename.jar";
0855: throw new DeploymentDescException(err);
0856: }
0857:
0858: // Now construct the URL from the absolute path from the url ejbJar and
0859: // the relative path from ejbJarLink
0860: URL ejbJarLinkUrl = null;
0861: try {
0862: ejbJarLinkUrl = new File(new File(ejbJar.getFile())
0863: .getParent()
0864: + File.separator + ejbJarLink)
0865: .getCanonicalFile().toURL();
0866: } catch (MalformedURLException mue) {
0867: String err = "Error when creating an url for the ejb jar filename. Error :"
0868: + mue.getMessage();
0869: throw new DeploymentDescException(err);
0870: } catch (IOException ioe) {
0871: String err = "Error when creating/accessing a file. Error :"
0872: + ioe.getMessage();
0873: throw new DeploymentDescException(err);
0874: }
0875:
0876: // Check if the jar exist.
0877: if (!new File(ejbJarLinkUrl.getFile()).exists()) {
0878: String err = "Cannot get the deployment descriptor for '"
0879: + ejbJarLinkUrl.getFile()
0880: + "'. The file doesn't exist.";
0881: throw new DeploymentDescException(err);
0882: }
0883:
0884: // We've got the url
0885: // Now, We can ask the Deployment Descriptor of this url
0886: dd = getDeploymentDesc(ejbJar, ejbJarLinkUrl);
0887: }
0888:
0889: //Link to a destination inside the same ejb-jar file.
0890: if (dd == null) {
0891: throw new DeploymentDescException(
0892: "Deployment desc for file ejb-jar '"
0893: + ejbJar.getFile() + "' not found");
0894: }
0895:
0896: boolean foundMd = dd.getMessageDestination(mdLink);
0897: if (!foundMd) {
0898: String err = "No message-destination was found for '"
0899: + mdLink + "' in the ejbjar specified.";
0900: throw new DeploymentDescException(err);
0901: }
0902:
0903: JonasMessageDestination md = dd
0904: .getJonasMessageDestination(mdLink);
0905:
0906: if (md == null) {
0907: String err = "No jonas-message-destination was found for '"
0908: + mdLink + "' in the ejbjar specified.";
0909: throw new DeploymentDescException(err);
0910: }
0911:
0912: if (logger.isLoggable(BasicLevel.DEBUG)) {
0913: logger.log(BasicLevel.DEBUG, "Message-destination found = "
0914: + md.getJndiName());
0915: }
0916:
0917: //Check if the type & usage of the message-destination-ref is correct.
0918: //checkTypeUsage(ejbJar, mdType, mdUsage, mdd);
0919:
0920: return md.getJndiName();
0921:
0922: }
0923:
0924: /**
0925: * Check if the link is available in the case of an ear application.
0926: * @param earClassLoader the ear classloader of the ear application.
0927: * @param url the url to check.
0928: * @throws DeploymentDescException if the ejb-link isn't available.
0929: */
0930: private void checkEjbLinkAvailable(ClassLoader earClassLoader,
0931: URL url) throws DeploymentDescException {
0932:
0933: Vector v = (Vector) earCLEjbLinkJar.get(earClassLoader);
0934:
0935: if (v != null) {
0936: if (!v.contains(url.getFile())) {
0937: String err = "The ejb-link or message-destination-link of '"
0938: + url.getFile()
0939: + "' must be done on an ejb-jar defined in the ear application (application.xml <module><ejb>###</ejb></module>)";
0940: throw new DeploymentDescException(err);
0941: }
0942: } else {
0943: String err = "setAvailableEjbLinkJar was badly called.";
0944: throw new DeploymentDescException(err);
0945: }
0946: }
0947:
0948: /**
0949: * Set for the given ear identified by its earClassLoader the list of the
0950: * ejb-jar that can be in the ejb-link and the optional Desployment Desc.
0951: * @param earClassLoader the classloader of the ear application.
0952: * @param urls the list of the URLs of the ear application that can be in
0953: * the ejb-link.
0954: * @param altDDs the list of the URLs of the alternate DDs to use if specified.
0955: */
0956: public void setAvailableEjbJarsAndAltDDs(
0957: ClassLoader earClassLoader, URL[] urls, URL[] altDDs) {
0958: Vector v = new Vector();
0959: for (int i = 0; i < urls.length; i++) {
0960: v.addElement(urls[i].getFile());
0961: if (altDDs[i] != null) {
0962: urlAltDDBindings.put(urls[i].getFile(), altDDs[i]);
0963: }
0964: }
0965: earCLEjbLinkJar.put(earClassLoader, v);
0966: }
0967:
0968: /**
0969: * Make a cleanup of the cache of deployment descriptor. This method must
0970: * be invoked after the ear deployment by the EAR service.
0971: * @param earClassLoader the URLClassLoader of the ear application to
0972: * remove from the cache.
0973: */
0974: public void removeCache(ClassLoader earClassLoader) {
0975: Vector v = (Vector) earCLEjbLinkJar.remove(earClassLoader);
0976: if (v != null) {
0977: for (int i = 0; i < v.size(); i++) {
0978: String url = (String) v.elementAt(i);
0979: urlJarBindings.remove(url);
0980: urlEarCLBindings.remove(url);
0981: urlEjbCLBindings.remove(url);
0982: urlAltDDBindings.remove(url);
0983: }
0984: }
0985:
0986: if (earCLEjbLinkJar.size() != 0 || urlJarBindings.size() != 0
0987: || urlEarCLBindings.size() != 0
0988: || urlAltDDBindings.size() != 0
0989: || urlEjbCLBindings.size() != 0) {
0990:
0991: String buffer = earCLEjbLinkJar.size() + " ";
0992: buffer += urlJarBindings.size() + " ";
0993: buffer += urlEarCLBindings.size() + " ";
0994: buffer += urlEjbCLBindings.size() + " ";
0995: buffer += urlAltDDBindings.size();
0996:
0997: if (logger.isLoggable(BasicLevel.DEBUG)) {
0998: logger.log(BasicLevel.DEBUG, buffer
0999: + " there are some elements in cache");
1000: }
1001: }
1002: }
1003:
1004: /**
1005: * Get the size of the cache (number of entries in the cache).
1006: * Used only for debugging.
1007: * @return the size of the cache (number of entries in the cache).
1008: */
1009: public int getCacheSize() {
1010: return earCLEjbLinkJar.size() + urlJarBindings.size()
1011: + urlEarCLBindings.size() + urlEjbCLBindings.size()
1012: + urlAltDDBindings.size();
1013: }
1014:
1015: /**
1016: * Return a string representation of the cache. (Used only for debugging).
1017: * @return a string representation of the cache.
1018: */
1019: public String toString() {
1020: return earCLEjbLinkJar.size() + " " + urlJarBindings.size()
1021: + " " + urlEarCLBindings.size() + " "
1022: + urlEjbCLBindings.size() + " "
1023: + urlAltDDBindings.size();
1024: }
1025:
1026: /**
1027: * Factory method using deployment descriptor and Jonas deployment descriptor
1028: * file names.
1029: * used by GEnIC or GenIDL
1030: * @param ejbJarXmlFileName name of the standard DD
1031: * @param jonasEjbJarXmlFileName name of the specific DD
1032: * @param jarFileName name of the jar file
1033: * @return instance of the corresponding DeploymentDesc
1034: * @exception DeploymentDescException when DeploymentDesc cannot be created with
1035: * given files.
1036: */
1037: public static DeploymentDesc getDeploymentDesc(
1038: String ejbJarXmlFileName, String jonasEjbJarXmlFileName,
1039: String jarFileName) throws DeploymentDescException {
1040: // instantiate deployment descriptor
1041: ClassLoader cl = DeploymentDesc.class.getClassLoader();
1042: if (cl == null) {
1043: cl = Thread.currentThread().getContextClassLoader();
1044: }
1045: return getDeploymentDescriptor(ejbJarXmlFileName,
1046: jonasEjbJarXmlFileName, cl, jarFileName);
1047: }
1048:
1049: /**
1050: * Factory method using deployment descriptor and Jonas deployment descriptor
1051: * file names. (input is 2 .xml descriptors)
1052: * @param ejbJarXmlFileName Name of the xml for the EJBJAR
1053: * @param jonasEjbJarXmlFileName Name of the xml for JOnAS ejbjar
1054: * @param cl classloader to use
1055: * @param moduleDirName name of file
1056: * @return instance of the corresponding DeploymentDesc
1057: * @exception DeploymentDescException when DeploymentDesc cannot be created with
1058: * given files.
1059: */
1060: private static DeploymentDesc getDeploymentDescriptor(
1061: String ejbJarXmlFileName, String jonasEjbJarXmlFileName,
1062: ClassLoader cl, String moduleDirName)
1063: throws DeploymentDescException {
1064:
1065: InputStream is;
1066:
1067: // load deployment descriptor data
1068: try {
1069: is = new FileInputStream(ejbJarXmlFileName);
1070: // store file content in a String
1071: xmlContent = xmlContent(is);
1072: // reposition to the begining of the stream
1073: is = new FileInputStream(ejbJarXmlFileName);
1074: } catch (FileNotFoundException e) {
1075: throw new DeploymentDescException(ejbJarXmlFileName
1076: + " file not found");
1077: } catch (IOException ioe) {
1078: throw new DeploymentDescException(
1079: "Cannot read the content of the xml file "
1080: + ejbJarXmlFileName);
1081: }
1082: EjbJar ejbJar = loadEjbJar(new InputStreamReader(is),
1083: ejbJarXmlFileName);
1084: String dtdversion = ejbJar.getVersion();
1085: try {
1086: is.close();
1087: } catch (IOException e) {
1088: logger.log(BasicLevel.WARN, "Can't close '"
1089: + ejbJarXmlFileName + "'");
1090: }
1091:
1092: // load jonas deployment descriptor data
1093: try {
1094: is = new FileInputStream(jonasEjbJarXmlFileName);
1095: // store file content in a String
1096: jonasXmlContent = xmlContent(is);
1097: // reposition to the begining of the stream
1098: is = new FileInputStream(jonasEjbJarXmlFileName);
1099: } catch (FileNotFoundException e) {
1100: throw new DeploymentDescException(jonasEjbJarXmlFileName
1101: + " file not found");
1102: } catch (IOException ioe) {
1103: throw new DeploymentDescException(
1104: "Cannot read the content of the xml file "
1105: + ejbJarXmlFileName);
1106: }
1107:
1108: JonasEjbJar jonasEjbJar = loadJonasEjbJar(
1109: new InputStreamReader(is), jonasEjbJarXmlFileName);
1110: try {
1111: is.close();
1112: } catch (IOException e) {
1113: logger.log(BasicLevel.WARN, "Can't close '"
1114: + jonasEjbJarXmlFileName + "'");
1115: }
1116:
1117: // instantiate deployment descriptor
1118: DeploymentDesc descEjb = null;
1119: if (dtdversion.equals("1.1")) {
1120: descEjb = new DeploymentDescEjb1_1(cl, ejbJar, jonasEjbJar,
1121: logger, moduleDirName);
1122: } else {
1123: descEjb = new DeploymentDescEjb2(cl, ejbJar, jonasEjbJar,
1124: logger, moduleDirName);
1125: }
1126: descEjb.setXmlContent(xmlContent);
1127: descEjb.setJOnASXmlContent(jonasXmlContent);
1128: return descEjb;
1129: }
1130:
1131: /**
1132: * Factory method using the ejb-jar file name. (input is a .jar file)
1133: * Called either from GenIC or from createContainer.
1134: * @param ejbJarFileName name of the ejbjar
1135: * @param cl classloader to use
1136: * @param altWebXmlFilename null if not ear
1137: * @return instance of the corresponding DeploymentDesc
1138: * @exception DeploymentDescException when DeploymentDesc cannot be created with
1139: * given ejb-jar file.
1140: */
1141: private static DeploymentDesc getDeploymentDescriptor(
1142: String ejbJarFileName, ClassLoader cl,
1143: String altWebXmlFilename) throws DeploymentDescException {
1144:
1145: ZipFile zf = null;
1146: InputStream isDd = null;
1147: InputStream isJdd = null;
1148: EjbJar ejbJar;
1149: JonasEjbJar jonasEjbJar;
1150:
1151: // Check if the Alt deploymentDesc file exists. (optional value)
1152: if ((altWebXmlFilename != null)
1153: && (!new File(altWebXmlFilename).exists())) {
1154: String err = "The file for the altdd tag for the EAR case '"
1155: + altWebXmlFilename + "' was not found.";
1156: throw new DeploymentDescException(err);
1157: }
1158:
1159: // Get the XML DD files of the ejb-jar as InputStream
1160: try {
1161: zf = new ZipFile(ejbJarFileName);
1162:
1163: if (altWebXmlFilename == null) {
1164: // No alt-dd case ( standard)
1165: ZipEntry ejbEntry = zf.getEntry(EJB_JAR_FILE_NAME);
1166: if (ejbEntry == null) {
1167: throw new DeploymentDescException("The entry '"
1168: + EJB_JAR_FILE_NAME
1169: + "' was not found in the file '"
1170: + ejbJarFileName + "'.");
1171: }
1172: isDd = zf.getInputStream(ejbEntry);
1173: xmlContent = xmlContent(isDd);
1174: isDd = zf
1175: .getInputStream(zf.getEntry(EJB_JAR_FILE_NAME));
1176: } else {
1177: // AltDD (Ear and optional)
1178: isDd = new FileInputStream(altWebXmlFilename);
1179: xmlContent = xmlContent(isDd);
1180: isDd = new FileInputStream(altWebXmlFilename);
1181: }
1182: ZipEntry jEjbEntry = zf.getEntry(JONAS_EJB_JAR_FILE_NAME);
1183: if (jEjbEntry != null) {
1184: isJdd = zf.getInputStream(jEjbEntry);
1185: jonasXmlContent = xmlContent(isJdd);
1186: isJdd = zf.getInputStream(zf
1187: .getEntry(JONAS_EJB_JAR_FILE_NAME));
1188: } else {
1189: logger.log(BasicLevel.WARN, "No entry '"
1190: + JONAS_EJB_JAR_FILE_NAME
1191: + "' was found in the file '" + ejbJarFileName
1192: + "'.");
1193: }
1194: } catch (Exception e) {
1195: if (zf != null) {
1196: try {
1197: zf.close();
1198: } catch (IOException i) {
1199: logger.log(BasicLevel.WARN, "Can't close '"
1200: + ejbJarFileName + "'");
1201: }
1202: }
1203: logger.log(BasicLevel.ERROR,
1204: "Cannot read the XML deployment descriptors for "
1205: + ejbJarFileName + ":", e);
1206: throw new DeploymentDescException(
1207: "Cannot read the XML deployment descriptors for "
1208: + ejbJarFileName + ":" + e);
1209: }
1210:
1211: // load standard deployment descriptor data
1212: ejbJar = loadEjbJar(new InputStreamReader(isDd),
1213: EJB_JAR_FILE_NAME);
1214: String dtdversion = ejbJar.getVersion();
1215: try {
1216: isDd.close();
1217: } catch (IOException e) {
1218: logger.log(BasicLevel.WARN,
1219: "Can't close META-INF/ejb-jar.xml in '"
1220: + ejbJarFileName + "'");
1221: }
1222:
1223: // load jonas deployment descriptor data
1224: if (isJdd != null) {
1225: jonasEjbJar = loadJonasEjbJar(new InputStreamReader(isJdd),
1226: JONAS_EJB_JAR_FILE_NAME);
1227: try {
1228: isJdd.close();
1229: } catch (IOException e) {
1230: logger.log(BasicLevel.WARN,
1231: "Can't close META-INF/jonas-ejb-jar.xml in '"
1232: + ejbJarFileName + "'");
1233: }
1234:
1235: } else {
1236: jonasEjbJar = new JonasEjbJar();
1237: }
1238:
1239: // Close the ZipFile
1240: if (zf != null) {
1241: try {
1242: zf.close();
1243: } catch (IOException e) {
1244: logger.log(BasicLevel.WARN, "Can't close '"
1245: + ejbJarFileName + "'");
1246: }
1247: }
1248:
1249: // instantiate deployment descriptor
1250: DeploymentDesc descEjb = null;
1251: if (dtdversion.equals("1.1")) {
1252: descEjb = new DeploymentDescEjb1_1(cl, ejbJar, jonasEjbJar,
1253: logger, ejbJarFileName);
1254: } else {
1255: descEjb = new DeploymentDescEjb2(cl, ejbJar, jonasEjbJar,
1256: logger, ejbJarFileName);
1257: }
1258: descEjb.setXmlContent(xmlContent);
1259: descEjb.setJOnASXmlContent(jonasXmlContent);
1260: return descEjb;
1261: }
1262:
1263: /**
1264: * Load the ejb_jar.xml file.
1265: * @param reader the reader of the XML file.
1266: * @param name the name of the file (ejb-jar.xml).
1267: * @return a structure containing the result of the ejb-jar.xml parsing.
1268: * @throws DeploymentDescException if the deployment descriptor
1269: * is corrupted.
1270: */
1271: public static EjbJar loadEjbJar(Reader reader, String name)
1272: throws DeploymentDescException {
1273: EjbJar ejbjar = new EjbJar();
1274:
1275: // Create if null
1276: if (ejbjarDigester == null) {
1277: // Create and initialize the digester
1278: ejbjarDigester = new JDigester(ejbjarRuleSet,
1279: parsingWithValidation, true, new EjbjarDTDs(),
1280: new EjbjarSchemas());
1281: }
1282: try {
1283: ejbjarDigester.parse(reader, name, ejbjar);
1284: } catch (DeploymentDescException e) {
1285: throw e;
1286: } finally {
1287: ejbjarDigester.push(null);
1288: }
1289: return ejbjar;
1290: }
1291:
1292: /**
1293: * Load the EjbJar file
1294: * @param reader reader containing the stream
1295: * @param name name of the file
1296: * @return JOnAS DD object
1297: * @throws DeploymentDescException if loading fails
1298: */
1299: public static JonasEjbJar loadJonasEjbJar(Reader reader, String name)
1300: throws DeploymentDescException {
1301: JonasEjbJar jonasEjbjar = new JonasEjbJar();
1302: // Create if null
1303: if (jonasEjbjarDigester == null) {
1304: // Create and initialize the digester
1305: jonasEjbjarDigester = new JDigester(jonasEjbjarRuleSet,
1306: parsingWithValidation, true, new JonasEjbjarDTDs(),
1307: new JonasEjbjarSchemas());
1308: }
1309: try {
1310: jonasEjbjarDigester.parse(reader, name, jonasEjbjar);
1311: } catch (DeploymentDescException e) {
1312: throw e;
1313: } finally {
1314: jonasEjbjarDigester.push(null);
1315: }
1316: return jonasEjbjar;
1317: }
1318:
1319: /**
1320: * Controls whether the parser is reporting all validity errors.
1321: * @return if true, all external entities will be read.
1322: */
1323: public static boolean getParsingWithValidation() {
1324: return parsingWithValidation;
1325: }
1326:
1327: /**
1328: * Controls whether the parser is reporting all validity errors.
1329: * @param validation if true, all external entities will be read.
1330: */
1331: public static void setParsingWithValidation(boolean validation) {
1332: EjbDeploymentDescManager.parsingWithValidation = validation;
1333: }
1334:
1335: /**
1336: * Return the content of the web.xml file
1337: * @return the content of the web.xml file
1338: */
1339: public static String getXmlContent() {
1340: return xmlContent;
1341: }
1342:
1343: /**
1344: * Return the content of the jonas-web.xml file
1345: * @return the content of the jonas-web.xml file
1346: */
1347: public static String getJOnASXmlContent() {
1348: return jonasXmlContent;
1349: }
1350:
1351: /**
1352: * Check if the type of the ejb-ref is correct.
1353: * @param ejbJar the URL of the ejb-jar being parsed.
1354: * @param ejbType the type of the ejb-ref (ejb-ref-type).
1355: * @param bd the descriptor of the referenced bean.
1356: * @throws DeploymentDescException if the type is incorrect.
1357: */
1358: protected void checkType(URL ejbJar, String ejbType,
1359: JndiEnvRefsGroup bd) throws DeploymentDescException {
1360:
1361: if (bd instanceof SessionDesc) {
1362: if (!ejbType.equalsIgnoreCase("Session")) {
1363: String err = "Deployment desc '"
1364: + ejbJar.getFile()
1365: + "' has an incompatible ejb-ref-type: Required Session but found "
1366: + ejbType;
1367: throw new DeploymentDescException(err);
1368: }
1369: } else if (bd instanceof EntityDesc) {
1370: if (!ejbType.equalsIgnoreCase("Entity")) {
1371: String err = "Deployment desc '"
1372: + ejbJar.getFile()
1373: + "' has an incompatible ejb-ref-type: Required Entity but found "
1374: + ejbType;
1375: throw new DeploymentDescException(err);
1376: }
1377: } else {
1378: String err = "Deployment desc '" + ejbJar.getFile()
1379: + "' has a bad ejb-ref-type.";
1380: throw new DeploymentDescException(err);
1381: }
1382: }
1383:
1384: /**
1385: * Check if the type & usage of the message-destination-ref is correct.
1386: * @param url the URL of the file being parsed.
1387: * @param mdType the type of the message-destination-ref
1388: * (message-destination-type).
1389: * @param mdUsage the usage of the message-destination-ref
1390: * (message-destination-usage).
1391: * @param bd the descriptor of the referenced bean.
1392: * @throws DeploymentDescException if the type is incorrect.
1393: */
1394: protected void checkTypeUsage(URL url, String mdType,
1395: String mdUsage, BeanDesc bd) throws DeploymentDescException {
1396:
1397: if (bd instanceof MessageDrivenDesc) {
1398: MessageDrivenDesc mdd = (MessageDrivenDesc) bd;
1399: if (mdd.getDestinationType().equals("javax.jms.Topic")) {
1400: if (!mdType.equalsIgnoreCase("javax.jms.Topic")) {
1401: String err = "Deployment desc '"
1402: + url.getFile()
1403: + "' has an incompatible message-destination-type: Required javax.jms.Topic but found "
1404: + mdType;
1405: throw new DeploymentDescException(err);
1406: }
1407: } else if (mdd.getDestinationType().equals(
1408: "javax.jms.Queue")) {
1409: if (!mdType.equalsIgnoreCase("javax.jms.Queue")) {
1410: String err = "Deployment desc '"
1411: + url.getFile()
1412: + "' has an incompatible message-destination-type: Required javax.jms.Queue but found "
1413: + mdType;
1414: throw new DeploymentDescException(err);
1415: }
1416: }
1417: } else {
1418: String err = "Deployment desc '" + url.getFile()
1419: + "' has a bad message-destination-ref-type.";
1420: throw new DeploymentDescException(err);
1421: }
1422: }
1423:
1424: /**
1425: * Add a mapping between url and classloader
1426: * @param ejbClassloader EjbClassloader on which associate URLs
1427: * @param urls array of urls associated to the classloader
1428: */
1429: public void addClassLoaderUrlMapping(ClassLoader ejbClassloader,
1430: URL[] urls) {
1431: for (int u = 0; u < urls.length; u++) {
1432: urlEjbCLBindings.put(urls[u].getPath(), ejbClassloader);
1433: }
1434: }
1435: }
|