All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectweb.jonas_client.deployment.lib.ClientDeploymentDescManager Maven / Gradle / Ivy

The newest version!
/**
 * 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(s): Florent BENOIT
 * --------------------------------------------------------------------------
 * $Id: ClientDeploymentDescManager.java 10513 2007-06-04 13:38:32Z sauthieg $
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas_client.deployment.lib;

//import java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
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.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import org.objectweb.jonas_client.deployment.api.AppClientDTDs;
import org.objectweb.jonas_client.deployment.api.AppClientSchemas;
import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDesc;
import org.objectweb.jonas_client.deployment.api.ClientContainerDeploymentDescException;
import org.objectweb.jonas_client.deployment.api.JonasAppClientDTDs;
import org.objectweb.jonas_client.deployment.api.JonasAppClientSchemas;
import org.objectweb.jonas_client.deployment.rules.ApplicationClientRuleSet;
import org.objectweb.jonas_client.deployment.rules.JonasClientRuleSet;
import org.objectweb.jonas_client.deployment.xml.ApplicationClient;
import org.objectweb.jonas_client.deployment.xml.JonasClient;

import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager;

import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc;
import org.objectweb.jonas_lib.deployment.digester.JDigester;
import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
import org.objectweb.jonas_lib.deployment.xml.JonasMessageDestination;
import org.objectweb.jonas.loader.WebappClassLoader;

import org.objectweb.jonas_ws.deployment.api.PortComponentDesc;
import org.objectweb.jonas_ws.deployment.api.PortComponentRefDesc;
import org.objectweb.jonas_ws.deployment.api.ServiceDesc;
import org.objectweb.jonas_ws.deployment.api.WSDeploymentDesc;
import org.objectweb.jonas_ws.deployment.api.IServiceRefDesc;
import org.objectweb.jonas_ws.deployment.lib.WSDeploymentDescManager;

/**
 * This class provide a way for managing the ClientContainerDeploymentDesc.
 * @author Florent Benoit
 */
public class ClientDeploymentDescManager extends AbsDeploymentDescManager {

    /**
     * The unique instance of the ClientDeploymentDescManager.
     */
    private static ClientDeploymentDescManager unique;

    /**
     * Reference on the EjbDeploymentDescManager.
     */
    private EjbDeploymentDescManager ejbDDManager = null;

    /**
     * Associate a ear classLoader to an hashtable which contains association
     * between Urls of wars and their optional alt-dd
     */
    private Hashtable earCLAltDDBindings = null;

    /**
     * The path to the application-client.xml file.
     */
    public static final String CLIENT_FILE_NAME = "META-INF/application-client.xml";

    /**
     * The path to the jonas-client.xml file.
     */
    public static final String JONAS_CLIENT_FILE_NAME = "META-INF/jonas-client.xml";

    /**
     * Digester used to parse application-client.xml
     */
    private static JDigester appClientDigester = null;

    /**
     * Digester use to parse jonas-client.xml
     */
    private static JDigester jonasAppClientDigester = null;

    /**
     * Flag for parser validation
     */
    private static boolean parsingWithValidation = true;

    /**
     * Rules to parse the application-client.xml
     */
    private static ApplicationClientRuleSet appClientRuleSet = new ApplicationClientRuleSet();

    /**
     * Rules to parse the jonas-client.xml
     */
    private static JonasClientRuleSet jonasAppClientRuleSet = new JonasClientRuleSet();

    /**
     * Contructs a unique ClientDeploymentDescManager
     */
    private ClientDeploymentDescManager() {
        ejbDDManager = EjbDeploymentDescManager.getInstance();
        earCLAltDDBindings = new Hashtable();
    }

    /**
     * Get an instance of the ClientDeploymentDescManager.
     * @return the instance of the ClientDeploymentDescManager.
     */
    public static ClientDeploymentDescManager getInstance() {
        if (unique == null) {
            unique = new ClientDeploymentDescManager();
        }
        return unique;
    }

    /**
     * Get the specified web deployment descriptor.
     * @param url the url where to load xml deployment descriptors.
     * @param loaderForCls classloader used to load web classes.
     * @param earLoader the ear classloader.
     * @return ClientContainerDeploymentDesc the web deployment descriptor.
     * @throws DeploymentDescException when
     *         ClientContainerDeploymentDesc cannot be created with the given
     *         files.
     */
    public ClientContainerDeploymentDesc getDeploymentDesc(URL url, ClassLoader loaderForCls, ClassLoader earLoader)
            throws DeploymentDescException {

        // Check if the jar exists ...
        if (!new File(url.getFile()).exists()) {
            String err = "Cannot get the deployment descriptor for ";
            err = err + "'" + url.getFile() + "'. The file doesn't exist.";
            throw new ClientContainerDeploymentDescException(err);
        }

        //url used to load an alternate DDesc in the EAR case
        URL altDDUrl = null;

        //check if it's an Ear case or not
        Hashtable urlAltddBindings = null;
        if (earLoader != null) {
            //Mapping ?
            urlAltddBindings = (Hashtable) earCLAltDDBindings.get(earLoader);
            if (urlAltddBindings == null) {
                //If there is no mapping, the setAltDD function was badly
                // called
                String err = "Cannot find if there is alt-dd for '" + url.getFile()
                        + "', the setAltDD function was badly called";
                throw new ClientContainerDeploymentDescException(err);
            }
            //Now we can get the optional alt-dd url file
            altDDUrl = (URL) urlAltddBindings.get(url);
        }

        // ... and get the instance of the ClientContainerDeploymentDesc.
        // If there is an alternate url for the application-client.xml, call the
        // method with this param.
        ClientContainerDeploymentDesc clientDD = null;
        try {
            if (altDDUrl != null) {
                clientDD = getInstance(url.getFile(), loaderForCls, altDDUrl.getFile());
            } else {
                clientDD = getInstance(url.getFile(), loaderForCls);
            }
        } catch (org.objectweb.jonas_lib.deployment.api.DeploymentDescException dde) {
            throw new ClientContainerDeploymentDescException(dde);
        }

        // Resolve the ejb-link for ejb-ref
        EjbRefDesc[] ejbRef = clientDD.getEjbRefDesc();
        for (int i = 0; i < ejbRef.length; i++) {
            if (ejbRef[i].getJndiName() == null) {
                String ejbLink = ejbRef[i].getEjbLink();
                String ejbRefType = ejbRef[i].getEjbRefType();
                if (ejbLink != null) {
                    if (earLoader == null) {
                        throw new ClientContainerDeploymentDescException(
                                "Ejb-link is not authorized from a single client jar. The client jar must be in an ear.");
                    } else {
                        String jndiName = getJndiName(url, ejbLink, earLoader, ejbRefType);
                        ejbRef[i].setJndiName(jndiName);
                    }
                }
            }
        }
        // Resolve the port-component-link for service-ref
        IServiceRefDesc[] serviceRef = clientDD.getServiceRefDesc();

        for (int i = 0; i < serviceRef.length; i++) {

            List pcRefs = serviceRef[i].getPortComponentRefs();
            for (int j = 0; j < pcRefs.size(); j++) {
                // for each service portComponents : resolve links
                PortComponentRefDesc pcr = (PortComponentRefDesc) pcRefs.get(j);
                String pclink = pcr.getPortComponentLink();
                if (pclink != null) {
                    // a pc link is defined, we resolve it
                    PortComponentDesc pcDesc = getPCDesc(url, pclink, earLoader);
                    pcr.setPortComponentDesc(pcDesc);
                }
            }
        }


        // Resolve the message-destination-link for message-destination-ref
        MessageDestinationRefDesc[] mdRef = clientDD.getMessageDestinationRefDesc();
        for (int i = 0; i < mdRef.length; i++) {
            if (mdRef[i].getJndiName() == null) {
                String jndiName = mdRef[i].getJndiName();
                String mdLink = mdRef[i].getMessageDestinationLink();
                String mdType = mdRef[i].getMessageDestinationType();
                String mdUsage = mdRef[i].getMessageDestinationUsage();
                if (mdLink != null) {
                    if (earLoader == null) {
                        throw new ClientContainerDeploymentDescException(
                                "Message-destination-link is not authorized from a single client jar. The client jar must be in an ear.");
                    } else {
                        String mdName = getMDJndiName(url, mdLink, mdType, mdUsage, earLoader);
                        //                        String jndiName = getMdJndiName(url, mdLink,
                        // earLoader, mdType);
                        mdRef[i].setJndiName(jndiName);
                    }
                }
            }
        }
        return clientDD;
    }
    /**
     * Return the port component desc from the pcLink string. pcLink format :
     * filename.[jar or war]#portComponentName in the same Ear File
     * @param warURL the url of the war being parsed. This is needed because
     *        pcLink is relative. With the url and the pcLink, we can know where
     *        the file is locate.
     * @param pcLink the pcLink tag of an port-component-ref.
     * @param earLoader the classloader of the ear.
     * @return the pcLink portComponent.
     * @throws DeploymentDescException when it failed
     */
    private PortComponentDesc getPCDesc(URL warURL, String pcLink, ClassLoader earLoader)
            throws DeploymentDescException {

        // Extract from the pc link
        //   - the name of the file
        //   - the name of the bean
        String moduleLink = null;
        String pcNameLink = null;

        // Check the format of the pc-link. It must contains .jar# or .war#
        if ((pcLink.toLowerCase().indexOf(".war" + LINK_SEPARATOR) == -1)
                && (pcLink.toLowerCase().indexOf(".jar" + LINK_SEPARATOR) == -1)) {
            // the pc link is not in war or jar file
            String err = "PC-link " + pcLink
                    + " has a bad format. Correct format :  filename.(jar|war)#portComponentName";
            throw new DeploymentDescException(err);
        }
        StringTokenizer st = new StringTokenizer(pcLink, 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 || pcLink.startsWith(LINK_SEPARATOR) || pcLink.endsWith(LINK_SEPARATOR)) {
            String err = "PC-link " + pcLink
                    + " has a bad format. Correct format :  filename.[jar or war]#portComponentName";
            throw new DeploymentDescException(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
        URL moduleLinkUrl = null;
        try {
            moduleLinkUrl = new File(new File(warURL.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 DeploymentDescException(err);
        } catch (IOException ioe) {
            String err = "Error when creating/accessing a file. Error :" + ioe.getMessage();
            throw new DeploymentDescException(err);
        }

        // 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 DeploymentDescException(err);
        }

        // We've got the url
        //   Now, We can ask the Deployment Descriptor of this url
        ClassLoader loaderForCls = null;
        ClassLoader current = Thread.currentThread().getContextClassLoader();
        if (moduleLink.toLowerCase().endsWith(".war")) {
            try {
                // webservice in webapp
                loaderForCls = new WebappClassLoader(moduleLinkUrl, current);
            } catch (IOException ioe) {
                throw new DeploymentDescException("Unable to create Web ClassLoader", ioe);
            }
        } else {
            // webservice in ejbjar
            loaderForCls = current;
        }

        WSDeploymentDesc wsDD = null;

        try {
            wsDD = WSDeploymentDescManager.getInstance().getDeploymentDesc(moduleLinkUrl, loaderForCls, earLoader);
        } catch (DeploymentDescException e) {
            String err = "Cannot get the deployment descriptor for '" + moduleLinkUrl.getFile() + "'.";
            throw new DeploymentDescException(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 DeploymentDescException(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 DeploymentDescException(err);
        }

        return pcd;
    }


    /**
     * Get an instance of a Client deployment descriptor by parsing the
     * application-client.xml and jonas-client.xml deployment descriptors.
     * @param clientFileName the fileName of the client file for the deployment
     *        descriptors.
     * @param classLoaderForCls the classloader for the classes.
     * @return a Client deployment descriptor by parsing the
     *         application-client.xml and jonas-client.xml deployment
     *         descriptors.
     * @throws DeploymentDescException if the deployment descriptors are
     *         corrupted.
     */
    public static ClientContainerDeploymentDesc getInstance(String clientFileName, ClassLoader classLoaderForCls)
            throws DeploymentDescException {

        return getInstance(clientFileName, classLoaderForCls, null);
    }

    /**
     * Get an instance of a Client deployment descriptor by parsing the
     * application-client.xml and jonas-client.xml deployment descriptors.
     * @param clientFileName the fileName of the client file for the deployment
     *        descriptors.
     * @param classLoaderForCls the classloader for the classes.
     * @param altClientXmlFilename the fileName to the application-client.xml
     *        for the alt-dd tag in the Ear Case. This is used for specify an
     *        alternate DDesc file.
     * @return a Client deployment descriptor by parsing the
     *         application-client.xml and jonas-client.xml deployment
     *         descriptors.
     * @throws DeploymentDescException if the deployment descriptors are
     *         corrupted.
     */
    public static ClientContainerDeploymentDesc getInstance(String clientFileName, ClassLoader classLoaderForCls,
            String altClientXmlFilename)

    throws DeploymentDescException {

        // clientjar file
        JarFile clientFile = null;

        // Input streams
        InputStream applicationClientInputStream = null;
        InputStream jonasClientInputStream = null;

        // ZipEntry
        ZipEntry applicationClientZipEntry = null;
        ZipEntry jonasClientZipEntry = null;

        // Clients
        ApplicationClient applicationClient;
        JonasClient jonasClient;

        // Init xml contents values;
        String xmlContent = "";
        String jonasXmlContent = "";

        // Build the file
        File fClient = new File(clientFileName);

        //Check if the file exists.
        if (!(fClient.exists())) {
            String err = "' " + clientFileName + "' was not found.";
            throw new ClientContainerDeploymentDescException(err);
        }

        //Check if the Alt deploymentDesc file exists.
        //But only if it's a non null value because it's optionnal.
        if ((altClientXmlFilename != null) && (!new File(altClientXmlFilename).exists())) {
            String err = "The file for the altdd tag for the EAR case '" + altClientXmlFilename + "' was not found.";
            throw new ClientContainerDeploymentDescException(err);
        }

        // load the application-client deployment descriptor data
        // (META-INF/application-client.xml
        // and META-INF/jonas-client.xml)
        //No alt-dd case
        if (altClientXmlFilename == null) {
            try {
                clientFile = new JarFile(clientFileName);

                //Lookup in the JAR
                //Check the client entry
                applicationClientZipEntry = clientFile.getEntry(CLIENT_FILE_NAME);
                if (applicationClientZipEntry == null) {
                    throw new ClientContainerDeploymentDescException("The entry '" + CLIENT_FILE_NAME
                            + "' was not found in the file '" + clientFileName + "'.");
                }
                //Get the stream
                applicationClientInputStream = clientFile.getInputStream(applicationClientZipEntry);
                xmlContent = xmlContent(applicationClientInputStream);
                // necessary to have a not empty InputStream !!!
                applicationClientInputStream = clientFile.getInputStream(applicationClientZipEntry);
            } catch (Exception e) {
                if (clientFile != null) {
                    try {
                        clientFile.close();
                    } catch (IOException ioe) {
                        //We can't close the file
                    }
                }
                throw new ClientContainerDeploymentDescException(
                        "Can not read the XML deployment descriptors of the client jar file '" + clientFileName + "'.",
                        e);
            }
        } else {
            try {
                applicationClientInputStream = new FileInputStream(altClientXmlFilename);
                xmlContent = xmlContent(applicationClientInputStream);
                // necessary to have a not empty InputStream !!!
                applicationClientInputStream = new FileInputStream(altClientXmlFilename);
            } catch (FileNotFoundException ioe) {
                throw new ClientContainerDeploymentDescException("The altDD file '" + altClientXmlFilename
                        + "' was not found.");
            } catch (Exception e) {
                if (applicationClientInputStream != null) {
                    try {
                        applicationClientInputStream.close();
                    } catch (IOException ioe) {
                        // Can't close the file
                    }
                }
                throw new ClientContainerDeploymentDescException("Cannot read the XML deployment descriptors of the client jar file '"
                        + clientFileName + "'.", e);
            }
        }

        applicationClient = loadApplicationClient(new InputStreamReader(applicationClientInputStream), CLIENT_FILE_NAME);

        try {
            clientFile = new JarFile(clientFileName);

            // Lookup in the JAR
            // Check the client entry
            jonasClientZipEntry = clientFile.getEntry(JONAS_CLIENT_FILE_NAME);
            if (jonasClientZipEntry != null) {
                //Get the stream
                jonasClientInputStream = clientFile.getInputStream(jonasClientZipEntry);
                jonasXmlContent = xmlContent(jonasClientInputStream);
                // necessary to have a not empty InputStream !!!
                jonasClientInputStream = clientFile.getInputStream(jonasClientZipEntry);
            }
        } catch (Exception e) {
            if (clientFile != null) {
                try {
                    clientFile.close();
                } catch (IOException ioe) {
                    //We can't close the file
                }
            }
            throw new ClientContainerDeploymentDescException(
                    "Can not read the XML deployment descriptors of the client jar file '" + clientFileName + "'.", e);
        }

        // load jonas-client deployment descriptor data
        // (META-INF/jonas-client.xml)
        if (jonasClientInputStream != null) {
            jonasClient = loadJonasClient(new InputStreamReader(jonasClientInputStream), JONAS_CLIENT_FILE_NAME);
            try {
                jonasClientInputStream.close();
            } catch (IOException e) {
                // Nothing to do
            }
        } else {
            jonasClient = new JonasClient();
        }

        // instantiate client deployment descriptor
        ClientContainerDeploymentDesc clientDD = new ClientContainerDeploymentDesc(classLoaderForCls, applicationClient, jonasClient);
        clientDD.setXmlContent(xmlContent);
        clientDD.setJOnASXmlContent(jonasXmlContent);
        return clientDD;
    }

    /**
     * Load the application-client.xml file.
     * @param reader the reader of the XML file.
     * @param fileName the name of the file (application-client.xml).
     * @return a structure containing the result of the application-client.xml
     *         parsing.
     * @throws DeploymentDescException if the deployment descriptor is
     *         corrupted.
     */
    public static ApplicationClient loadApplicationClient(Reader reader, String fileName)
            throws DeploymentDescException {

        ApplicationClient appc = new ApplicationClient();

        // Create if null
        if (appClientDigester == null) {
            // Create and initialize the digester
            appClientDigester = new JDigester(appClientRuleSet, getParsingWithValidation(), true, new AppClientDTDs(),
                    new AppClientSchemas());
        }

        try {
            appClientDigester.parse(reader, fileName, appc);
        } catch (DeploymentDescException e) {
            throw e;
        } finally {
            appClientDigester.push(null);
        }
        return appc;
    }

    /**
     * Load the jonas-client.xml file.
     * @param reader the stream of the XML file.
     * @param fileName the name of the file (jonas-client.xml).
     * @return a structure containing the result of the jonas-client.xml
     *         parsing.
     * @throws DeploymentDescException if the deployment descriptor is
     *         corrupted.
     */
    public static JonasClient loadJonasClient(Reader reader, String fileName) throws DeploymentDescException {

        JonasClient jc = new JonasClient();

        // Create if null
        if (jonasAppClientDigester == null) {
            jonasAppClientDigester = new JDigester(jonasAppClientRuleSet, getParsingWithValidation(), true,
                    new JonasAppClientDTDs(), new JonasAppClientSchemas());
        }

        try {
            jonasAppClientDigester.parse(reader, fileName, jc);

        } catch (DeploymentDescException e) {
            throw e;
        } finally {
            jonasAppClientDigester.push(null);
        }
        return jc;
    }

    /**
     * Return the JNDI name from the ejbLink string. ejbLink format :
     * filename.jar#beanName in the same Ear File
     * @param clientURL the url of the jar being parsed. This is needed because
     *        ejbLink is relative. With the url and the ejbLink, we can know
     *        where the file is locate.
     * @param ejbLink the ejbLink tag of an ejb-ref.
     * @param earLoader the classloader of the ear.
     * @param ejbType the type of the referenced ejb in the ejb-ref tag.
     * @return the JNDI name if found, null otherwise
     * @throws DeploymentDescException when it failed
     */
    private String getJndiName(URL clientURL, String ejbLink, ClassLoader earLoader, String ejbType)
            throws DeploymentDescException {
        // Now ask EJB deployment Desc manager
        // Last arg is always true as it is always ejb ref and not local ref from a client
        return ejbDDManager.getJndiName(clientURL, ejbLink, earLoader, ejbType, null, true);
    }

    /**
     * Make a cleanup of the cache of deployment descriptor. This method must
     * Return the JNDI name from the mdLink string. mdLink format :
     * filename.jar#mdName in the same Ear File
     * @param clientURL the url of the jar being parsed. This is needed because
     *        mdLink is relative. With the url and the mdLink, we can know where
     *        the file is locate.
     * @param mdLink the mdLink tag of a message-destination-ref
     * @param mdType the type of the referenced mdb in the
     *        message-destination-ref tag.
     * @param mdUsage the usage of the referenced mdb in the
     *        message-destination-ref tag.
     * @param earLoader the classloader of the ear.
     * @return the JNDI name if found, null otherwise
     * @throws ClientContainerDeploymentDescException when it failed
     */
    private String getMDJndiName(URL clientURL, String mdLink, String mdType, String mdUsage, ClassLoader earLoader)
            throws ClientContainerDeploymentDescException {

        // Extract from the mdb link
        //   - the name of the file
        //   - the name of the destination
        String ejbJarLink = null;
        String destNameLink = null;
        DeploymentDesc dd = null;

        // Check the format of the ejb-link. It must contains .jar#
        if (mdLink.toLowerCase().indexOf(".jar#") == -1) {
            String err = "Message-destination-link " + mdLink
                    + " has a bad format. Correct format :  filename.jar#messageDestinationName";
            throw new ClientContainerDeploymentDescException(err);
        }

        StringTokenizer st = new StringTokenizer(mdLink, LINK_SEPARATOR);

        // We must have only two elements after this step, one for the fileName
        // before the # and the name of the message-destination after the # char
        if (st.countTokens() != 2 || mdLink.startsWith(LINK_SEPARATOR) || mdLink.endsWith(LINK_SEPARATOR)) {

            String err = "Message-destination-link " + mdLink
                    + " has a bad format. Correct format :  filename.jar#messageDestinationName.";
            throw new ClientContainerDeploymentDescException(err);
        }

        //Get the token
        ejbJarLink = st.nextToken();
        destNameLink = st.nextToken();

        //Check if ejbJarLink is a jar or not
        if (!ejbJarLink.endsWith(".jar")) {
            String err = "Ejbjar filename " + ejbJarLink + " from the message-destination-link " + mdLink
                    + " has a bad format. Correct format :  filename.jar";
            throw new ClientContainerDeploymentDescException(err);
        }

        // Now construct the URL from the absolute path from the url clientURL
        // and
        // the relative path from ejbJarLink
        URL ejbJarLinkUrl = null;
        try {
            ejbJarLinkUrl = new File(new File(clientURL.getFile()).getParent() + File.separator + ejbJarLink)
                    .getCanonicalFile().toURL();
        } catch (MalformedURLException mue) {
            String err = "Error when creating an url for the ejb jar filename. Error :" + mue.getMessage();
            throw new ClientContainerDeploymentDescException(err);
        } catch (IOException ioe) {
            String err = "Error when creating/accessing a file. Error :" + ioe.getMessage();
            throw new ClientContainerDeploymentDescException(err);
        }

        // Check if the jar exist.
        if (!new File(ejbJarLinkUrl.getFile()).exists()) {
            String err = "Cannot get the deployment descriptor for '" + ejbJarLinkUrl.getFile()
                    + "'. The file doesn't exist.";
            throw new ClientContainerDeploymentDescException(err);
        }

        // We've got the url
        //   Now, We can ask the Deployment Descriptor of this url
        URL[] ddURL = new URL[1];
        ddURL[0] = ejbJarLinkUrl;
        URLClassLoader loaderForClsEjb = new URLClassLoader(ddURL, earLoader);
        try {
            dd = ejbDDManager.getDeploymentDesc(ejbJarLinkUrl, loaderForClsEjb, earLoader);
        } catch (DeploymentDescException e) {
            String err = "Cannot get the deployment descriptor for '" + ejbJarLinkUrl.getFile() + "'.";
            throw new ClientContainerDeploymentDescException(err, e);
        }

        JonasMessageDestination md = dd.getJonasMessageDestination(mdLink);

        if (md == null) {
            String err = "No message-destination-link was found for '" + mdLink + "' in the file "
                    + clientURL.getFile() + " specified.";
            throw new ClientContainerDeploymentDescException(err);
        }

        //Check if the type & usage of the message-destination-ref is correct.
        //For now checkTypeUsage(clientURL, mdType, mdUsage, dd);

        return md.getJndiName();
    }

    /**
     * Make a cleanup of the cache of deployment descriptor. This method must be
     * invoked after the ear deployment by the EAR service.
     * @param earClassLoader the ClassLoader of the ear application to remove
     *        from the cache.
     */
    public void removeCache(ClassLoader earClassLoader) {
        //Remove the altdd mapping
        earCLAltDDBindings.remove(earClassLoader);

        //Then remove the cache of the ejb dd manager
        ejbDDManager.removeCache(earClassLoader);
    }

    /**
     * Set the alt deployment desc which are used instead of the web.xml file
     * which is in the war file. The alt-dd tag is in the application.xml file
     * of the ear files and is used ony in the EAR case. ie : deployment of wars
     * packaged into EAR applications. alt-dd tag is optionnal
     * @param earClassLoader the ear classloader which is used for mapped the
     *        URLs of the wars to the Alt dd.
     * @param urls the urls of the wars
     * @param altDDs the alt-dd name for the specified war URLs
     */
    public void setAltDD(ClassLoader earClassLoader, URL[] urls, URL[] altDDs) {

        //Associate an url to a altDD url
        Hashtable urlAltddBindings = new Hashtable();

        //Fill the hashtable for each url
        for (int i = 0; i < urls.length; i++) {
            if (altDDs[i] != null) {
                urlAltddBindings.put(urls[i], altDDs[i]);
            }
        }

        //Bind the hashtable
        earCLAltDDBindings.put(earClassLoader, urlAltddBindings);

    }

    /**
     * Get the size of the cache (number of entries in the cache). This method
     * is used only for the tests.
     * @return the size of the cache (number of entries in the cache).
     */
    public int getCacheSize() {
        int bufferSize = 0;

        Enumeration keys = earCLAltDDBindings.keys();
        while (keys.hasMoreElements()) {
            ClassLoader loader = (ClassLoader) keys.nextElement();
            Hashtable hashtab = (Hashtable) earCLAltDDBindings.get(loader);
            bufferSize = bufferSize + hashtab.size();
        }

        return bufferSize;
    }

    /**
     * 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) {
        ClientDeploymentDescManager.parsingWithValidation = validation;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy