org.objectweb.jonas_ws.deployment.lib.WSDeploymentDescManager Maven / Gradle / Ivy
/**
* JOnAS: Java(TM) Open Application Server
* Copyright (C) 1999-2004 Bull S.A.
* Contact: [email protected]
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Initial Developer : Delplanque Xavier & Sauthier Guillaume
* --------------------------------------------------------------------------
* $Id: WSDeploymentDescManager.java 10290 2007-04-25 16:11:47Z durieuxp $
* --------------------------------------------------------------------------
*/
package org.objectweb.jonas_ws.deployment.lib;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc;
import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;
import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
import org.objectweb.jonas_lib.deployment.digester.JDigester;
import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc;
import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDescException;
import org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager;
import org.objectweb.jonas_ws.deployment.api.JonasWsSchemas;
import org.objectweb.jonas_ws.deployment.api.PortComponentDesc;
import org.objectweb.jonas_ws.deployment.api.ServiceDesc;
import org.objectweb.jonas_ws.deployment.api.WSDeploymentDesc;
import org.objectweb.jonas_ws.deployment.api.WSDeploymentDescException;
import org.objectweb.jonas_ws.deployment.api.WsSchemas;
import org.objectweb.jonas_ws.deployment.rules.JonasWebservicesRuleSet;
import org.objectweb.jonas_ws.deployment.rules.WebservicesRuleSet;
import org.objectweb.jonas_ws.deployment.xml.JonasWebservices;
import org.objectweb.jonas_ws.deployment.xml.Webservices;
import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
/**
* This class provide a way for managing the WSDeploymentDesc. Note that there
* is 1 instance of the WSDeploymentDescManager on each JOnAS server.
* @author Guillaume Sauthier
* @author Xavier Delplanque
* @author Helene Joanin
*/
public class WSDeploymentDescManager extends AbsDeploymentDescManager {
/**
* ejb-jar.xml filename
*/
public static final String WS_EJBJAR_FILE_NAME = "META-INF/webservices.xml";
/**
* jonas-ejb-jar.xml filename
*/
public static final String JONAS_WS_EJBJAR_FILE_NAME = "META-INF/jonas-webservices.xml";
/**
* ejb-jar.xml filename
*/
public static final String WS_WEBAPP_FILE_NAME = "WEB-INF/webservices.xml";
/**
* jonas-ejb-jar.xml filename
*/
public static final String JONAS_WS_WEBAPP_FILE_NAME = "WEB-INF/jonas-webservices.xml";
/**
* Digester used to parse webservices.xml
*/
private static JDigester wsDigester = null;
/**
* Digester used to parse jonas-webservices.xml
*/
private static JDigester jwsDigester = null;
/**
* Rules to parse the webservices.xml
*/
private static WebservicesRuleSet wsRuleSet = new WebservicesRuleSet();
/**
* Rules to parse the jonas-webservices.xml
*/
private static JonasWebservicesRuleSet jwsRuleSet = new JonasWebservicesRuleSet();
/**
* Flag for parser validation
*/
private static boolean parsingWithValidation = true;
/**
* The unique instance of the WSDeploymentDescManager
*/
private static WSDeploymentDescManager unique = null;
/**
* is the manager instanciated ?
*/
private static boolean isInstanciated = false;
/**
* Logger for the deployment desc manager.
*/
private static Logger logger = Log.getLogger(Log.JONAS_WS_PREFIX);
/**
* Associates module or webservices dd URL and a WSDeploymentDesc
*/
private HashMap urlWsddBindings;
/**
* Associates a given ClassLaoder (ear/ejb/web) to a list of URL containing
* (or not) WSDD
*/
private Map classLoader2URLs;
/**
* EJB Descriptor Manager
*/
private EjbDeploymentDescManager ejbManager = null;
/**
* Web Descriptor Manager
*/
private WebDeploymentDescManager webManager = null;
/**
* Constructor : creates a WSDeploymentDescManager object. Used only when
* loading files in the running JOnAS instance.
*/
private WSDeploymentDescManager() {
urlWsddBindings = new HashMap();
classLoader2URLs = new Hashtable();
ejbManager = EjbDeploymentDescManager.getInstance();
webManager = WebDeploymentDescManager.getInstance();
}
/**
* Get the unique instance of the WSDeploymentDescManager.
* @return the instance of the WSDeploymentDescManager.
*/
public static WSDeploymentDescManager getInstance() {
if (!isInstanciated) {
isInstanciated = true;
unique = new WSDeploymentDescManager();
}
return unique;
}
/**
* Get the specified WebService deployment descriptor. Used by WsGen.
* @param file module (ejbjar or war). It is required that file is not a
* directory.
* @param jarCL the classloader where classes are stored.
* @return the module webservices deployment descriptor if it exists, null
* else.
* @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
* with the given files.
*/
public static WSDeploymentDesc getDeploymentDesc(String file, ClassLoader jarCL) throws WSDeploymentDescException {
URL fileUrl = null;
try {
fileUrl = new File(file).toURL();
} catch (MalformedURLException mue) {
throw new WSDeploymentDescException(mue);
}
WSDeploymentDesc wsdd = loadDeploymentDesc(fileUrl, jarCL);
// webservices.xml not present in file, no resolution needed
if (wsdd == null) {
return null;
}
// Resolve ejb-link and servlet-link elements
List sdl = wsdd.getServiceDescs();
for (int i = 0; i < sdl.size(); i++) {
List pcdl = ((ServiceDesc) sdl.get(i)).getPortComponents();
for (int j = 0; j < pcdl.size(); j++) {
// Resolve the ejb-link and servlet-link of each port components
PortComponentDesc pcd = (PortComponentDesc) pcdl.get(j);
String sibLink = pcd.getSibLink();
// a link is defined, we resolve it
if (pcd.hasBeanImpl()) {
SessionStatelessDesc desc = getBeanDesc(file, sibLink, jarCL);
pcd.setDesc(desc);
} else if (pcd.hasJaxRpcImpl()) {
WebContainerDeploymentDesc desc = getWebDesc(file, sibLink, jarCL);
pcd.setDesc(desc);
}
}
}
return wsdd;
}
/**
* Get the specified ws deployment descriptor and put it in the cache if it
* is not in.
* @param url module (ejbjar or war). It can be a directory or a jar file.
* @param jarCL classloader used to load bean classes.
* @param earCL the parent classloader (the ear classloader). Null when not
* in the case of an ear application.
* @return the module webservices deployment descriptor if it exists, null
* else.
* @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
* with the given files.
*/
public WSDeploymentDesc getDeploymentDesc(URL url, ClassLoader jarCL, ClassLoader earCL)
throws WSDeploymentDescException {
return getDeploymentDesc(url, null, jarCL, earCL);
}
/**
* Get the specified ws deployment descriptor and put it in the cache if it
* is not in.
* @param url module (ejbjar or war). It can be a directory or a jar file.
* @param unpackedURL Unpacked URL of the module archive
* @param jarCL classloader used to load bean classes.
* @param earCL the parent classloader (the ear classloader). Null when not
* in the case of an ear application.
* @return the module webservices deployment descriptor if it exists, null
* else.
* @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
* with the given files.
*/
public WSDeploymentDesc getDeploymentDesc(URL url, URL unpackedURL, ClassLoader jarCL, ClassLoader earCL)
throws WSDeploymentDescException {
WSDeploymentDesc wsdd = null;
File moduleFile = new File(url.getFile());
if (moduleFile.exists()) {
// if the module has yet been loaded
if (!urlWsddBindings.containsKey(url)) {
wsdd = getDeploymentDescriptor(url, unpackedURL, jarCL, earCL);
} else { // module already loaded
// Can be null if no webservices.xml has been found in specified
// module
wsdd = (WSDeploymentDesc) urlWsddBindings.get(url);
}
} else {
throw new WSDeploymentDescException("'" + moduleFile.getName() + "' doesn't exists");
}
// Store binding
ClassLoader keyCL;
if (earCL != null) {
keyCL = earCL;
} else {
keyCL = jarCL;
}
List urls = (List) classLoader2URLs.get(keyCL);
if (urls == null) {
urls = new Vector();
classLoader2URLs.put(keyCL, urls);
}
urls.add(url);
return wsdd;
}
/**
* return the specified webservices deployment descriptor and put it in
* cache.
* @param url an existing module (ejbjar or war). It can be a directory or a
* jar file
* @param unpackedURL Unpacked URL of the module archive
* @param jarCL classloader used to load war or ejbjar classes.
* @param earCL the parent classloader (the ear classloader). Null when not
* in the case of an ear application.
* @return the module webservices deployment descriptor if it exists, null
* else.
* @throws WSDeploymentDescException when WSDeploymentDesc cannot be created
* with the given files.
*/
private WSDeploymentDesc getDeploymentDescriptor(URL url, URL unpackedURL, ClassLoader jarCL, ClassLoader earCL)
throws WSDeploymentDescException {
URL baseURL = url;
if (unpackedURL != null) {
baseURL = unpackedURL;
}
WSDeploymentDesc wsdd = loadDeploymentDesc(baseURL, jarCL);
// add in cache the deployment descriptor and return it
urlWsddBindings.put(url, wsdd);
// No WSDeploymentDesc, return null
if (wsdd == null) {
return null;
}
// Resolve ejb-link and servlet-link elements
List sdl = wsdd.getServiceDescs();
for (int i = 0; i < sdl.size(); i++) {
List pcdl = ((ServiceDesc) sdl.get(i)).getPortComponents();
for (int j = 0; j < pcdl.size(); j++) {
// Resolve the ejb-link and servlet-link of each port components
PortComponentDesc pcd = (PortComponentDesc) pcdl.get(j);
String sibLink = pcd.getSibLink();
// a link is defined, we resolve it
if (pcd.hasBeanImpl()) {
SessionStatelessDesc desc = getBeanDesc(url.getFile(), sibLink, jarCL, earCL);
pcd.setDesc(desc);
} else if (pcd.hasJaxRpcImpl()) {
WebContainerDeploymentDesc desc = getWebDesc(url.getFile(), sibLink, jarCL, earCL);
pcd.setDesc(desc);
}
}
}
return wsdd;
}
/**
* Load webservices.xml in the WSDeploymentDesc structure (null if
* webservices.xml not found). Can take as parameter a directory (like an
* unpacked jar root directory), a XML file name (path to
* (META-INF|WEB-INF)/webservices.xml) or a packed jar.
* @param url the url to load (can be a directory, xml, jar).
* @param cl the classLoader to use for loading files.
* @return WSDeploymentDesc object.
* @throws WSDeploymentDescException when parsing error.
*/
private static WSDeploymentDesc loadDeploymentDesc(URL url, ClassLoader cl) throws WSDeploymentDescException {
URLClassLoader ucl = (URLClassLoader) cl;
// get the Webservices object for this module
InputStream isWebservices = null;
// get the JonasWebservices object for this module
InputStream isJonasWebservices = null;
URL wsXml = null;
URL jwsXml = null;
try {
boolean foundInEjb = false;
for (Enumeration ejbWebservices = ucl.findResources("META-INF/webservices.xml"); ejbWebservices
.hasMoreElements()
&& !foundInEjb;) {
wsXml = (URL) ejbWebservices.nextElement();
if (isResourceInFile(url, wsXml)) {
foundInEjb = true;
}
}
// if DD found in Ejb
if (foundInEjb) {
isWebservices = openInputStream(wsXml);
foundInEjb = false;
// try load jonas DD
for (Enumeration ejbJonasWebservices = ucl.findResources("META-INF/jonas-webservices.xml"); ejbJonasWebservices
.hasMoreElements()
&& !foundInEjb;) {
jwsXml = (URL) ejbJonasWebservices.nextElement();
if (isResourceInFile(url, jwsXml)) {
foundInEjb = true;
}
}
if (foundInEjb) {
isJonasWebservices = openInputStream(jwsXml);
}
}
boolean foundInWeb = false;
for (Enumeration webWebservices = ucl.findResources("WEB-INF/webservices.xml"); webWebservices
.hasMoreElements()
&& !foundInWeb;) {
wsXml = (URL) webWebservices.nextElement();
if (isResourceInFile(url, wsXml)) {
foundInWeb = true;
}
}
// if DD found in Web
if (foundInWeb) {
isWebservices = openInputStream(wsXml);
foundInWeb = false;
// try load jonas DD
for (Enumeration webJonasWebservices = ucl.findResources("WEB-INF/jonas-webservices.xml"); webJonasWebservices
.hasMoreElements()
&& !foundInWeb;) {
jwsXml = (URL) webJonasWebservices.nextElement();
if (isResourceInFile(url, jwsXml)) {
foundInWeb = true;
}
}
if (foundInWeb) {
isJonasWebservices = openInputStream(jwsXml);
}
}
} catch (IOException ioe) {
String err = "Cannot open Streams on WebServices Deployment Descriptor for '" + url + "'";
throw new WSDeploymentDescException(err, ioe);
}
// webservices.xml not found in module, return null
if (isWebservices == null) {
return null;
}
// Load and Parse files
Webservices webservices = loadWebservices(new InputStreamReader(isWebservices), wsXml.getFile());
JonasWebservices jonasWebservices = null;
if (isJonasWebservices != null) {
jonasWebservices = loadJonasWebservices(new InputStreamReader(isJonasWebservices), jwsXml.getFile());
}
try {
if (isWebservices != null) {
isWebservices.close();
}
if (isJonasWebservices != null) {
isJonasWebservices.close();
}
} catch (IOException ioe) {
// nothing to do, just log a warning
String err = "Cannot close InputStreams for '" + url + "'";
logger.log(BasicLevel.WARN, err);
}
// Create DeploymentDesc
WSDeploymentDesc wsdd = new WSDeploymentDesc(cl, logger, webservices, jonasWebservices);
return wsdd;
}
/**
* @param xml URL
* @return InputStream of the URL Content
* @throws IOException
*/
private static InputStream openInputStream(URL xml) throws IOException {
URLConnection conn = xml.openConnection();
conn.setUseCaches(false);
conn.setDefaultUseCaches(false);
InputStream is = conn.getInputStream();
return is;
}
/**
* Returns true if the URL resource is located in the specified file.
* @param file file to search in
* @param resource resource name to search
* @return true if the URL resource is located in the specified file.
*/
private static boolean isResourceInFile(URL file, URL resource) {
boolean within = false;
File f = new File(file.getFile());
if (f.isDirectory()) {
// test directory
// resource need to be of the form :
// = /META-INF/webservices.xml for example
if (resource.toString().startsWith(file.toString())) {
within = true;
if (logger.isLoggable(BasicLevel.DEBUG)) {
logger.log(BasicLevel.DEBUG, "Directory case. found '" + resource + "' in '" + file + "'");
}
}
} else if (f.isFile()) {
if (f.getPath().endsWith(".xml")) {
// test XML
// resource need to be of the form :
// =
if (file.equals(resource)) {
within = true;
if (logger.isLoggable(BasicLevel.DEBUG)) {
logger.log(BasicLevel.DEBUG, "XML case. found '" + resource + "' in '" + file + "'");
}
}
} else if ((f.getPath().endsWith(".war")) || (f.getPath().endsWith(".jar"))) {
// test JarFile
// resource need to be of the form :
// = jar:!/META-INF/webservices.xml for example
int index = resource.toString().indexOf("!/");
if (index != -1) {
if (resource.toString().startsWith(("jar:" + file.toString()))) {
within = true;
if (logger.isLoggable(BasicLevel.DEBUG)) {
logger.log(BasicLevel.DEBUG, "Archive case. found '" + resource + "' in '" + file + "'");
}
}
}
}
}
return within;
}
/**
* return a 'xml' object containing webservices.xml informations
* @param reader webservices.xml file input stream reader
* @param fileName webservices.xml file name
* @return a 'xml' object containing webservices.xml informations
* @throws WSDeploymentDescException when Webservices cannot be created with
* the given files.
*/
public static Webservices loadWebservices(Reader reader, String fileName) throws WSDeploymentDescException {
Webservices ws = new Webservices();
// Create if wsDigester is null
if (wsDigester == null) {
try {
// Create and initialize the digester
wsDigester = new JDigester(wsRuleSet, getParsingWithValidation(), true, null, new WsSchemas());
} catch (DeploymentDescException e) {
throw new WSDeploymentDescException(e);
}
}
try {
wsDigester.parse(reader, fileName, ws);
} catch (DeploymentDescException e) {
throw new WSDeploymentDescException(e);
} finally {
wsDigester.push(null);
}
return ws;
}
/**
* return a 'xml' object containing jonas-webservices.xml informations
* @param reader jonas-webservices.xml file input stream reader
* @param fileName jonas-webservices.xml file name
* @return a 'xml' object containing jonas-webservices.xml informations
* @throws WSDeploymentDescException when JonasWebservices cannot be created
* with the given files.
*/
public static JonasWebservices loadJonasWebservices(Reader reader, String fileName)
throws WSDeploymentDescException {
JonasWebservices jws = new JonasWebservices();
// Create if wsDigester is null
if (jwsDigester == null) {
try {
// Create and initialize the digester
jwsDigester = new JDigester(jwsRuleSet, getParsingWithValidation(), true, null, new JonasWsSchemas());
} catch (DeploymentDescException e) {
throw new WSDeploymentDescException(e);
}
}
try {
jwsDigester.parse(reader, fileName, jws);
} catch (DeploymentDescException e) {
throw new WSDeploymentDescException(e);
} finally {
jwsDigester.push(null);
}
return jws;
}
/**
* Get the size of the cache (number of entries in the cache). Used only for
* debugging.
* @return the size of the cache (number of entries in the cache).
*/
public int getCacheSize() {
return urlWsddBindings.size();
}
/**
* Clear the cache.
*/
public void clearCache() {
urlWsddBindings = new HashMap();
}
/**
* Remove the DD cache for the specified ClassLoader
* @param cl the Key ClassLoader
*/
public void removeCache(ClassLoader cl) {
List urls = (List) classLoader2URLs.remove(cl);
if (urls != null) {
for (Iterator i = urls.iterator(); i.hasNext();) {
URL url = (URL) i.next();
urlWsddBindings.remove(url);
}
}
}
/**
* Return a string representation of the cache. (Used only for debugging).
* @return a string representation of the cache.
*/
public String toString() {
return "" + getCacheSize();
}
/**
* Return a StatelessSessionDesc found in filename with the name link. Used
* by WsGen only. (No JOnAS running).
* @param filename the ejb-jar file to load.
* @param link the ejb-name to retrieve.
* @param cl the classLoader to use.
* @return he StatelessSessionDesc associated with this port component
* @throws WSDeploymentDescException if ejb-link not found or something went
* wrong when parsing ejb deployment desc.
*/
private static SessionStatelessDesc getBeanDesc(String filename, String link, ClassLoader cl)
throws WSDeploymentDescException {
BeanDesc bd = null;
try {
// Note : Because we are in the static getDeploymentDesc
// we have the right (accordingly to classloader hierarchie) to use
// real EjbJar Manager
// ---------------------------------------------------
// Do not add import on EjbDeploymentDescManager !!!!
DeploymentDesc dd = org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager.getDeploymentDesc(
filename, cl);
bd = dd.getBeanDesc(link);
} catch (DeploymentDescException dde) {
throw new WSDeploymentDescException("DeploymentDescException when searching '" + link + "' in '" + filename
+ "'", dde);
}
if (bd == null) {
throw new WSDeploymentDescException("Unable to find the ejb-link '" + link + "' in '" + filename + "'");
}
if (!(bd instanceof SessionStatelessDesc)) {
throw new WSDeploymentDescException("ejb-link '" + link + "' must be a Stateless Session Bean not a '"
+ bd.getClass().getName() + "'");
}
return (SessionStatelessDesc) bd;
}
/**
* Return a StatelessSessionDesc found in filename with the name link. Used
* when JOnAS is running.
* @param filename the ejb-jar file to load.
* @param link the ejb-name to retrieve.
* @param jarCL the loader for classes.
* @param earCL the EAR classLoader .
* @return the StatelessSessionDesc associated with this port component
* @throws WSDeploymentDescException if ejb-link not found or something went
* wrong when parsing ejb deployment desc.
*/
private SessionStatelessDesc getBeanDesc(String filename, String link, ClassLoader jarCL, ClassLoader earCL)
throws WSDeploymentDescException {
URL url;
try {
url = new File(filename).toURL();
} catch (MalformedURLException mue) {
throw new WSDeploymentDescException("Url Error with '" + filename + "'", mue);
}
BeanDesc bd = null;
try {
DeploymentDesc dd = ejbManager.getDeploymentDesc(url, jarCL, earCL);
bd = dd.getBeanDesc(link);
} catch (DeploymentDescException dde) {
throw new WSDeploymentDescException("Unable to load EjbJar '" + url + "'", dde);
}
// Ejb Link not found
if (bd == null) {
throw new WSDeploymentDescException("Unable to find the ejb-link '" + link + "' in '" + filename + "'");
}
if (!(bd instanceof SessionStatelessDesc)) {
throw new WSDeploymentDescException("ejb-link '" + link + "' must be a Stateless Session Bean");
}
return (SessionStatelessDesc) bd;
}
/**
* Return the Web Deployment Desc found in filename with the name link.
* @param filename the war file to load.
* @param link the servlet-name to retrieve.
* @param cl the classLoader to use.
* @return the Web Deployment Desc associated with this port component
* @throws WSDeploymentDescException if servlet-link not found or something
* went wrong when parsing web deployment desc.
*/
private static WebContainerDeploymentDesc getWebDesc(String filename, String link, ClassLoader cl)
throws WSDeploymentDescException {
WebContainerDeploymentDesc wd = null;
try {
// Note : Because we are in the static getDeploymentDesc
// we have the right (accordingly to classloader hierarchie) to use
// real Web Manager
// ---------------------------------------------------
// Do not add import on WebDeploymentDescManager !!!!
wd = org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager.getDeploymentDesc(filename, cl);
} catch (WebContainerDeploymentDescException wcdde) {
throw new WSDeploymentDescException("Error while reading/parsing " + filename, wcdde);
}
// link not found in this deployment desc
if (wd.getServletClassname(link) == null) {
throw new WSDeploymentDescException("Unable to find the servlet-link '" + link + "' in '" + filename + "'");
}
return wd;
}
/**
* Return the Web Deployment Desc found in filename with the name link. Used
* when JOnAS is up and running.
* @param filename the war file to load.
* @param link the servlet-name to retrieve.
* @param jarCL the classLoader to us.
* @param earCL the EAR classLoader.
* @return the Web Deployment Desc associated with this port component
* @throws WSDeploymentDescException if servlet-link not found or something
* went wrong when parsing web deployment desc.
*/
private WebContainerDeploymentDesc getWebDesc(String filename, String link, ClassLoader jarCL, ClassLoader earCL)
throws WSDeploymentDescException {
URL url;
try {
url = new File(filename).toURL();
} catch (MalformedURLException mue) {
throw new WSDeploymentDescException("Url Error with '" + filename + "'", mue);
}
WebContainerDeploymentDesc wd = null;
try {
wd = webManager.getDeploymentDesc(url, jarCL, earCL);
} catch (DeploymentDescException wcdde) {
throw new WSDeploymentDescException("Error while reading/parsing " + filename, wcdde);
}
// link not found in this deployment desc
if (wd.getServletClassname(link) == null) {
throw new WSDeploymentDescException("Unable to find the servlet-link '" + link + "' in '" + filename + "'");
}
return wd;
}
/**
* Controls whether the parser is reporting all validity errors.
* @return if true, all external entities will be read.
*/
public static boolean getParsingWithValidation() {
return parsingWithValidation;
}
/**
* Controls whether the parser is reporting all validity errors.
* @param validation if true, all external entities will be read.
*/
public static void setParsingWithValidation(boolean validation) {
WSDeploymentDescManager.parsingWithValidation = validation;
}
/**
* Return the port component desc from the pcLink string. pcLink format :
* filename.[jar or war]#portComponentName in the same Ear File
* @param callerURL the url of the module being parsed. This is needed because
* pcLink is relative. With the url and the pcLink, we can know where
* the file is locate.
* @param portComponentLinkName the pcLink tag of an port-component-ref.
* @param earLoader the classloader of the ear.
* @param moduleLoader classlaoder of the current module
* @return the pcLink portComponent.
* @throws WSDeploymentDescException when it failed
*/
public PortComponentDesc getPortComponentDesc(URL callerURL, String portComponentLinkName, ClassLoader moduleLoader, ClassLoader earLoader)
throws WSDeploymentDescException {
// Extract from the pc link
// - the name of the file
// - the name of the bean
String moduleLink = null;
String pcNameLink = null;
URL moduleLinkUrl = null;
URLClassLoader loaderForCls = null;
// port-component-link can use directly the portComponentName without #
// See Bug #300592
if (!portComponentLinkName.matches(".*#.*")) {
// no xxx#yyy
// we just have the port link
pcNameLink = portComponentLinkName;
moduleLinkUrl = callerURL;
loaderForCls = (URLClassLoader) moduleLoader;
} else {
// xxx#yyy
// Check the format of the pc-link. It must contains .jar# or .war#
if ((portComponentLinkName.toLowerCase().indexOf(".war" + AbsDeploymentDescManager.LINK_SEPARATOR) == -1) && (portComponentLinkName.toLowerCase().indexOf(".jar" + AbsDeploymentDescManager.LINK_SEPARATOR) == -1)) {
// the pc link is not in war or jar file
String err = "PC-link " + portComponentLinkName + " has a bad format. Correct format : filename.[jar or war]#portComponentName or just portComponentName";
throw new WSDeploymentDescException(err);
}
StringTokenizer st = new StringTokenizer(portComponentLinkName, LINK_SEPARATOR);
// We must have only two elements after this step, one for the fileName
// before the # and the name of the bean after the # char
if (st.countTokens() != 2 || portComponentLinkName.startsWith(AbsDeploymentDescManager.LINK_SEPARATOR)
|| portComponentLinkName.endsWith(AbsDeploymentDescManager.LINK_SEPARATOR)) {
String err = "PC-link " + portComponentLinkName + " has a bad format. Correct format : filename.[jar or war]#portComponentName or just portComponentName";
throw new WSDeploymentDescException(err);
}
//Get the token
moduleLink = st.nextToken();
pcNameLink = st.nextToken();
// Now construct the URL from the absolute path from the url module and
// the relative path from moduleJarLink
try {
moduleLinkUrl = new File(new File(callerURL.getFile()).getParent() + File.separator + moduleLink).getCanonicalFile().toURL();
} catch (MalformedURLException mue) {
String err = "Error when creating an url for the module filename. Error :" + mue.getMessage();
throw new WSDeploymentDescException(err, mue);
} catch (IOException ioe) {
String err = "Error when creating/accessing a file. Error :" + ioe.getMessage();
throw new WSDeploymentDescException(err, ioe);
}
// Check if the jar exist.
if (!new File(moduleLinkUrl.getFile()).exists()) {
String err = "Cannot get the deployment descriptor for '" + moduleLinkUrl.getFile() + "'. The file doesn't exist.";
throw new WSDeploymentDescException(err);
}
URL[] ddURL = new URL[1];
ddURL[0] = moduleLinkUrl;
loaderForCls = new URLClassLoader(ddURL, earLoader);
}
// We've got the url
// Now, We can ask the Deployment Descriptor of this url
WSDeploymentDesc wsDD = null;
try {
wsDD = getDeploymentDesc(moduleLinkUrl, loaderForCls, earLoader);
} catch (DeploymentDescException e) {
String err = "Cannot get the deployment descriptor for '" + moduleLinkUrl.getFile() + "'.";
throw new WSDeploymentDescException(err, e);
}
if (wsDD == null) {
// the module doesn't contain port components.
String err = "Port component link " + pcNameLink + " not found in " + moduleLinkUrl.getFile();
throw new WSDeploymentDescException(err);
}
//get port component desc //pcNameLink
List sdl = wsDD.getServiceDescs();
boolean isFound = false;
PortComponentDesc pcd = null;
for (int i = 0; (i < sdl.size()) && !isFound; i++) {
if (sdl.get(i) != null) {
pcd = ((ServiceDesc) sdl.get(i)).getPortComponent(pcNameLink);
isFound = (pcd != null);
// we stop when we have found the good portComponent
}
}
if (!isFound) {
// the module doesn't contain port components.
String err = "the port component link " + pcNameLink + " doesn't exist in " + moduleLinkUrl.getFile();
throw new WSDeploymentDescException(err);
}
return pcd;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy