0001: /**
0002: * JOnAS: Java(TM) Open Application Server
0003: * Copyright (C) 1999-2004 Bull S.A.
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: * Initial Developer : Delplanque Xavier & Sauthier Guillaume
0022: * --------------------------------------------------------------------------
0023: * $Id: WSDeploymentDescManager.java 7467 2005-10-04 12:53:14Z sauthieg $
0024: * --------------------------------------------------------------------------
0025: */package org.objectweb.jonas_ws.deployment.lib;
0026:
0027: import java.io.File;
0028: import java.io.IOException;
0029: import java.io.InputStream;
0030: import java.io.InputStreamReader;
0031: import java.io.Reader;
0032: import java.net.MalformedURLException;
0033: import java.net.URL;
0034: import java.net.URLClassLoader;
0035: import java.net.URLConnection;
0036: import java.util.Enumeration;
0037: import java.util.HashMap;
0038: import java.util.Hashtable;
0039: import java.util.Iterator;
0040: import java.util.List;
0041: import java.util.Map;
0042: import java.util.StringTokenizer;
0043: import java.util.Vector;
0044:
0045: import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
0046: import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
0047: import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc;
0048: import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
0049:
0050: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
0051: import org.objectweb.jonas_lib.deployment.digester.JDigester;
0052: import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
0053:
0054: import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc;
0055: import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDescException;
0056: import org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager;
0057:
0058: import org.objectweb.jonas_ws.deployment.api.JonasWsSchemas;
0059: import org.objectweb.jonas_ws.deployment.api.PortComponentDesc;
0060: import org.objectweb.jonas_ws.deployment.api.ServiceDesc;
0061: import org.objectweb.jonas_ws.deployment.api.WSDeploymentDesc;
0062: import org.objectweb.jonas_ws.deployment.api.WSDeploymentDescException;
0063: import org.objectweb.jonas_ws.deployment.api.WsSchemas;
0064: import org.objectweb.jonas_ws.deployment.rules.JonasWebservicesRuleSet;
0065: import org.objectweb.jonas_ws.deployment.rules.WebservicesRuleSet;
0066: import org.objectweb.jonas_ws.deployment.xml.JonasWebservices;
0067: import org.objectweb.jonas_ws.deployment.xml.Webservices;
0068:
0069: import org.objectweb.jonas.common.Log;
0070:
0071: import org.objectweb.util.monolog.api.BasicLevel;
0072: import org.objectweb.util.monolog.api.Logger;
0073:
0074: /**
0075: * This class provide a way for managing the WSDeploymentDesc. Note that there
0076: * is 1 instance of the WSDeploymentDescManager on each JOnAS server.
0077: * @author Guillaume Sauthier
0078: * @author Xavier Delplanque
0079: * @author Helene Joanin
0080: */
0081: public class WSDeploymentDescManager extends AbsDeploymentDescManager {
0082:
0083: /**
0084: * ejb-jar.xml filename
0085: */
0086: public static final String WS_EJBJAR_FILE_NAME = "META-INF/webservices.xml";
0087:
0088: /**
0089: * jonas-ejb-jar.xml filename
0090: */
0091: public static final String JONAS_WS_EJBJAR_FILE_NAME = "META-INF/jonas-webservices.xml";
0092:
0093: /**
0094: * ejb-jar.xml filename
0095: */
0096: public static final String WS_WEBAPP_FILE_NAME = "WEB-INF/webservices.xml";
0097:
0098: /**
0099: * jonas-ejb-jar.xml filename
0100: */
0101: public static final String JONAS_WS_WEBAPP_FILE_NAME = "WEB-INF/jonas-webservices.xml";
0102:
0103: /**
0104: * Digester used to parse webservices.xml
0105: */
0106: private static JDigester wsDigester = null;
0107:
0108: /**
0109: * Digester used to parse jonas-webservices.xml
0110: */
0111: private static JDigester jwsDigester = null;
0112:
0113: /**
0114: * Rules to parse the webservices.xml
0115: */
0116: private static WebservicesRuleSet wsRuleSet = new WebservicesRuleSet();
0117:
0118: /**
0119: * Rules to parse the jonas-webservices.xml
0120: */
0121: private static JonasWebservicesRuleSet jwsRuleSet = new JonasWebservicesRuleSet();
0122:
0123: /**
0124: * Flag for parser validation
0125: */
0126: private static boolean parsingWithValidation = true;
0127:
0128: /**
0129: * The unique instance of the WSDeploymentDescManager
0130: */
0131: private static WSDeploymentDescManager unique = null;
0132:
0133: /**
0134: * is the manager instanciated ?
0135: */
0136: private static boolean isInstanciated = false;
0137:
0138: /**
0139: * Logger for the deployment desc manager.
0140: */
0141: private static Logger logger = Log.getLogger(Log.JONAS_WS_PREFIX);
0142:
0143: /**
0144: * Associates module or webservices dd URL and a WSDeploymentDesc
0145: */
0146: private HashMap urlWsddBindings;
0147:
0148: /**
0149: * Associates a given ClassLaoder (ear/ejb/web) to a list of URL containing
0150: * (or not) WSDD
0151: */
0152: private Map classLoader2URLs;
0153:
0154: /**
0155: * EJB Descriptor Manager
0156: */
0157: private EjbDeploymentDescManager ejbManager = null;
0158:
0159: /**
0160: * Web Descriptor Manager
0161: */
0162: private WebDeploymentDescManager webManager = null;
0163:
0164: /**
0165: * Constructor : creates a WSDeploymentDescManager object. Used only when
0166: * loading files in the running JOnAS instance.
0167: */
0168: private WSDeploymentDescManager() {
0169: urlWsddBindings = new HashMap();
0170: classLoader2URLs = new Hashtable();
0171:
0172: ejbManager = EjbDeploymentDescManager.getInstance();
0173: webManager = WebDeploymentDescManager.getInstance();
0174: }
0175:
0176: /**
0177: * Get the unique instance of the WSDeploymentDescManager.
0178: * @return the instance of the WSDeploymentDescManager.
0179: */
0180: public static WSDeploymentDescManager getInstance() {
0181: if (!isInstanciated) {
0182: isInstanciated = true;
0183: unique = new WSDeploymentDescManager();
0184:
0185: }
0186: return unique;
0187: }
0188:
0189: /**
0190: * Get the specified WebService deployment descriptor. Used by WsGen.
0191: * @param file module (ejbjar or war). It is required that file is not a
0192: * directory.
0193: * @param jarCL the classloader where classes are stored.
0194: * @return the module webservices deployment descriptor if it exists, null
0195: * else.
0196: * @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
0197: * with the given files.
0198: */
0199: public static WSDeploymentDesc getDeploymentDesc(String file,
0200: ClassLoader jarCL) throws WSDeploymentDescException {
0201:
0202: URL fileUrl = null;
0203: try {
0204: fileUrl = new File(file).toURL();
0205: } catch (MalformedURLException mue) {
0206: throw new WSDeploymentDescException(mue);
0207: }
0208:
0209: WSDeploymentDesc wsdd = loadDeploymentDesc(fileUrl, jarCL);
0210:
0211: // webservices.xml not present in file, no resolution needed
0212: if (wsdd == null) {
0213: return null;
0214:
0215: }
0216:
0217: // Resolve ejb-link and servlet-link elements
0218: List sdl = wsdd.getServiceDescs();
0219:
0220: for (int i = 0; i < sdl.size(); i++) {
0221: List pcdl = ((ServiceDesc) sdl.get(i)).getPortComponents();
0222:
0223: for (int j = 0; j < pcdl.size(); j++) {
0224: // Resolve the ejb-link and servlet-link of each port components
0225: PortComponentDesc pcd = (PortComponentDesc) pcdl.get(j);
0226: String sibLink = pcd.getSibLink();
0227:
0228: // a link is defined, we resolve it
0229: if (pcd.hasBeanImpl()) {
0230: SessionStatelessDesc desc = getBeanDesc(file,
0231: sibLink, jarCL);
0232: pcd.setDesc(desc);
0233:
0234: } else if (pcd.hasJaxRpcImpl()) {
0235: WebContainerDeploymentDesc desc = getWebDesc(file,
0236: sibLink, jarCL);
0237: pcd.setDesc(desc);
0238:
0239: }
0240: }
0241: }
0242:
0243: return wsdd;
0244: }
0245:
0246: /**
0247: * Get the specified ws deployment descriptor and put it in the cache if it
0248: * is not in.
0249: * @param url module (ejbjar or war). It can be a directory or a jar file.
0250: * @param jarCL classloader used to load bean classes.
0251: * @param earCL the parent classloader (the ear classloader). Null when not
0252: * in the case of an ear application.
0253: * @return the module webservices deployment descriptor if it exists, null
0254: * else.
0255: * @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
0256: * with the given files.
0257: */
0258: public WSDeploymentDesc getDeploymentDesc(URL url,
0259: ClassLoader jarCL, ClassLoader earCL)
0260: throws WSDeploymentDescException {
0261: return getDeploymentDesc(url, null, jarCL, earCL);
0262: }
0263:
0264: /**
0265: * Get the specified ws deployment descriptor and put it in the cache if it
0266: * is not in.
0267: * @param url module (ejbjar or war). It can be a directory or a jar file.
0268: * @param unpackedURL Unpacked URL of the module archive
0269: * @param jarCL classloader used to load bean classes.
0270: * @param earCL the parent classloader (the ear classloader). Null when not
0271: * in the case of an ear application.
0272: * @return the module webservices deployment descriptor if it exists, null
0273: * else.
0274: * @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
0275: * with the given files.
0276: */
0277: public WSDeploymentDesc getDeploymentDesc(URL url, URL unpackedURL,
0278: ClassLoader jarCL, ClassLoader earCL)
0279: throws WSDeploymentDescException {
0280:
0281: WSDeploymentDesc wsdd = null;
0282: File moduleFile = new File(url.getFile());
0283:
0284: if (moduleFile.exists()) {
0285: // if the module has yet been loaded
0286: if (!urlWsddBindings.containsKey(url)) {
0287: wsdd = getDeploymentDescriptor(url, unpackedURL, jarCL,
0288: earCL);
0289: } else { // module already loaded
0290: // Can be null if no webservices.xml has been found in specified
0291: // module
0292: wsdd = (WSDeploymentDesc) urlWsddBindings.get(url);
0293: }
0294: } else {
0295: throw new WSDeploymentDescException("'"
0296: + moduleFile.getName() + "' doesn't exists");
0297: }
0298:
0299: // Store binding
0300: ClassLoader keyCL;
0301: if (earCL != null) {
0302: keyCL = earCL;
0303: } else {
0304: keyCL = jarCL;
0305: }
0306: List urls = (List) classLoader2URLs.get(keyCL);
0307: if (urls == null) {
0308: urls = new Vector();
0309: classLoader2URLs.put(keyCL, urls);
0310: }
0311: urls.add(url);
0312:
0313: return wsdd;
0314: }
0315:
0316: /**
0317: * return the specified webservices deployment descriptor and put it in
0318: * cache.
0319: * @param url an existing module (ejbjar or war). It can be a directory or a
0320: * jar file
0321: * @param unpackedURL Unpacked URL of the module archive
0322: * @param jarCL classloader used to load war or ejbjar classes.
0323: * @param earCL the parent classloader (the ear classloader). Null when not
0324: * in the case of an ear application.
0325: * @return the module webservices deployment descriptor if it exists, null
0326: * else.
0327: * @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
0328: * with the given files.
0329: */
0330: private WSDeploymentDesc getDeploymentDescriptor(URL url,
0331: URL unpackedURL, ClassLoader jarCL, ClassLoader earCL)
0332: throws WSDeploymentDescException {
0333:
0334: URL baseURL = url;
0335: if (unpackedURL != null) {
0336: baseURL = unpackedURL;
0337: }
0338: WSDeploymentDesc wsdd = loadDeploymentDesc(baseURL, jarCL);
0339:
0340: // add in cache the deployment descriptor and return it
0341: urlWsddBindings.put(url, wsdd);
0342:
0343: // No WSDeploymentDesc, return null
0344: if (wsdd == null) {
0345: return null;
0346: }
0347:
0348: // Resolve ejb-link and servlet-link elements
0349: List sdl = wsdd.getServiceDescs();
0350:
0351: for (int i = 0; i < sdl.size(); i++) {
0352: List pcdl = ((ServiceDesc) sdl.get(i)).getPortComponents();
0353:
0354: for (int j = 0; j < pcdl.size(); j++) {
0355: // Resolve the ejb-link and servlet-link of each port components
0356: PortComponentDesc pcd = (PortComponentDesc) pcdl.get(j);
0357: String sibLink = pcd.getSibLink();
0358:
0359: // a link is defined, we resolve it
0360: if (pcd.hasBeanImpl()) {
0361: SessionStatelessDesc desc = getBeanDesc(url
0362: .getFile(), sibLink, jarCL, earCL);
0363: pcd.setDesc(desc);
0364:
0365: } else if (pcd.hasJaxRpcImpl()) {
0366: WebContainerDeploymentDesc desc = getWebDesc(url
0367: .getFile(), sibLink, jarCL, earCL);
0368: pcd.setDesc(desc);
0369:
0370: }
0371: }
0372: }
0373:
0374: return wsdd;
0375: }
0376:
0377: /**
0378: * Load webservices.xml in the WSDeploymentDesc structure (null if
0379: * webservices.xml not found). Can take as parameter a directory (like an
0380: * unpacked jar root directory), a XML file name (path to
0381: * (META-INF|WEB-INF)/webservices.xml) or a packed jar.
0382: * @param url the url to load (can be a directory, xml, jar).
0383: * @param cl the classLoader to use for loading files.
0384: * @return WSDeploymentDesc object.
0385: * @throws WSDeploymentDescException when parsing error.
0386: */
0387: private static WSDeploymentDesc loadDeploymentDesc(URL url,
0388: ClassLoader cl) throws WSDeploymentDescException {
0389:
0390: URLClassLoader ucl = (URLClassLoader) cl;
0391:
0392: // get the Webservices object for this module
0393: InputStream isWebservices = null;
0394:
0395: // get the JonasWebservices object for this module
0396: InputStream isJonasWebservices = null;
0397:
0398: URL wsXml = null;
0399: URL jwsXml = null;
0400:
0401: try {
0402:
0403: boolean foundInEjb = false;
0404: for (Enumeration ejbWebservices = ucl
0405: .findResources("META-INF/webservices.xml"); ejbWebservices
0406: .hasMoreElements()
0407: && !foundInEjb;) {
0408: wsXml = (URL) ejbWebservices.nextElement();
0409: if (isResourceInFile(url, wsXml)) {
0410: foundInEjb = true;
0411: }
0412: }
0413:
0414: // if DD found in Ejb
0415: if (foundInEjb) {
0416: isWebservices = openInputStream(wsXml);
0417:
0418: foundInEjb = false;
0419: // try load jonas DD
0420: for (Enumeration ejbJonasWebservices = ucl
0421: .findResources("META-INF/jonas-webservices.xml"); ejbJonasWebservices
0422: .hasMoreElements()
0423: && !foundInEjb;) {
0424: jwsXml = (URL) ejbJonasWebservices.nextElement();
0425: if (isResourceInFile(url, jwsXml)) {
0426: foundInEjb = true;
0427: }
0428: }
0429: if (foundInEjb) {
0430: isJonasWebservices = openInputStream(jwsXml);
0431:
0432: }
0433: }
0434:
0435: boolean foundInWeb = false;
0436: for (Enumeration webWebservices = ucl
0437: .findResources("WEB-INF/webservices.xml"); webWebservices
0438: .hasMoreElements()
0439: && !foundInWeb;) {
0440: wsXml = (URL) webWebservices.nextElement();
0441: if (isResourceInFile(url, wsXml)) {
0442: foundInWeb = true;
0443: }
0444: }
0445:
0446: // if DD found in Web
0447: if (foundInWeb) {
0448: isWebservices = openInputStream(wsXml);
0449:
0450: foundInWeb = false;
0451: // try load jonas DD
0452: for (Enumeration webJonasWebservices = ucl
0453: .findResources("WEB-INF/jonas-webservices.xml"); webJonasWebservices
0454: .hasMoreElements()
0455: && !foundInWeb;) {
0456: jwsXml = (URL) webJonasWebservices.nextElement();
0457: if (isResourceInFile(url, jwsXml)) {
0458: foundInWeb = true;
0459: }
0460: }
0461: if (foundInWeb) {
0462: isJonasWebservices = openInputStream(jwsXml);
0463: }
0464: }
0465: } catch (IOException ioe) {
0466: String err = "Cannot open Streams on WebServices Deployment Descriptor for '"
0467: + url + "'";
0468: throw new WSDeploymentDescException(err, ioe);
0469: }
0470:
0471: // webservices.xml not found in module, return null
0472: if (isWebservices == null) {
0473: return null;
0474: }
0475:
0476: // Load and Parse files
0477: Webservices webservices = loadWebservices(
0478: new InputStreamReader(isWebservices), wsXml.getFile());
0479: JonasWebservices jonasWebservices = null;
0480:
0481: if (isJonasWebservices != null) {
0482: jonasWebservices = loadJonasWebservices(
0483: new InputStreamReader(isJonasWebservices), jwsXml
0484: .getFile());
0485: }
0486:
0487: try {
0488: if (isWebservices != null) {
0489: isWebservices.close();
0490: }
0491: if (isJonasWebservices != null) {
0492: isJonasWebservices.close();
0493: }
0494: } catch (IOException ioe) {
0495: // nothing to do, just log a warning
0496: String err = "Cannot close InputStreams for '" + url + "'";
0497: logger.log(BasicLevel.WARN, err);
0498: }
0499:
0500: // Create DeploymentDesc
0501: WSDeploymentDesc wsdd = new WSDeploymentDesc(cl, logger,
0502: webservices, jonasWebservices);
0503:
0504: return wsdd;
0505:
0506: }
0507:
0508: /**
0509: * @param xml URL
0510: * @return InputStream of the URL Content
0511: * @throws IOException
0512: */
0513: private static InputStream openInputStream(URL xml)
0514: throws IOException {
0515: URLConnection conn = xml.openConnection();
0516: conn.setUseCaches(false);
0517: conn.setDefaultUseCaches(false);
0518: InputStream is = conn.getInputStream();
0519:
0520: return is;
0521: }
0522:
0523: /**
0524: * Returns true if the URL resource is located in the specified file.
0525: * @param file file to search in
0526: * @param resource resource name to search
0527: * @return true if the URL resource is located in the specified file.
0528: */
0529: private static boolean isResourceInFile(URL file, URL resource) {
0530:
0531: boolean within = false;
0532:
0533: File f = new File(file.getFile());
0534: if (f.isDirectory()) {
0535: // test directory
0536: // resource need to be of the form :
0537: // <resource> = <file>/META-INF/webservices.xml for example
0538: if (resource.toString().startsWith(file.toString())) {
0539: within = true;
0540: if (logger.isLoggable(BasicLevel.DEBUG)) {
0541: logger.log(BasicLevel.DEBUG,
0542: "Directory case. found '" + resource
0543: + "' in '" + file + "'");
0544: }
0545: }
0546: } else if (f.isFile()) {
0547: if (f.getPath().endsWith(".xml")) {
0548: // test XML
0549: // resource need to be of the form :
0550: // <file> = <resource>
0551: if (file.equals(resource)) {
0552: within = true;
0553: if (logger.isLoggable(BasicLevel.DEBUG)) {
0554: logger.log(BasicLevel.DEBUG,
0555: "XML case. found '" + resource
0556: + "' in '" + file + "'");
0557: }
0558: }
0559: } else if ((f.getPath().endsWith(".war"))
0560: || (f.getPath().endsWith(".jar"))) {
0561: // test JarFile
0562: // resource need to be of the form :
0563: // <resource> = jar:<file>!/META-INF/webservices.xml for example
0564: int index = resource.toString().indexOf("!/");
0565: if (index != -1) {
0566: if (resource.toString().startsWith(
0567: ("jar:" + file.toString()))) {
0568: within = true;
0569: if (logger.isLoggable(BasicLevel.DEBUG)) {
0570: logger.log(BasicLevel.DEBUG,
0571: "Archive case. found '" + resource
0572: + "' in '" + file + "'");
0573: }
0574: }
0575: }
0576: }
0577: }
0578: return within;
0579: }
0580:
0581: /**
0582: * return a 'xml' object containing webservices.xml informations
0583: * @param reader webservices.xml file input stream reader
0584: * @param fileName webservices.xml file name
0585: * @return a 'xml' object containing webservices.xml informations
0586: * @throws WSDeploymentDescException when Webservices cannot be created with
0587: * the given files.
0588: */
0589: public static Webservices loadWebservices(Reader reader,
0590: String fileName) throws WSDeploymentDescException {
0591:
0592: Webservices ws = new Webservices();
0593:
0594: // Create if wsDigester is null
0595: if (wsDigester == null) {
0596: try {
0597: // Create and initialize the digester
0598: wsDigester = new JDigester(wsRuleSet,
0599: getParsingWithValidation(), true, null,
0600: new WsSchemas());
0601: } catch (DeploymentDescException e) {
0602: throw new WSDeploymentDescException(e);
0603: }
0604: }
0605:
0606: try {
0607: wsDigester.parse(reader, fileName, ws);
0608: } catch (DeploymentDescException e) {
0609: throw new WSDeploymentDescException(e);
0610: } finally {
0611: wsDigester.push(null);
0612: }
0613:
0614: return ws;
0615: }
0616:
0617: /**
0618: * return a 'xml' object containing jonas-webservices.xml informations
0619: * @param reader jonas-webservices.xml file input stream reader
0620: * @param fileName jonas-webservices.xml file name
0621: * @return a 'xml' object containing jonas-webservices.xml informations
0622: * @throws WSDeploymentDescException when JonasWebservices cannot be created
0623: * with the given files.
0624: */
0625: public static JonasWebservices loadJonasWebservices(Reader reader,
0626: String fileName) throws WSDeploymentDescException {
0627:
0628: JonasWebservices jws = new JonasWebservices();
0629:
0630: // Create if wsDigester is null
0631: if (jwsDigester == null) {
0632: try {
0633: // Create and initialize the digester
0634: jwsDigester = new JDigester(jwsRuleSet,
0635: getParsingWithValidation(), true, null,
0636: new JonasWsSchemas());
0637: } catch (DeploymentDescException e) {
0638: throw new WSDeploymentDescException(e);
0639: }
0640: }
0641:
0642: try {
0643: jwsDigester.parse(reader, fileName, jws);
0644: } catch (DeploymentDescException e) {
0645: throw new WSDeploymentDescException(e);
0646: } finally {
0647: jwsDigester.push(null);
0648: }
0649:
0650: return jws;
0651:
0652: }
0653:
0654: /**
0655: * Get the size of the cache (number of entries in the cache). Used only for
0656: * debugging.
0657: * @return the size of the cache (number of entries in the cache).
0658: */
0659: public int getCacheSize() {
0660: return urlWsddBindings.size();
0661:
0662: }
0663:
0664: /**
0665: * Clear the cache.
0666: */
0667: public void clearCache() {
0668: urlWsddBindings = new HashMap();
0669: }
0670:
0671: /**
0672: * Remove the DD cache for the specified ClassLoader
0673: * @param cl the Key ClassLoader
0674: */
0675: public void removeCache(ClassLoader cl) {
0676: List urls = (List) classLoader2URLs.remove(cl);
0677: if (urls != null) {
0678: for (Iterator i = urls.iterator(); i.hasNext();) {
0679: URL url = (URL) i.next();
0680: urlWsddBindings.remove(url);
0681: }
0682: }
0683: }
0684:
0685: /**
0686: * Return a string representation of the cache. (Used only for debugging).
0687: * @return a string representation of the cache.
0688: */
0689: public String toString() {
0690: return "" + getCacheSize();
0691:
0692: }
0693:
0694: /**
0695: * Return a StatelessSessionDesc found in filename with the name link. Used
0696: * by WsGen only. (No JOnAS running).
0697: * @param filename the ejb-jar file to load.
0698: * @param link the ejb-name to retrieve.
0699: * @param cl the classLoader to use.
0700: * @return he StatelessSessionDesc associated with this port component
0701: * @throws WSDeploymentDescException if ejb-link not found or something went
0702: * wrong when parsing ejb deployment desc.
0703: */
0704: private static SessionStatelessDesc getBeanDesc(String filename,
0705: String link, ClassLoader cl)
0706: throws WSDeploymentDescException {
0707:
0708: BeanDesc bd = null;
0709:
0710: try {
0711: // Note : Because we are in the static getDeploymentDesc
0712: // we have the right (accordingly to classloader hierarchie) to use
0713: // real EjbJar Manager
0714: // ---------------------------------------------------
0715: // Do not add import on EjbDeploymentDescManager !!!!
0716: DeploymentDesc dd = org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager
0717: .getDeploymentDesc(filename, cl);
0718: bd = dd.getBeanDesc(link);
0719:
0720: } catch (DeploymentDescException dde) {
0721: throw new WSDeploymentDescException(
0722: "DeploymentDescException when searching '" + link
0723: + "' in '" + filename + "'", dde);
0724: }
0725:
0726: if (bd == null) {
0727: throw new WSDeploymentDescException(
0728: "Unable to find the ejb-link '" + link + "' in '"
0729: + filename + "'");
0730: }
0731:
0732: if (!(bd instanceof SessionStatelessDesc)) {
0733: throw new WSDeploymentDescException("ejb-link '" + link
0734: + "' must be a Stateless Session Bean not a '"
0735: + bd.getClass().getName() + "'");
0736: }
0737:
0738: return (SessionStatelessDesc) bd;
0739:
0740: }
0741:
0742: /**
0743: * Return a StatelessSessionDesc found in filename with the name link. Used
0744: * when JOnAS is running.
0745: * @param filename the ejb-jar file to load.
0746: * @param link the ejb-name to retrieve.
0747: * @param jarCL the loader for classes.
0748: * @param earCL the EAR classLoader .
0749: * @return the StatelessSessionDesc associated with this port component
0750: * @throws WSDeploymentDescException if ejb-link not found or something went
0751: * wrong when parsing ejb deployment desc.
0752: */
0753: private SessionStatelessDesc getBeanDesc(String filename,
0754: String link, ClassLoader jarCL, ClassLoader earCL)
0755: throws WSDeploymentDescException {
0756: URL url;
0757:
0758: try {
0759: url = new File(filename).toURL();
0760:
0761: } catch (MalformedURLException mue) {
0762: throw new WSDeploymentDescException("Url Error with '"
0763: + filename + "'", mue);
0764: }
0765:
0766: BeanDesc bd = null;
0767:
0768: try {
0769: DeploymentDesc dd = ejbManager.getDeploymentDesc(url,
0770: jarCL, earCL);
0771: bd = dd.getBeanDesc(link);
0772:
0773: } catch (DeploymentDescException dde) {
0774: throw new WSDeploymentDescException(
0775: "Unable to load EjbJar '" + url + "'", dde);
0776: }
0777:
0778: // Ejb Link not found
0779: if (bd == null) {
0780: throw new WSDeploymentDescException(
0781: "Unable to find the ejb-link '" + link + "' in '"
0782: + filename + "'");
0783: }
0784:
0785: if (!(bd instanceof SessionStatelessDesc)) {
0786: throw new WSDeploymentDescException("ejb-link '" + link
0787: + "' must be a Stateless Session Bean");
0788: }
0789:
0790: return (SessionStatelessDesc) bd;
0791:
0792: }
0793:
0794: /**
0795: * Return the Web Deployment Desc found in filename with the name link.
0796: * @param filename the war file to load.
0797: * @param link the servlet-name to retrieve.
0798: * @param cl the classLoader to use.
0799: * @return the Web Deployment Desc associated with this port component
0800: * @throws WSDeploymentDescException if servlet-link not found or something
0801: * went wrong when parsing web deployment desc.
0802: */
0803: private static WebContainerDeploymentDesc getWebDesc(
0804: String filename, String link, ClassLoader cl)
0805: throws WSDeploymentDescException {
0806:
0807: WebContainerDeploymentDesc wd = null;
0808:
0809: try {
0810: // Note : Because we are in the static getDeploymentDesc
0811: // we have the right (accordingly to classloader hierarchie) to use
0812: // real Web Manager
0813: // ---------------------------------------------------
0814: // Do not add import on WebDeploymentDescManager !!!!
0815: wd = org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager
0816: .getDeploymentDesc(filename, cl);
0817: } catch (WebContainerDeploymentDescException wcdde) {
0818: throw new WSDeploymentDescException(
0819: "Error while reading/parsing " + filename, wcdde);
0820: }
0821:
0822: // link not found in this deployment desc
0823: if (wd.getServletClassname(link) == null) {
0824: throw new WSDeploymentDescException(
0825: "Unable to find the servlet-link '" + link
0826: + "' in '" + filename + "'");
0827: }
0828:
0829: return wd;
0830:
0831: }
0832:
0833: /**
0834: * Return the Web Deployment Desc found in filename with the name link. Used
0835: * when JOnAS is up and running.
0836: * @param filename the war file to load.
0837: * @param link the servlet-name to retrieve.
0838: * @param jarCL the classLoader to us.
0839: * @param earCL the EAR classLoader.
0840: * @return the Web Deployment Desc associated with this port component
0841: * @throws WSDeploymentDescException if servlet-link not found or something
0842: * went wrong when parsing web deployment desc.
0843: */
0844: private WebContainerDeploymentDesc getWebDesc(String filename,
0845: String link, ClassLoader jarCL, ClassLoader earCL)
0846: throws WSDeploymentDescException {
0847:
0848: URL url;
0849:
0850: try {
0851: url = new File(filename).toURL();
0852: } catch (MalformedURLException mue) {
0853: throw new WSDeploymentDescException("Url Error with '"
0854: + filename + "'", mue);
0855: }
0856:
0857: WebContainerDeploymentDesc wd = null;
0858:
0859: try {
0860: wd = webManager.getDeploymentDesc(url, jarCL, earCL);
0861: } catch (DeploymentDescException wcdde) {
0862: throw new WSDeploymentDescException(
0863: "Error while reading/parsing " + filename, wcdde);
0864: }
0865:
0866: // link not found in this deployment desc
0867: if (wd.getServletClassname(link) == null) {
0868: throw new WSDeploymentDescException(
0869: "Unable to find the servlet-link '" + link
0870: + "' in '" + filename + "'");
0871: }
0872:
0873: return wd;
0874:
0875: }
0876:
0877: /**
0878: * Controls whether the parser is reporting all validity errors.
0879: * @return if true, all external entities will be read.
0880: */
0881: public static boolean getParsingWithValidation() {
0882: return parsingWithValidation;
0883: }
0884:
0885: /**
0886: * Controls whether the parser is reporting all validity errors.
0887: * @param validation if true, all external entities will be read.
0888: */
0889: public static void setParsingWithValidation(boolean validation) {
0890: WSDeploymentDescManager.parsingWithValidation = validation;
0891: }
0892:
0893: /**
0894: * Return the port component desc from the pcLink string. pcLink format :
0895: * filename.[jar or war]#portComponentName in the same Ear File
0896: * @param callerURL the url of the module being parsed. This is needed because
0897: * pcLink is relative. With the url and the pcLink, we can know where
0898: * the file is locate.
0899: * @param portComponentLinkName the pcLink tag of an port-component-ref.
0900: * @param earLoader the classloader of the ear.
0901: * @param moduleLoader classlaoder of the current module
0902: * @return the pcLink portComponent.
0903: * @throws WSDeploymentDescException when it failed
0904: */
0905: public PortComponentDesc getPortComponentDesc(URL callerURL,
0906: String portComponentLinkName, ClassLoader moduleLoader,
0907: ClassLoader earLoader) throws WSDeploymentDescException {
0908:
0909: // Extract from the pc link
0910: // - the name of the file
0911: // - the name of the bean
0912: String moduleLink = null;
0913: String pcNameLink = null;
0914: URL moduleLinkUrl = null;
0915: URLClassLoader loaderForCls = null;
0916:
0917: // port-component-link can use directly the portComponentName without #
0918: // See Bug #300592
0919: if (!portComponentLinkName.matches(".*#.*")) {
0920: // no xxx#yyy
0921: // we just have the port link
0922: pcNameLink = portComponentLinkName;
0923:
0924: moduleLinkUrl = callerURL;
0925: loaderForCls = (URLClassLoader) moduleLoader;
0926: } else {
0927: // xxx#yyy
0928:
0929: // Check the format of the pc-link. It must contains .jar# or .war#
0930: if ((portComponentLinkName.toLowerCase().indexOf(
0931: ".war" + AbsDeploymentDescManager.LINK_SEPARATOR) == -1)
0932: && (portComponentLinkName
0933: .toLowerCase()
0934: .indexOf(
0935: ".jar"
0936: + AbsDeploymentDescManager.LINK_SEPARATOR) == -1)) {
0937: // the pc link is not in war or jar file
0938: String err = "PC-link "
0939: + portComponentLinkName
0940: + " has a bad format. Correct format : filename.[jar or war]#portComponentName or just portComponentName";
0941: throw new WSDeploymentDescException(err);
0942: }
0943: StringTokenizer st = new StringTokenizer(
0944: portComponentLinkName, LINK_SEPARATOR);
0945:
0946: // We must have only two elements after this step, one for the fileName
0947: // before the # and the name of the bean after the # char
0948: if (st.countTokens() != 2
0949: || portComponentLinkName
0950: .startsWith(AbsDeploymentDescManager.LINK_SEPARATOR)
0951: || portComponentLinkName
0952: .endsWith(AbsDeploymentDescManager.LINK_SEPARATOR)) {
0953: String err = "PC-link "
0954: + portComponentLinkName
0955: + " has a bad format. Correct format : filename.[jar or war]#portComponentName or just portComponentName";
0956: throw new WSDeploymentDescException(err);
0957: }
0958:
0959: //Get the token
0960: moduleLink = st.nextToken();
0961: pcNameLink = st.nextToken();
0962:
0963: // Now construct the URL from the absolute path from the url module and
0964: // the relative path from moduleJarLink
0965: try {
0966: moduleLinkUrl = new File(new File(callerURL.getFile())
0967: .getParent()
0968: + File.separator + moduleLink)
0969: .getCanonicalFile().toURL();
0970: } catch (MalformedURLException mue) {
0971: String err = "Error when creating an url for the module filename. Error :"
0972: + mue.getMessage();
0973: throw new WSDeploymentDescException(err, mue);
0974: } catch (IOException ioe) {
0975: String err = "Error when creating/accessing a file. Error :"
0976: + ioe.getMessage();
0977: throw new WSDeploymentDescException(err, ioe);
0978: }
0979:
0980: // Check if the jar exist.
0981: if (!new File(moduleLinkUrl.getFile()).exists()) {
0982: String err = "Cannot get the deployment descriptor for '"
0983: + moduleLinkUrl.getFile()
0984: + "'. The file doesn't exist.";
0985: throw new WSDeploymentDescException(err);
0986: }
0987:
0988: URL[] ddURL = new URL[1];
0989: ddURL[0] = moduleLinkUrl;
0990: loaderForCls = new URLClassLoader(ddURL, earLoader);
0991:
0992: }
0993:
0994: // We've got the url
0995: // Now, We can ask the Deployment Descriptor of this url
0996: WSDeploymentDesc wsDD = null;
0997:
0998: try {
0999: wsDD = getDeploymentDesc(moduleLinkUrl, loaderForCls,
1000: earLoader);
1001: } catch (DeploymentDescException e) {
1002: String err = "Cannot get the deployment descriptor for '"
1003: + moduleLinkUrl.getFile() + "'.";
1004: throw new WSDeploymentDescException(err, e);
1005: }
1006: if (wsDD == null) {
1007: // the module doesn't contain port components.
1008: String err = "Port component link " + pcNameLink
1009: + " not found in " + moduleLinkUrl.getFile();
1010: throw new WSDeploymentDescException(err);
1011: }
1012:
1013: //get port component desc //pcNameLink
1014: List sdl = wsDD.getServiceDescs();
1015: boolean isFound = false;
1016: PortComponentDesc pcd = null;
1017: for (int i = 0; (i < sdl.size()) && !isFound; i++) {
1018: if (sdl.get(i) != null) {
1019: pcd = ((ServiceDesc) sdl.get(i))
1020: .getPortComponent(pcNameLink);
1021: isFound = (pcd != null);
1022: // we stop when we have found the good portComponent
1023: }
1024: }
1025: if (!isFound) {
1026: // the module doesn't contain port components.
1027: String err = "the port component link " + pcNameLink
1028: + " doesn't exist in " + moduleLinkUrl.getFile();
1029: throw new WSDeploymentDescException(err);
1030: }
1031:
1032: return pcd;
1033: }
1034: }
|