EjbDeploymentDescManager.java

00001 
00027 package org.objectweb.jonas_ejb.deployment.lib;
00028 
00029 import java.io.File;
00030 import java.io.FileInputStream;
00031 import java.io.FileNotFoundException;
00032 import java.io.IOException;
00033 import java.io.InputStream;
00034 import java.io.InputStreamReader;
00035 import java.io.Reader;
00036 import java.net.MalformedURLException;
00037 import java.net.URL;
00038 import java.net.URLClassLoader;
00039 import java.util.Enumeration;
00040 import java.util.Hashtable;
00041 import java.util.List;
00042 import java.util.StringTokenizer;
00043 import java.util.Vector;
00044 import java.util.zip.ZipEntry;
00045 import java.util.zip.ZipFile;
00046 
00047 import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
00048 import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc;
00049 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb1_1;
00050 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
00051 import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
00052 import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
00053 import org.objectweb.jonas_ejb.deployment.api.SessionDesc;
00054 import org.objectweb.jonas_ejb.deployment.rules.EjbJarRuleSet;
00055 import org.objectweb.jonas_ejb.deployment.rules.JonasEjbJarRuleSet;
00056 import org.objectweb.jonas_ejb.deployment.xml.EjbJar;
00057 import org.objectweb.jonas_ejb.deployment.xml.JonasEjbJar;
00058 import org.objectweb.jonas_ejb.lib.BeanNaming;
00059 
00060 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
00061 import org.objectweb.jonas_lib.deployment.api.EjbLocalRefDesc;
00062 import org.objectweb.jonas_lib.deployment.api.EjbRefDesc;
00063 import org.objectweb.jonas_lib.deployment.api.JndiEnvRefsGroup;
00064 import org.objectweb.jonas_lib.deployment.api.MessageDestinationRefDesc;
00065 import org.objectweb.jonas_lib.deployment.digester.JDigester;
00066 import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager;
00067 import org.objectweb.jonas_lib.deployment.xml.JonasMessageDestination;
00068 
00069 import org.objectweb.jonas_ws.deployment.api.PortComponentDesc;
00070 import org.objectweb.jonas_ws.deployment.api.PortComponentRefDesc;
00071 import org.objectweb.jonas_ws.deployment.api.ServiceRefDesc;
00072 import org.objectweb.jonas_ws.deployment.api.WSDeploymentDescException;
00073 import org.objectweb.jonas_ws.deployment.lib.WSDeploymentDescManager;
00074 
00075 import org.objectweb.jonas.common.Log;
00076 
00077 import org.objectweb.util.monolog.api.BasicLevel;
00078 import org.objectweb.util.monolog.api.Logger;
00079 
00092 public class EjbDeploymentDescManager extends AbsDeploymentDescManager {
00093 
00097     public static final String EJB_JAR_FILE_NAME = "META-INF/ejb-jar.xml";
00098 
00102     public static final String JONAS_EJB_JAR_FILE_NAME = "META-INF/jonas-ejb-jar.xml";
00103 
00107     private static boolean parsingWithValidation = true;
00108 
00112     private static EjbDeploymentDescManager unique;
00113 
00114 
00118     private static JDigester ejbjarDigester = null;
00119 
00123     private static JDigester jonasEjbjarDigester = null;
00124 
00128     private static EjbJarRuleSet ejbjarRuleSet = new EjbJarRuleSet();
00129 
00133     private static JonasEjbJarRuleSet jonasEjbjarRuleSet = new JonasEjbJarRuleSet();
00134 
00135 
00139     private WSDeploymentDescManager wsDDManager = null;
00140 
00145     private Hashtable urlJarBindings;
00146 
00150     private Hashtable urlEarCLBindings;
00151 
00155     private Hashtable urlEjbCLBindings;
00156 
00160     private Hashtable urlAltDDBindings = null;
00161 
00167     private Hashtable earCLEjbLinkJar;
00168 
00172     private static Logger logger = Log.getLogger("org.objectweb.jonas_ejb.dd");
00173 
00177     private static Hashtable staticCache = new Hashtable();
00178 
00182     private static String xmlContent = "";
00183 
00187     private static String jonasXmlContent = "";
00188 
00192     private EjbDeploymentDescManager() {
00193         urlJarBindings = new Hashtable();
00194         urlEarCLBindings = new Hashtable();
00195         urlEjbCLBindings = new Hashtable();
00196         earCLEjbLinkJar = new Hashtable();
00197         urlAltDDBindings = new Hashtable();
00198     }
00199 
00204     public static EjbDeploymentDescManager getInstance() {
00205         if (unique == null) {
00206             unique = new EjbDeploymentDescManager();
00207         }
00208         return unique;
00209     }
00210 
00220     public static DeploymentDesc getDeploymentDesc(String ejbjar, ClassLoader ejbLoader)
00221         throws DeploymentDescException {
00222         if (!staticCache.containsKey(ejbjar)) {
00223             return getDeploymentDescriptor(ejbjar, ejbLoader, (String) null);
00224         } else {
00225             return (DeploymentDesc) staticCache.get(ejbjar);
00226         }
00227     }
00228 
00242     public synchronized DeploymentDesc getDeploymentDesc(URL url,
00243                                                          ClassLoader ejbLoader,
00244                                                          ClassLoader earLoader)
00245         throws DeploymentDescException {
00246         // load an instance of the WebService Manager
00247         if (wsDDManager == null) {
00248             wsDDManager = WSDeploymentDescManager.getInstance();
00249         }
00250 
00251         // Check in the ejb-link is allowed : the ejb-link must be done
00252         // on an ejb-jar defined in the ear application.
00253         if (earLoader != null) {
00254             checkEjbLinkAvailable(earLoader, url);
00255         }
00256 
00257         DeploymentDesc dd = (DeploymentDesc) urlJarBindings.get(url.getFile());
00258         if (dd == null) {
00259             // dd not in cache => load the deployment descriptor.
00260             dd = loadDeploymentDesc(url, ejbLoader, earLoader);
00261         }
00262         return dd;
00263     }
00264 
00274     private DeploymentDesc getDeploymentDesc(URL currentUrl, URL urlToLoad)
00275         throws DeploymentDescException {
00276         DeploymentDesc ejbLinkDD = (DeploymentDesc) urlJarBindings.get(urlToLoad.getFile());
00277         if (ejbLinkDD == null) {
00278             // ejbLinkDD not in cache => load the deployment descriptor.
00279             String url = currentUrl.getFile();
00280             URLClassLoader earLoader = (URLClassLoader) urlEarCLBindings.get(url);
00281             if (new File(url).isFile()) {
00282                 if (!url.toLowerCase().endsWith(".jar")) {
00283                     String err = "File '" + url + "' is not a jar file";
00284                     throw new DeploymentDescException(err);
00285                 }
00286             }
00287 
00288             if (earLoader != null) {
00289                 // In the case of an ear application.
00290 
00291                 // Check in the ejb-link is allowed : the ejb-link must be done
00292                 // on an ejb-jar defined in the ear application.
00293                 checkEjbLinkAvailable(earLoader, urlToLoad);
00294 
00295                 // get the loader for classes (ejb classloader).
00296                 URLClassLoader loaderForCls = (URLClassLoader) urlEjbCLBindings.get(url);
00297 
00298                 // Build a default classloader
00299                 if (loaderForCls == null) {
00300                     loaderForCls = new URLClassLoader(new URL[] {urlToLoad});
00301                 }
00302 
00303                 // get the ear classloader.
00304                 URLClassLoader loader = (URLClassLoader) urlEarCLBindings.get(url);
00305                 ejbLinkDD = loadDeploymentDesc(urlToLoad, loaderForCls, loader);
00306             } else {
00307                 // In the case of a non ear application.
00308                 if (!currentUrl.getFile().equals(urlToLoad)) {
00309                     String err = "In '" + url + "' ejb-link is not allowed outside the ejb-jar if you are not in an ear application.";
00310                     throw new DeploymentDescException(err);
00311                 }
00312                 // else nothing to do.
00313             }
00314         }
00315         return ejbLinkDD;
00316     }
00317 
00329     private DeploymentDesc loadDeploymentDesc(URL url, ClassLoader ejbLoader, ClassLoader earLoader)
00330         throws DeploymentDescException {
00331         // Check if the ejb-jar exists.
00332         String filename = url.getFile();
00333         File f = new File(filename);
00334         if (!f.exists()) {
00335             throw new DeploymentDescException(filename + " not found");
00336         }
00337 
00338         // Get the instance of the DeploymentDesc.
00339         DeploymentDesc dd = null;
00340         if (f.isDirectory()) {
00341             dd = getDeploymentDescriptor(filename + EJB_JAR_FILE_NAME,
00342                                          BeanNaming.getJonasXmlName(filename + EJB_JAR_FILE_NAME),
00343                                          ejbLoader,
00344                                          f.getAbsolutePath());
00345 
00346         } else if (filename.toLowerCase().endsWith(".xml")) {
00347             // This is an XML file name: Treat it for upward compatibility
00348             // f is the ejb-jar.xml file, jonas specific is colocated to this file.
00349             File parent = f.getParentFile();
00350             dd = getDeploymentDescriptor(filename,
00351                                          BeanNaming.getJonasXmlName(filename),
00352                                          ejbLoader,
00353                                          parent.getAbsolutePath());
00354         } else {
00355             // This is an ejb-jar
00356             // Check if there is an altenate DD for this URL (ear only)
00357             String altname = null;
00358             URL altDDUrl = (URL) urlAltDDBindings.get(url.getFile());
00359             if (altDDUrl != null) {
00360                 altname = altDDUrl.getFile();
00361             }
00362             dd = getDeploymentDescriptor(filename, ejbLoader, altname);
00363         }
00364 
00365         // Put it in the cache in case of ear.
00366         if (earLoader != null) {
00367             urlEjbCLBindings.put(filename, ejbLoader);
00368             urlEarCLBindings.put(filename, earLoader);
00369         }
00370 
00371         BeanDesc[] bd = dd.getBeanDesc();
00372         for (int j = 0; j < bd.length; j++) {
00373 
00374             // Resolve the ejb-link for ejb-ref
00375             EjbRefDesc[] ejbRef = bd[j].getEjbRefDesc();
00376             for (int i = 0; i < ejbRef.length; i++) {
00377                 String jndiName = ejbRef[i].getJndiName();
00378                 String ejbLink = ejbRef[i].getEjbLink();
00379                 String ejbRefType = ejbRef[i].getEjbRefType();
00380                 if (ejbLink != null && jndiName == null) {
00381                     String ejbName = getJndiName(url, ejbLink, earLoader, ejbRefType, dd, true);
00382                     ejbRef[i].setJndiName(ejbName);
00383                 }
00384             }
00385 
00386             // Resolve the ejb-link for ejb-local-ref
00387             EjbLocalRefDesc[] ejbLocalRef = bd[j].getEjbLocalRefDesc();
00388             for (int i = 0; i < ejbLocalRef.length; i++) {
00389                 String ejblink = ejbLocalRef[i].getEjbLink();
00390                 if (ejblink == null) {
00391                     String err = "Ejb-link must be specified for ejb-local-ref " + ejbLocalRef[i].getEjbRefName();
00392                     throw new DeploymentDescException(err);
00393                 }
00394                 String ejbRefType = ejbLocalRef[i].getEjbRefType();
00395                 String ejbName = getJndiName(url, ejblink, earLoader, ejbRefType, dd, false);
00396                 ejbLocalRef[i].setJndiLocalName(ejbName);
00397             }
00398 
00399             // Resolve the port-component-link for service-ref
00400             ServiceRefDesc[] serviceRef = bd[j].getServiceRefDesc();
00401 
00402             for (int i = 0; i < serviceRef.length; i++) {
00403                 List pcRefs = serviceRef[i].getPortComponentRefs();
00404 
00405                 for (int k = 0; k < pcRefs.size(); k++) {
00406                     // for each service portComponents : resolve links
00407                     PortComponentRefDesc pcr = (PortComponentRefDesc) pcRefs.get(k);
00408                     String pclink = pcr.getPortComponentLink();
00409                     if (pclink != null) {
00410                         // a pc link is defined, we resolve it
00411                         PortComponentDesc pcDesc = getPCDesc(url, pclink, ejbLoader, earLoader);
00412                         pcr.setPortComponentDesc(pcDesc);
00413                     }
00414                 }
00415             }
00416 
00417             // Resolve the message-destination-link for message-destination-ref
00418             MessageDestinationRefDesc[] mdRef = bd[j].getMessageDestinationRefDesc();
00419             for (int i = 0; i < mdRef.length; i++) {
00420                 String jndiName = mdRef[i].getJndiName();
00421                 String mdLink = mdRef[i].getMessageDestinationLink();
00422                 String mdType = mdRef[i].getMessageDestinationType();
00423                 String mdUsage = mdRef[i].getMessageDestinationUsage();
00424                 logger.log(BasicLevel.DEBUG, "" + jndiName + " " + mdLink + " " + mdType + " " + mdUsage);
00425                 if (mdLink != null && jndiName == null) {
00426                     String mdName = getMDJndiName(url, mdLink, mdType, mdUsage, dd);
00427                     mdRef[i].setJndiName(mdName);
00428                 }
00429             }
00430 
00431         }
00432 
00433         // ... and put it in cache if ear case.
00434         if (earLoader != null) {
00435             // case of ear application.
00436             urlJarBindings.put(filename, dd);
00437         }
00438 
00439         return dd;
00440     }
00441 
00442 
00459     private PortComponentDesc getPCDesc(URL ejbjarURL,
00460                                         String pcLink,
00461                                         ClassLoader moduleLoader,
00462                                         ClassLoader earLoader)
00463         throws WSDeploymentDescException {
00464 
00465         // now ask WS Manager for port-component-desc
00466         return wsDDManager.getPortComponentDesc(ejbjarURL, pcLink, moduleLoader, earLoader);
00467     }
00468 
00469 
00485     public String getJndiName(URL currentFile, String ejbLink, ClassLoader earCl, String ejbType,
00486                                DeploymentDesc deploymentDesc, boolean isEjbRef)
00487         throws DeploymentDescException {
00488         // Extract from the ejb link
00489         //   - the name of the file
00490         //   - the name of the bean
00491         String ejbJarLink = null;
00492         String beanNameLink = null;
00493 
00494         //Same jar ?
00495         if (ejbLink.indexOf(LINK_SEPARATOR) == -1) {
00496             BeanDesc bd = null;
00497             //Link to a bean inside the same ejb-jar file.
00498             if (earCl == null && deploymentDesc == null) {
00499                     throw new DeploymentDescException("Deployment desc for file ejb-jar '" + currentFile.getFile() + "' not found");
00500             }
00501             // Read in its own deployment descriptor if not null
00502             if (deploymentDesc != null) {
00503                 bd =  deploymentDesc.getBeanDesc(ejbLink);
00504             }
00505             String url = currentFile.getFile();
00506             URLClassLoader earClassLoader = null;
00507             // get the loader for classes (ejb classloader).
00508             URLClassLoader ejbLoader = (URLClassLoader) urlEjbCLBindings.get(url);
00509             if (earCl != null) {
00510                 earClassLoader = (URLClassLoader) earCl;
00511                 //Add it
00512                 urlEarCLBindings.put(url, earCl);
00513             } else {
00514                 earClassLoader = (URLClassLoader) urlEarCLBindings.get(url);
00515             }
00516 
00517             //ejb standalone case
00518             if ((earClassLoader == null) && (bd == null)) {
00519                 String err = "Ejb-link " + ejbLink + " not found inside the file " + currentFile.getFile() + ". The bean doesn't exists.";
00520                 throw new DeploymentDescException(err);
00521             }
00522 
00523             // ear case, search in all ejbjars
00524             if (bd == null) {
00525                 logger.log(BasicLevel.DEBUG, "The bean '" + ejbLink + "' was not found in the current ejbjar, searching on all the ejbjars.");
00526                 Vector v = (Vector) earCLEjbLinkJar.get(earClassLoader);
00527                 DeploymentDesc lookupDD = null;
00528                 String fileName = null;
00529                 URL urlRead = null;
00530                 String urlReadString = null;
00531                 boolean found = false;
00532                 BeanDesc bdtmp = null;
00533                 for (Enumeration e = v.elements(); e.hasMoreElements();) {
00534                     urlReadString = (String) e.nextElement();
00535                     File f = new File(urlReadString);
00536                     try {
00537                         urlRead = f.toURL();
00538                     } catch (Exception ue) {
00539                         throw new DeploymentDescException("Cannot make an url with the argument'" + urlReadString + "'.");
00540                     }
00541                     // Classloader is null ? try to get it
00542                     if (ejbLoader == null) {
00543                         ejbLoader = (URLClassLoader) urlEjbCLBindings.get(urlReadString);
00544                     }
00545                     // if it is still null, fails
00546                     if (ejbLoader == null) {
00547                         throw new DeploymentDescException("Error while resolving ejb-link. The ejb classloader is not found for url '" + urlReadString + "'.");
00548                     }
00549 
00550                     // Add it
00551                     urlEjbCLBindings.put(urlReadString, ejbLoader);
00552 
00553                     fileName = urlRead.getFile();
00554                     //do not analyse current file
00555                     if (!fileName.equals(url)) {
00556                         //Need to load deployment desc without any resolving link
00557                         // Get the instance of the DeploymentDesc.
00558                         if (f.isDirectory()) {
00559                             lookupDD = getDeploymentDescriptor(fileName + EJB_JAR_FILE_NAME,
00560                                                                BeanNaming.getJonasXmlName(fileName + EJB_JAR_FILE_NAME),
00561                                                                ejbLoader,
00562                                                                f.getAbsolutePath());
00563                         } else if (fileName.toLowerCase().endsWith(".xml")) {
00564                             // This is an XML file name: Treat it for upward compatibility
00565                             // f is the ejb-jar.xml file, first paretn is the META-INF directory, and second parent is the root directory of the module
00566                             File parent = f.getParentFile().getParentFile();
00567                             lookupDD = getDeploymentDescriptor(fileName,
00568                                                                BeanNaming.getJonasXmlName(fileName),
00569                                                                ejbLoader,
00570                                                                parent.getAbsolutePath());
00571                         } else {
00572                             // This is an ejb-jar
00573                             // Check if there is an altenate DD for this URL (ear only)
00574                             String altname = null;
00575                             URL altDDUrl = (URL) urlAltDDBindings.get(url);
00576                             if (altDDUrl != null) {
00577                                 altname = altDDUrl.getFile();
00578                             }
00579                             lookupDD = getDeploymentDescriptor(fileName,
00580                                                                ejbLoader,
00581                                                                altname);
00582                         }
00583 
00584                         if (lookupDD != null) {
00585                             bdtmp = lookupDD.getBeanDesc(ejbLink);
00586                             if (bdtmp != null) {
00587                                 logger.log(BasicLevel.DEBUG, "Found a BeanDesc in the Deployment Desc." + urlRead);
00588                                 //ejblink was found ?
00589                                 if (found) {
00590                                     String err = "There are more than one bean with the name '" + ejbLink + "' which were found in all the ejbjars of this EAR.";
00591                                     throw new DeploymentDescException(err);
00592                                 } else {
00593                                     found = true;
00594                                     bd = bdtmp;
00595                                 }
00596                             } else {
00597                                 logger.log(BasicLevel.DEBUG, "No BeanDesc found in the Deployment Desc." + urlRead);
00598                             }
00599                         }
00600                     }
00601                 }
00602                 if (!found) {
00603                     String err = "No ejblink was found for '" + ejbLink + "' in all the ejbjars of this EAR.";
00604                     throw new DeploymentDescException(err);
00605                 }
00606             }
00607 
00608             logger.log(BasicLevel.DEBUG, "BeanDesc found = " + bd.getEjbName());
00609             //Check if the type of the ejb-ref is correct.
00610             checkType(currentFile, ejbType, bd);
00611 
00612             if (bd == null) {
00613                 String err = "Ejb-link " + ejbLink + " not found inside the file " + currentFile.getFile() + ". The bean doesn't exists.";
00614                 throw new DeploymentDescException(err);
00615             }
00616 
00617             String jndiname;
00618             if (isEjbRef) {
00619                 jndiname = bd.getJndiName();
00620             } else {
00621                 jndiname = bd.getJndiLocalName();
00622             }
00623             return jndiname;
00624         }
00625 
00626         if (earCl != null) {
00627             String url = currentFile.getFile();
00628             //Add it
00629             urlEarCLBindings.put(url, earCl);
00630         }
00631 
00632         //Ejb-link not in the same ejb-jar file.
00633         StringTokenizer st = new StringTokenizer(ejbLink, LINK_SEPARATOR);
00634 
00635         // We must have only two elements after this step, one for the fileName
00636         // before the # and the name of the bean after the # char
00637         if (st.countTokens() != 2 || ejbLink.startsWith(LINK_SEPARATOR)
00638             || ejbLink.endsWith(LINK_SEPARATOR)) {
00639 
00640             String err = "Ejb link " + ejbLink + " has a bad format. Correct format :  filename.jar#beanName.";
00641             throw new DeploymentDescException(err);
00642         }
00643 
00644         //Get the token
00645         ejbJarLink = st.nextToken();
00646         beanNameLink = st.nextToken();
00647 
00648         //Check if ejbJarLink is a jar or not
00649         if (!ejbJarLink.endsWith(".jar")) {
00650             String err = "Ejbjar filename " + ejbJarLink + " from the ejb-link " + ejbLink + " has a bad format. Correct format :  filename.jar";
00651             throw new DeploymentDescException(err);
00652         }
00653 
00654 
00655         // Now construct the URL from the absolute path from the url ejbJar and
00656         // the relative path from ejbJarLink
00657         URL ejbJarLinkUrl = null;
00658         try {
00659             ejbJarLinkUrl = new File(new File(currentFile.getFile()).getParent() + File.separator + ejbJarLink).getCanonicalFile().toURL();
00660         } catch (MalformedURLException mue) {
00661             String err = "Error when creating an url for the ejb jar filename. Error :" + mue.getMessage();
00662             throw new DeploymentDescException(err);
00663         } catch (IOException ioe) {
00664             String err = "Error when creating/accessing a file. Error :" + ioe.getMessage();
00665             throw new DeploymentDescException(err);
00666         }
00667 
00668         // We've got the url
00669         BeanDesc bd = null;
00670         // The ejb-link with .jar#beanName could reference the current jar file
00671         if (currentFile.getPath().equalsIgnoreCase(ejbJarLinkUrl.getPath())) {
00672             logger.log(BasicLevel.DEBUG, "ejblink jar#bean reference our current file");
00673 
00674             // Read in its own deployment descriptor if not null
00675             if (deploymentDesc != null) {
00676                 bd =  deploymentDesc.getBeanDesc(beanNameLink);
00677             } else {
00678                 logger.log(BasicLevel.DEBUG, "DD = null, cannot return bean in the current DD");
00679             }
00680 
00681         } else {
00682             //Another file :
00683 
00684             // Now, We can ask the Deployment Descriptor of this url
00685             DeploymentDesc dd = getDeploymentDesc(currentFile, ejbJarLinkUrl);
00686 
00687             // JndiName resolve.
00688             bd = dd.getBeanDesc(beanNameLink);
00689         }
00690 
00691         if (bd == null) {
00692             String err = "Ejb-link " + ejbLink + " not found inside the file " + currentFile.getFile() + ". The bean doesn't exists";
00693             throw new DeploymentDescException(err);
00694         }
00695 
00696         //Check if the type of the ejb-ref is correct.
00697         checkType(currentFile, ejbType, bd);
00698 
00699         String jndiname;
00700         if (isEjbRef) {
00701             jndiname = bd.getJndiName();
00702         } else {
00703             jndiname = bd.getJndiLocalName();
00704         }
00705         return jndiname;
00706     }
00707 
00722     private String getMDJndiName(URL ejbJar, String mdLink, String mdType, String mdUsage,
00723                                  DeploymentDesc deploymentDesc)
00724         throws DeploymentDescException {
00725 
00726         logger.log(BasicLevel.DEBUG, "" + ejbJar + " " + mdLink + " " + mdType + " " + mdUsage);
00727         // Extract from the mdb link
00728         //   - the name of the file
00729         //   - the name of the destination
00730         String ejbJarLink = null;
00731         String destNameLink = null;
00732         DeploymentDesc dd = deploymentDesc;
00733 
00734         //Different jar ?
00735         if (mdLink.indexOf(LINK_SEPARATOR) != -1) {
00736             //Message-destination-link not in the same ejb-jar file.
00737             StringTokenizer st = new StringTokenizer(mdLink, LINK_SEPARATOR);
00738 
00739             // We must have only two elements after this step, one for the fileName
00740             // before the # and the name of the message-destination after the # char
00741             if (st.countTokens() != 2 || mdLink.startsWith(LINK_SEPARATOR)
00742                 || mdLink.endsWith(LINK_SEPARATOR)) {
00743 
00744                 String err = "Message-destination-link " + mdLink + " has a bad format. Correct format :  filename.jar#messageDestinationName.";
00745                 throw new DeploymentDescException(err);
00746             }
00747 
00748             //Get the token
00749             ejbJarLink = st.nextToken();
00750             destNameLink = st.nextToken();
00751 
00752             //Check if ejbJarLink is a jar or not
00753             if (!ejbJarLink.endsWith(".jar")) {
00754                 String err = "Ejbjar filename " + ejbJarLink + " from the message-destination-link " + mdLink + " has a bad format. Correct format :  filename.jar";
00755                 throw new DeploymentDescException(err);
00756             }
00757 
00758 
00759             // Now construct the URL from the absolute path from the url ejbJar and
00760             // the relative path from ejbJarLink
00761             URL ejbJarLinkUrl = null;
00762             try {
00763                 ejbJarLinkUrl = new File(new File(ejbJar.getFile()).getParent() + File.separator + ejbJarLink).getCanonicalFile().toURL();
00764             } catch (MalformedURLException mue) {
00765                 String err = "Error when creating an url for the ejb jar filename. Error :" + mue.getMessage();
00766                 throw new DeploymentDescException(err);
00767             } catch (IOException ioe) {
00768                 String err = "Error when creating/accessing a file. Error :" + ioe.getMessage();
00769                 throw new DeploymentDescException(err);
00770             }
00771 
00772             // Check if the jar exist.
00773             if (!new File(ejbJarLinkUrl.getFile()).exists()) {
00774                 String err = "Cannot get the deployment descriptor for '" + ejbJarLinkUrl.getFile() + "'. The file doesn't exist.";
00775                 throw new DeploymentDescException(err);
00776             }
00777 
00778             // We've got the url
00779             // Now, We can ask the Deployment Descriptor of this url
00780             dd = getDeploymentDesc(ejbJar, ejbJarLinkUrl);
00781         }
00782 
00783         //Link to a destination inside the same ejb-jar file.
00784         if (dd == null) {
00785             throw new DeploymentDescException("Deployment desc for file ejb-jar '" + ejbJar.getFile() + "' not found");
00786         }
00787 
00788         boolean foundMd = dd.getMessageDestination(mdLink);
00789         if (!foundMd) {
00790             String err = "No message-destination was found for '" + mdLink + "' in the ejbjar specified.";
00791             throw new DeploymentDescException(err);
00792         }
00793 
00794         JonasMessageDestination md = dd.getJonasMessageDestination(mdLink);
00795 
00796         if (md == null) {
00797             String err = "No jonas-message-destination was found for '" + mdLink + "' in the ejbjar specified.";
00798             throw new DeploymentDescException(err);
00799         }
00800 
00801         logger.log(BasicLevel.DEBUG, "Message-destination found = " + md.getJndiName());
00802 
00803         //Check if the type & usage of the message-destination-ref is correct.
00804         //checkTypeUsage(ejbJar, mdType, mdUsage, mdd);
00805 
00806         return md.getJndiName();
00807 
00808     }
00809 
00816     private void checkEjbLinkAvailable(ClassLoader earClassLoader,
00817                                        URL url)
00818         throws DeploymentDescException {
00819 
00820         Vector v = (Vector) earCLEjbLinkJar.get(earClassLoader);
00821 
00822         if (v != null) {
00823             if (!v.contains(url.getFile())) {
00824                 String err = "The ejb-link or message-destination-link of '" + url.getFile() + "' must be done on an ejb-jar defined in the ear application (application.xml <module><ejb>###</ejb></module>)";
00825                 throw new DeploymentDescException(err);
00826             }
00827         } else {
00828             String err = "setAvailableEjbLinkJar was badly called.";
00829             throw new DeploymentDescException(err);
00830         }
00831     }
00832 
00841     public void setAvailableEjbJarsAndAltDDs(ClassLoader earClassLoader,
00842                                              URL[] urls,
00843                                              URL[] altDDs) {
00844         Vector v = new Vector();
00845         for (int i = 0; i < urls.length; i++) {
00846             v.addElement(urls[i].getFile());
00847             if (altDDs[i] != null) {
00848                 urlAltDDBindings.put(urls[i].getFile(), altDDs[i]);
00849             }
00850         }
00851         earCLEjbLinkJar.put(earClassLoader, v);
00852     }
00853 
00860     public void removeCache(ClassLoader earClassLoader) {
00861         Vector v = (Vector) earCLEjbLinkJar.remove(earClassLoader);
00862         if (v != null) {
00863             for (int i = 0; i < v.size(); i++) {
00864                 String url = (String) v.elementAt(i);
00865                 urlJarBindings.remove(url);
00866                 urlEarCLBindings.remove(url);
00867                 urlEjbCLBindings.remove(url);
00868                 urlAltDDBindings.remove(url);
00869             }
00870         }
00871 
00872         if (earCLEjbLinkJar.size() != 0
00873             || urlJarBindings.size() != 0
00874             || urlEarCLBindings.size() != 0
00875             || urlAltDDBindings.size() != 0
00876             || urlEjbCLBindings.size() != 0) {
00877 
00878             String buffer = earCLEjbLinkJar.size() + " ";
00879             buffer += urlJarBindings.size() + " ";
00880             buffer += urlEarCLBindings.size() + " ";
00881             buffer += urlEjbCLBindings.size() + " ";
00882             buffer += urlAltDDBindings.size();
00883 
00884             logger.log(BasicLevel.DEBUG, buffer + " there are some elements in cache");
00885         }
00886     }
00887 
00893     public int getCacheSize() {
00894         return earCLEjbLinkJar.size() + urlJarBindings.size()
00895             + urlEarCLBindings.size() + urlEjbCLBindings.size()
00896             + urlAltDDBindings.size();
00897     }
00898 
00903     public String toString() {
00904         return earCLEjbLinkJar.size() + " " + urlJarBindings.size() + " "
00905             + urlEarCLBindings.size() + " " + urlEjbCLBindings.size() + " "
00906             + urlAltDDBindings.size();
00907     }
00908 
00920     public static DeploymentDesc getDeploymentDesc(String ejbJarXmlFileName,
00921                                                    String jonasEjbJarXmlFileName,
00922                                                    String jarFileName)
00923         throws DeploymentDescException {
00924         // instantiate deployment descriptor
00925         ClassLoader cl = DeploymentDesc.class.getClassLoader();
00926         if (cl == null) {
00927             cl = Thread.currentThread().getContextClassLoader();
00928         }
00929         return getDeploymentDescriptor(ejbJarXmlFileName, jonasEjbJarXmlFileName, cl, jarFileName);
00930     }
00931 
00943     private static DeploymentDesc getDeploymentDescriptor(String ejbJarXmlFileName,
00944                                                           String jonasEjbJarXmlFileName,
00945                                                           ClassLoader cl,
00946                                                           String moduleDirName)
00947         throws DeploymentDescException {
00948 
00949         InputStream is;
00950 
00951         // load deployment descriptor data
00952         try {
00953             is = new FileInputStream(ejbJarXmlFileName);
00954             // store file content in a String
00955             xmlContent = xmlContent(is);
00956             // reposition to the begining of the stream
00957             is = new FileInputStream(ejbJarXmlFileName);
00958         } catch (FileNotFoundException e) {
00959             throw new DeploymentDescException(ejbJarXmlFileName + " file not found");
00960         } catch (IOException ioe) {
00961             throw new DeploymentDescException("Cannot read the content of the xml file " + ejbJarXmlFileName);
00962         }
00963         EjbJar ejbJar = loadEjbJar(new InputStreamReader(is), ejbJarXmlFileName);
00964         String dtdversion = ejbJar.getVersion();
00965         try {
00966             is.close();
00967         } catch (IOException e) {
00968             logger.log(BasicLevel.WARN, "Can't close '" + ejbJarXmlFileName + "'");
00969         }
00970 
00971         // load jonas deployment descriptor data
00972         try {
00973             is = new FileInputStream(jonasEjbJarXmlFileName);
00974             // store file content in a String
00975             jonasXmlContent = xmlContent(is);
00976             // reposition to the begining of the stream
00977             is = new FileInputStream(jonasEjbJarXmlFileName);
00978         } catch (FileNotFoundException e) {
00979             throw new DeploymentDescException(jonasEjbJarXmlFileName + " file not found");
00980         } catch (IOException ioe) {
00981             throw new DeploymentDescException("Cannot read the content of the xml file " + ejbJarXmlFileName);
00982         }
00983 
00984         JonasEjbJar jonasEjbJar = loadJonasEjbJar(new InputStreamReader(is),
00985                                                   jonasEjbJarXmlFileName);
00986         try {
00987             is.close();
00988         } catch (IOException e) {
00989             logger.log(BasicLevel.WARN, "Can't close '" + jonasEjbJarXmlFileName + "'");
00990         }
00991 
00992         // instantiate deployment descriptor
00993         DeploymentDesc descEjb = null;
00994         if (dtdversion.equals("1.1")) {
00995             descEjb = new DeploymentDescEjb1_1(cl, ejbJar, jonasEjbJar, logger, moduleDirName);
00996         } else {
00997             descEjb = new DeploymentDescEjb2(cl, ejbJar, jonasEjbJar, logger, moduleDirName);
00998         }
00999         descEjb.setXmlContent(xmlContent);
01000         descEjb.setJOnASXmlContent(jonasXmlContent);
01001         return descEjb;
01002     }
01003 
01004 
01015     private static DeploymentDesc getDeploymentDescriptor(String ejbJarFileName,
01016                                                           ClassLoader cl,
01017                                                           String altWebXmlFilename)
01018         throws DeploymentDescException {
01019 
01020         ZipFile zf = null;
01021         InputStream isDd = null;
01022         InputStream isJdd = null;
01023         EjbJar ejbJar;
01024         JonasEjbJar jonasEjbJar;
01025 
01026         // Check if the Alt deploymentDesc file exists. (optional value)
01027         if ((altWebXmlFilename != null) && (!new File(altWebXmlFilename).exists())) {
01028             String err = "The file for the altdd tag for the EAR case '" + altWebXmlFilename + "' was not found.";
01029             throw new DeploymentDescException(err);
01030         }
01031 
01032         // Get the XML DD files of the ejb-jar as InputStream
01033         try {
01034             zf = new ZipFile(ejbJarFileName);
01035 
01036             if (altWebXmlFilename == null) {
01037                 // No alt-dd case ( standard)
01038                 ZipEntry ejbEntry = zf.getEntry(EJB_JAR_FILE_NAME);
01039                 if (ejbEntry == null) {
01040                     throw new DeploymentDescException("The entry '" + EJB_JAR_FILE_NAME
01041                             + "' was not found in the file '" + ejbJarFileName + "'.");
01042                 }
01043                 isDd = zf.getInputStream(ejbEntry);
01044                 xmlContent = xmlContent(isDd);
01045                 isDd = zf.getInputStream(zf.getEntry(EJB_JAR_FILE_NAME));
01046             } else {
01047                 // AltDD (Ear and optional)
01048                 isDd = new FileInputStream(altWebXmlFilename);
01049                 xmlContent = xmlContent(isDd);
01050                 isDd = new FileInputStream(altWebXmlFilename);
01051             }
01052             ZipEntry jEjbEntry = zf.getEntry(JONAS_EJB_JAR_FILE_NAME);
01053             if (jEjbEntry != null) {
01054                 isJdd = zf.getInputStream(jEjbEntry);
01055                 jonasXmlContent = xmlContent(isJdd);
01056                 isJdd = zf.getInputStream(zf.getEntry(JONAS_EJB_JAR_FILE_NAME));
01057             } else {
01058                 logger.log(BasicLevel.WARN, "No entry '" + JONAS_EJB_JAR_FILE_NAME + "' was found in the file '" + ejbJarFileName + "'.");
01059             }
01060         } catch (Exception e) {
01061             if (zf != null) {
01062                 try {
01063                     zf.close();
01064                 } catch (IOException i) {
01065                     logger.log(BasicLevel.WARN, "Can't close '" + ejbJarFileName + "'");
01066                 }
01067             }
01068             logger.log(BasicLevel.ERROR, "Cannot read the XML deployment descriptors for " + ejbJarFileName + ":", e);
01069             throw new DeploymentDescException("Cannot read the XML deployment descriptors for " + ejbJarFileName + ":" + e);
01070         }
01071 
01072         // load standard deployment descriptor data
01073         ejbJar = loadEjbJar(new InputStreamReader(isDd), EJB_JAR_FILE_NAME);
01074         String dtdversion = ejbJar.getVersion();
01075         try {
01076             isDd.close();
01077         } catch (IOException e) {
01078             logger.log(BasicLevel.WARN, "Can't close META-INF/ejb-jar.xml in '" + ejbJarFileName + "'");
01079         }
01080 
01081         // load jonas deployment descriptor data
01082         if (isJdd != null) {
01083             jonasEjbJar = loadJonasEjbJar(new InputStreamReader(isJdd),
01084                                       JONAS_EJB_JAR_FILE_NAME);
01085             try {
01086                 isJdd.close();
01087             } catch (IOException e) {
01088                 logger.log(BasicLevel.WARN, "Can't close META-INF/jonas-ejb-jar.xml in '" + ejbJarFileName + "'");
01089             }
01090 
01091         } else {
01092             jonasEjbJar = new JonasEjbJar();
01093         }
01094 
01095         // Close the ZipFile
01096         if (zf != null) {
01097             try {
01098                 zf.close();
01099             } catch (IOException e) {
01100                 logger.log(BasicLevel.WARN, "Can't close '" + ejbJarFileName + "'");
01101             }
01102         }
01103 
01104         // instantiate deployment descriptor
01105         DeploymentDesc descEjb = null;
01106         if (dtdversion.equals("1.1")) {
01107             descEjb = new DeploymentDescEjb1_1(cl, ejbJar, jonasEjbJar, logger, ejbJarFileName);
01108         } else {
01109             descEjb = new DeploymentDescEjb2(cl, ejbJar, jonasEjbJar, logger, ejbJarFileName);
01110         }
01111         descEjb.setXmlContent(xmlContent);
01112         descEjb.setJOnASXmlContent(jonasXmlContent);
01113         return descEjb;
01114     }
01115 
01116 
01125     public static EjbJar loadEjbJar(Reader reader, String name)
01126         throws DeploymentDescException {
01127         EjbJar ejbjar = new EjbJar();
01128 
01129         // Create if null
01130         if (ejbjarDigester == null) {
01131             // Create and initialize the digester
01132             ejbjarDigester = new JDigester(ejbjarRuleSet,
01133                                            parsingWithValidation,
01134                                            true,
01135                                            new EjbjarDTDs(),
01136                                            new EjbjarSchemas());
01137         }
01138         try {
01139             ejbjarDigester.parse(reader, name, ejbjar);
01140         } catch (DeploymentDescException  e) {
01141             throw e;
01142         } finally {
01143             ejbjarDigester.push(null);
01144         }
01145         return ejbjar;
01146     }
01147 
01155     public static JonasEjbJar loadJonasEjbJar(Reader reader,
01156                                                String name)
01157         throws DeploymentDescException {
01158          JonasEjbJar jonasEjbjar = new JonasEjbJar();
01159         // Create if null
01160         if (jonasEjbjarDigester == null) {
01161             // Create and initialize the digester
01162             jonasEjbjarDigester = new JDigester(jonasEjbjarRuleSet,
01163                                            parsingWithValidation,
01164                                            true,
01165                                            new JonasEjbjarDTDs(),
01166                                            new JonasEjbjarSchemas());
01167         }
01168         try {
01169             jonasEjbjarDigester.parse(reader , name, jonasEjbjar);
01170         } catch (DeploymentDescException  e) {
01171             throw e;
01172         } finally {
01173             jonasEjbjarDigester.push(null);
01174         }
01175         return jonasEjbjar;
01176     }
01177 
01182     public static boolean getParsingWithValidation() {
01183         return parsingWithValidation;
01184     }
01185 
01190     public static void setParsingWithValidation(boolean validation) {
01191         EjbDeploymentDescManager.parsingWithValidation = validation;
01192     }
01193 
01198     public static String getXmlContent() {
01199         return xmlContent;
01200     }
01201 
01206     public static String getJOnASXmlContent() {
01207         return jonasXmlContent;
01208     }
01209 
01210 
01218     protected void checkType(URL ejbJar, String ejbType, JndiEnvRefsGroup bd) throws DeploymentDescException {
01219 
01220         if (bd instanceof SessionDesc) {
01221             if (!ejbType.equalsIgnoreCase("Session")) {
01222                 String err = "Deployment desc '" + ejbJar.getFile()
01223                         + "' has an incompatible ejb-ref-type: Required Session but found " + ejbType;
01224                 throw new DeploymentDescException(err);
01225             }
01226         } else if (bd instanceof EntityDesc) {
01227             if (!ejbType.equalsIgnoreCase("Entity")) {
01228                 String err = "Deployment desc '" + ejbJar.getFile()
01229                         + "' has an incompatible ejb-ref-type: Required Entity but found " + ejbType;
01230                 throw new DeploymentDescException(err);
01231             }
01232         } else {
01233             String err = "Deployment desc '" + ejbJar.getFile() + "' has a bad ejb-ref-type.";
01234             throw new DeploymentDescException(err);
01235         }
01236     }
01237 
01248     protected void checkTypeUsage(URL url, String mdType, String mdUsage, BeanDesc bd) throws DeploymentDescException {
01249 
01250         if (bd instanceof MessageDrivenDesc) {
01251             MessageDrivenDesc mdd = (MessageDrivenDesc) bd;
01252             if (mdd.getDestinationType().equals("javax.jms.Topic")) {
01253                 if (!mdType.equalsIgnoreCase("javax.jms.Topic")) {
01254                     String err = "Deployment desc '" + url.getFile()
01255                             + "' has an incompatible message-destination-type: Required javax.jms.Topic but found "
01256                             + mdType;
01257                     throw new DeploymentDescException(err);
01258                 }
01259             } else if (mdd.getDestinationType().equals("javax.jms.Queue")) {
01260                 if (!mdType.equalsIgnoreCase("javax.jms.Queue")) {
01261                     String err = "Deployment desc '" + url.getFile()
01262                             + "' has an incompatible message-destination-type: Required javax.jms.Queue but found "
01263                             + mdType;
01264                     throw new DeploymentDescException(err);
01265                 }
01266             }
01267         } else {
01268             String err = "Deployment desc '" + url.getFile() + "' has a bad message-destination-ref-type.";
01269             throw new DeploymentDescException(err);
01270         }
01271     }
01272 
01278     public void addClassLoaderUrlMapping(ClassLoader ejbClassloader, URL[] urls) {
01279         for (int u = 0; u < urls.length; u++) {
01280             urlEjbCLBindings.put(urls[u].getPath(), ejbClassloader);
01281         }
01282     }
01283 }

Generated on Tue Feb 15 15:05:47 2005 for JOnAS by  doxygen 1.3.9.1