| /******************************************************************************* |
| * Copyright (c) 2001, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.j2ee.commonarchivecore.internal.util; |
| |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.zip.ZipFile; |
| import java.util.zip.ZipInputStream; |
| import java.util.zip.ZipOutputStream; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.URIConverter; |
| import org.eclipse.emf.ecore.resource.impl.URIMappingRegistryImpl; |
| import org.eclipse.jem.java.JavaURL; |
| import org.eclipse.jst.j2ee.application.Module; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.Container; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleRef; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ArchiveException; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.EmptyResourceException; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveURIConverterImpl; |
| import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl; |
| import org.eclipse.jst.j2ee.internal.J2EEConstants; |
| import org.eclipse.jst.j2ee.internal.J2EEVersionConstants; |
| import org.eclipse.jst.j2ee.internal.common.XMLResource; |
| import org.eclipse.jst.j2ee.internal.xml.GeneralXmlDocumentReader; |
| import org.eclipse.jst.j2ee.internal.xml.XmlDocumentReader; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentType; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| import org.xml.sax.InputSource; |
| |
| import com.ibm.icu.util.StringTokenizer; |
| |
| |
| /** |
| * This is a utility class to hold helper methods common to multiple classes in the archive support |
| * packages |
| */ |
| public class ArchiveUtil { |
| public static final String DOT_CLASS = ".class"; //$NON-NLS-1$ |
| |
| public static final String DOT_JAVA = ".java"; //$NON-NLS-1$ |
| |
| public static final String DOT_SQLJ = ".sqlj"; //$NON-NLS-1$ |
| |
| public static final String DOT_JSP = ".jsp"; //$NON-NLS-1$ |
| |
| protected static boolean isRuntime = false; |
| |
| /** |
| * Flag to indicate whether the temp directory should be used for extracting nested jars for |
| * read; defaults to true |
| */ |
| protected static boolean shouldUseTempDirectoryForRead = true; |
| |
| /** |
| * Settable name for the temp directory; must resolve to a valid file on the file system; if not |
| * specified, defaults to the system temp directory |
| */ |
| protected static String tempDirectoryName; |
| |
| protected static java.io.File tempDirectory; |
| |
| /** |
| * Flag to indicate whether empty directories should be included during import; defaults to true. |
| * |
| * @see ZipFileLoadStrategyImpl#isIncludeEmptyDirectories() |
| */ |
| public static boolean INCLUDE_EMPTY_DIRECTORIES = true; |
| |
| |
| public static String classNameToJavaUri(String className) { |
| return className.replace('.', '/').concat(DOT_JAVA); |
| } |
| |
| public static String classNameToUri(String className) { |
| return className.replace('.', '/').concat(DOT_CLASS); |
| } |
| |
| /** |
| * For a given uri of a .class file, derive the uri of the .java file; takes into consideration |
| * inner classes by splitting on the first occurrence of '$' |
| * |
| * @return String a uri or null if the input is null or doesn't end with ".class" |
| */ |
| public static String classUriToJavaUri(String classUri) { |
| if (classUri == null || !classUri.endsWith(DOT_CLASS)) |
| return null; |
| |
| String truncated = truncateIgnoreCase(classUri, DOT_CLASS); |
| StringTokenizer tok = new StringTokenizer(truncated, "$"); //$NON-NLS-1$ |
| return tok.nextToken().concat(DOT_JAVA); |
| } |
| |
| /** |
| * Concatenates the two strings with a separator, if necessary |
| */ |
| public static String concatUri(String directoryname, String filename, char separator) { |
| String uri = directoryname; |
| if (!directoryname.endsWith(separator + "") && !filename.startsWith(separator + "")) //$NON-NLS-2$//$NON-NLS-1$ |
| uri = uri + separator; |
| return uri + filename; |
| } |
| |
| /** |
| * Copy all the data from the input stream to the output stream up until the first end of file |
| * character, and close the two streams |
| */ |
| public static void copy(InputStream in, OutputStream out) throws IOException { |
| byte[] buffer = new byte[1024]; |
| try { |
| int n = in.read(buffer); |
| while (n > 0) { |
| out.write(buffer, 0, n); |
| n = in.read(buffer); |
| } |
| } finally { |
| if (!(in instanceof ZipInputStream)) |
| in.close(); |
| if (!(out instanceof ZipOutputStream)) |
| out.close(); |
| } |
| } |
| |
| public static File createTempDirectory(String baseName, File parentDirectory) throws IOException { |
| |
| File tempFile = createTempFile(baseName, parentDirectory); |
| tempFile.delete(); |
| tempFile.mkdir(); |
| return tempFile; |
| } |
| |
| public static File createTempFile(String baseName) throws IOException { |
| return createTempFile(baseName, getTempDirectory()); |
| } |
| |
| public static File createTempFile(String baseName, File directory) throws IOException { |
| String fileName = getFileNameTail(baseName); |
| if (fileName.length() < 3) { |
| fileName = "WSTMP" + fileName; //$NON-NLS-1$ |
| } |
| File tempFile = File.createTempFile(fileName, null, directory); |
| return tempFile; |
| } |
| |
| /** |
| * deletes a file from the file system; for directories, recurse the subdirectories and delete |
| * them as well |
| * |
| * @return true if successful; false if any file or sub file could not be deleted |
| */ |
| public static boolean delete(File aFile) { |
| if (aFile == null) |
| return true; |
| if (aFile.isDirectory()) { |
| File[] files = aFile.listFiles(); |
| if (files != null) { |
| for (int i = 0; i < files.length; i++) { |
| if (!delete(files[i])) |
| return false; |
| } |
| } |
| } |
| return aFile.delete(); |
| } |
| |
| /** |
| * returns a list of all files, recursive, that can't be written |
| */ |
| public static List getWriteProtectedFiles(File aFile, List aList) { |
| if (aList == null) |
| aList = new ArrayList(); |
| if (aFile.exists() && !aFile.canWrite()) |
| aList.add(aFile); |
| if (aFile.isDirectory()) { |
| File[] files = aFile.listFiles(); |
| for (int i = 0; i < files.length; i++) { |
| getWriteProtectedFiles(files[i], aList); |
| } |
| } |
| return aList; |
| } |
| |
| /** |
| * <p>Alternate method for resolving class path entries.</p> |
| * |
| * <p>Note: Not sure what this is for, as a classpath |
| * entry such as "../targetJar.jar" seems invalid, as it |
| * reaches outside of the EAR directory.</p> |
| * |
| * <p>While this method will remove "./" from a classpath entry, |
| * it will not remove "../", which will be added back when |
| * deresolving the entry. There is no meaningful name to assign |
| * to an entity outside of the fileset of the container.</p> |
| * |
| * <p>This implementation uses eclipse URI function, as opposed to the |
| * implementation in <code>deriveEARRelativeURI</code>.</p> |
| * |
| * @param classpathEntry The class-path entry which is to be resolved. |
| * @param container The container against which to resolve the entry. |
| * |
| * @return The text of the resolved entry. |
| */ |
| |
| public static String deriveRelativeURI(String classpathEntry, Container container) |
| { |
| URI containerURI = URI.createFileURI( container.getURI() ); |
| // 'container.getURI()' returns a string. |
| |
| URI entryURI = URI.createFileURI(classpathEntry); |
| |
| URI resolvedURI = entryURI.resolve(containerURI); |
| URI recoveredURI = resolvedURI.deresolve(containerURI); |
| |
| return recoveredURI.toFileString(); |
| } |
| |
| /** |
| * Leverage the java.io.File apis to resolve things like "./xxx" and "../xxx" into uris of |
| * entries in the ear file |
| * |
| * @param classpathEntry - |
| * a classpath entry from the manifest of |
| * @anArchive |
| * @param anArchive - |
| * the archive to which the dependent jar is relative |
| * |
| * @return a cananonicalized relative uri of an entry in an ear file representing the dependent |
| * jar |
| */ |
| public static String deriveEARRelativeURI(String classpathEntry, Archive anArchive) { |
| return deriveEARRelativeURI(classpathEntry, anArchive.getURI()); |
| } |
| |
| /** |
| * Leverage the java.io.File apis to resolve things like "./xxx" and "../xxx" into uris of |
| * entries in the ear file |
| * |
| * @param classpathEntry - |
| * a classpath entry from the manifest of an archive |
| * @param String - |
| * the uri of the archive to which the dependent jar is relative |
| * |
| * @return a cananonicalized relative uri of an entry in an ear file representing the dependent |
| * jar |
| */ |
| public static String deriveEARRelativeURI(String classpathEntry, String archiveUri) { |
| try { |
| String parent = getFileNameParent(archiveUri); |
| if (parent == null || parent.equals("")) //$NON-NLS-1$ |
| parent = "."; //$NON-NLS-1$ |
| String workingDir = new java.io.File(".").getCanonicalPath(); //$NON-NLS-1$ |
| |
| String resolvedPath = new java.io.File(parent, classpathEntry).getCanonicalPath(); |
| if (!resolvedPath.startsWith(workingDir)) |
| return null; |
| if (resolvedPath.equals(workingDir)) |
| return null; |
| int start = workingDir.endsWith(java.io.File.separator) ? workingDir.length() : workingDir.length() + 1; |
| return resolvedPath.substring(start, resolvedPath.length()).replace(java.io.File.separatorChar, '/'); |
| } catch (java.io.IOException ex) { |
| //getCanonicalPath could throw this |
| return null; |
| } |
| } |
| |
| /** |
| * Return "" if there is no extension |
| */ |
| public static String getFileNameExtension(String uri) { |
| |
| if (uri != null) { |
| int index = uri.lastIndexOf("."); //$NON-NLS-1$ |
| if (index != -1) |
| return uri.substring(index + 1); |
| } |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the directory from the uri, or the truncation of the segment after the last |
| * occurrence of a separator |
| */ |
| public static String getFileNameParent(String uri) { |
| if (uri==null) |
| return ""; //$NON-NLS-1$ |
| String tempURI = uri.replace('\\', '/'); |
| while (tempURI.endsWith("/")) //$NON-NLS-1$ |
| tempURI = tempURI.substring(0, tempURI.length() - 1); |
| int lastIndex = tempURI.lastIndexOf('/'); |
| if (lastIndex == -1) |
| return ""; //$NON-NLS-1$ |
| else if (lastIndex == 0) |
| return "/"; //$NON-NLS-1$ |
| return uri.substring(0, lastIndex); |
| } |
| |
| /** |
| * Returns the filename from the uri, or the segment after the last occurrence of a separator |
| */ |
| public static String getFileNameTail(String uri) { |
| String tempURI = uri.replace('\\', '/'); |
| while (tempURI.endsWith("/")) //$NON-NLS-1$ |
| tempURI = tempURI.substring(0, tempURI.length() - 1); |
| int lastIndex = tempURI.lastIndexOf('/'); |
| if (lastIndex == -1) |
| return uri; |
| return uri.substring(lastIndex + 1, tempURI.length()); |
| } |
| |
| /** |
| * For the given object in the deployment descriptor, return the owning module file; for |
| * example, retrieve the EJBJarFile that owns the EJBJar. This works even for alts |
| */ |
| public static ModuleFile getModuleFile(EObject ddObject) { |
| Resource res = ddObject.eResource(); |
| if (res == null) |
| return null; |
| |
| Archive archive = getArchive(res); |
| if (archive == null || !archive.isModuleFile()) |
| return null; |
| |
| if (!(res instanceof XMLResource)) |
| return null; |
| |
| XMLResource xmlRes = (XMLResource) res; |
| if (xmlRes.isAlt()) |
| return getModuleFileUsingAltDD((EARFile) archive, res); |
| |
| return (ModuleFile) archive; |
| } |
| |
| protected static ModuleFile getModuleFileUsingAltDD(EARFile ear, Resource res) { |
| if (res == null) |
| return null; |
| |
| String uri = res.getURI().toString(); |
| Module m = ear.getDeploymentDescriptor().getModuleHavingAltDD(uri); |
| if (m == null) |
| return null; |
| ModuleRef ref = ear.getModuleRef(m); |
| if (ref == null) |
| return null; |
| |
| return ref.getModuleFile(); |
| } |
| |
| public static String getModuleFileTypeName(int moduleType) { |
| switch (moduleType) { |
| case XMLResource.APPLICATION_TYPE : |
| return CommonArchiveResourceHandler.A_Application_file; |
| case XMLResource.APP_CLIENT_TYPE : |
| return CommonArchiveResourceHandler.An_Application_Client_JAR_file; |
| case XMLResource.EJB_TYPE : |
| return CommonArchiveResourceHandler.An_EJB_JAR_file; |
| case XMLResource.WEB_APP_TYPE : |
| return CommonArchiveResourceHandler.A_WAR_file; |
| case XMLResource.RAR_TYPE : |
| return CommonArchiveResourceHandler.A_RAR_file; |
| } |
| return null; |
| } |
| |
| /** |
| * For the given resource, return the owning module file; for example, retrieve the EJBJarFile |
| * that owns the EJBJar. In the case of alts, this returns the EARFile and not the module file. |
| * This method is internal; clients should use {@link #getModuleFile(EObject)} |
| */ |
| public static Archive getArchive(Resource res) { |
| if (res == null) |
| return null; |
| |
| ResourceSet set = res.getResourceSet(); |
| if (set == null) |
| return null; |
| |
| URIConverter conv = set.getURIConverter(); |
| if (conv == null || !(conv instanceof ArchiveURIConverterImpl)) |
| return null; |
| |
| return ((ArchiveURIConverterImpl) conv).getArchive(); |
| } |
| |
| /** |
| * Concatenates the two strings and ensures the correct separator is used in the path |
| */ |
| public static String getOSUri(String uri) { |
| char sep = File.separatorChar; |
| if (sep != '/') |
| return uri.replace('/', sep); |
| return uri.replace('\\', sep); |
| } |
| |
| /** |
| * Concatenates the two strings and ensures the correct separator is used in the path |
| */ |
| public static String getOSUri(String directoryname, String filename) { |
| String osDirName = getOSUri(directoryname); |
| String osFileName = getOSUri(filename); |
| return concatUri(osDirName, osFileName, File.separatorChar); |
| } |
| |
| /** |
| * Returns the first element in the extent of the resource |
| * |
| * @throws EmptyResourceException - |
| * thrown if the extent is empty |
| */ |
| public static EObject getRoot(Resource aResource) throws EmptyResourceException { |
| EList extent = aResource.getContents(); |
| if (extent.size() < 1) { |
| throw new EmptyResourceException(aResource.getURI().toString()); |
| } |
| return (EObject) extent.get(0); |
| } |
| |
| public static java.io.File getTempDirectory() { |
| return tempDirectory; |
| } |
| |
| /** |
| * Insert the method's description here. Creation date: (12/19/00 1:16:48 PM) |
| * |
| * @return java.lang.String |
| */ |
| public static java.lang.String getTempDirectoryName() { |
| return tempDirectoryName; |
| } |
| |
| public static String[] getTokens(String aString) { |
| return getTokens(aString, null); |
| } |
| |
| public static String[] getTokens(String aString, String delimiter) { |
| |
| StringTokenizer tok = (delimiter == null) ? new StringTokenizer(aString) : new StringTokenizer(aString, delimiter); |
| int size = tok.countTokens(); |
| String[] tokens = new String[size]; |
| for (int i = 0; i < size && tok.hasMoreTokens(); i++) { |
| tokens[i] = tok.nextToken(); |
| } |
| return tokens; |
| } |
| |
| /** |
| * getValueIgnoreKeyCase method comment. |
| */ |
| public static java.lang.String getValueIgnoreKeyCase(java.lang.String key, java.util.jar.Attributes attr) { |
| Iterator keysAndValues = attr.entrySet().iterator(); |
| while (keysAndValues.hasNext()) { |
| Map.Entry entry = (Map.Entry) keysAndValues.next(); |
| String entryKey = entry.getKey().toString(); |
| if (entryKey.equalsIgnoreCase(key)) |
| return entry.getValue() == null ? null : entry.getValue().toString(); |
| } |
| return null; |
| } |
| |
| public static void inform(String message) { |
| org.eclipse.jem.util.logger.proxy.Logger.getLogger().logInfo(message); |
| } |
| |
| /** |
| * Read all the data from the input stream up until the first end of file character, add this |
| * data to a byte array, and close the input stream; returns the byte array |
| */ |
| public static byte[] inputStreamToBytes(InputStream in) throws IOException { |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| copy(in, out); |
| return out.toByteArray(); |
| } |
| |
| public static boolean isJavaResource(Resource aResource) { |
| return JavaURL.isJavaURL(aResource.getURI().toString()); |
| } |
| |
| public static boolean isRegisteredURIMapping(Resource res) { |
| return URIMappingRegistryImpl.INSTANCE.getURI(res.getURI()) != res.getURI(); |
| } |
| |
| public static boolean isPlatformMetaResource(Resource res) { |
| URI uri = res.getURI(); |
| return "platform".equals(uri.scheme()) && "meta".equals(uri.segment(0)); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| public static boolean isNullOrEmpty(String aString) { |
| return aString == null || aString.trim().length() == 0; |
| } |
| |
| public static boolean isRuntime() { |
| return isRuntime; |
| } |
| |
| /** |
| * Is it within the spec for the JAR or module file to reference the archive via the Manifest |
| * Class-Path? |
| */ |
| public static boolean isValidDependency(Archive referencedJAR, Archive referencingJAR) { |
| //No other modules should reference wars |
| if (referencedJAR.isWARFile()) |
| return false; |
| |
| if (referencedJAR == referencingJAR) |
| return false; |
| |
| //Clients can reference all but the WARs, which we've already covered |
| // above; WARs and EJB JARs |
| //can reference all but WARs, above, or ApplicationClients |
| return referencingJAR.isApplicationClientFile() || !referencedJAR.isApplicationClientFile(); |
| } |
| |
| /** |
| * Loads a properties file with the given uri from the given archive |
| * |
| * @throws FileNotFoundException |
| * if the file does not exist in the archive |
| * @throws IOException |
| * if an IO exception occurs reading the properties |
| */ |
| public static Properties loadProperties(Archive archive, String uri) throws FileNotFoundException, IOException { |
| InputStream in = null; |
| try { |
| in = archive.getInputStream(uri); |
| Properties p = new Properties(); |
| p.load(in); |
| return p; |
| } finally { |
| if (in != null) |
| in.close(); |
| } |
| } |
| |
| public static void setIsRuntime(boolean aBoolean) { |
| isRuntime = aBoolean; |
| } |
| |
| /** |
| * |
| */ |
| public static void setShouldUseTempDirectoryForRead(boolean value) { |
| shouldUseTempDirectoryForRead = value; |
| } |
| |
| /** |
| * Insert the method's description here. Creation date: (12/19/00 1:26:28 PM) |
| * |
| * @param newTempDirectory |
| * java.io.File |
| */ |
| public static void setTempDirectory(java.io.File newTempDirectory) { |
| tempDirectory = newTempDirectory; |
| tempDirectoryName = newTempDirectory.getAbsolutePath(); |
| } |
| |
| /** |
| * Sets the temp directory to the specified path; creates it and sets it to be deleted on exit |
| * if it does not exist. |
| * |
| * @param newTempDirectoryName |
| * java.lang.String |
| * @throws ArchiveException |
| * thrown if the directory does not exist and can not be created |
| */ |
| public static void setTempDirectoryName(java.lang.String newTempDirectoryName) throws ArchiveException { |
| java.io.File dir = new java.io.File(newTempDirectoryName); |
| if (!dir.exists()) { |
| dir.mkdirs(); |
| if (!dir.exists()) |
| throw new ArchiveException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.make_temp_dir_EXC_, (new Object[]{newTempDirectoryName}))); // = "Unable to make temp directory: " |
| DeleteOnExitUtility.markForDeletion(dir); |
| } |
| setTempDirectory(dir); |
| } |
| |
| /** |
| * Insert the method's description here. Creation date: (12/19/00 1:08:20 PM) |
| * |
| * @return boolean |
| */ |
| public static boolean shouldUseTempDirectoryForRead() { |
| return shouldUseTempDirectoryForRead; |
| } |
| |
| /** |
| * Convert the list of string elements to an array of file URLs; if an entry is relative, make |
| * it relative to the uri root |
| */ |
| public static java.net.URL[] toLocalURLs(List entries, String uriRoot) { |
| List urls = new ArrayList(); |
| for (int i = 0; i < entries.size(); i++) { |
| String pathEntry = (String) entries.get(i); |
| java.io.File aFile = new java.io.File(pathEntry); |
| if (!aFile.isAbsolute()) { |
| pathEntry = getOSUri(uriRoot, pathEntry); |
| aFile = new java.io.File(pathEntry); |
| } |
| if (!aFile.exists()) { |
| //inform("Classpath element " + pathEntry + " does not |
| // exist"); |
| continue; |
| } |
| if (aFile.isDirectory()) { |
| if (!pathEntry.endsWith(java.io.File.separator)) { |
| pathEntry = pathEntry + java.io.File.separatorChar; |
| } |
| } else { |
| ZipFile zip = null; |
| try { |
| zip = new ZipFile(aFile); |
| } catch (Exception ex) { |
| inform(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.invalid_classpath_WARN_, (new Object[]{pathEntry}))); // = "Classpath element "{0}" is not a directory or a Zip file" |
| continue; |
| } finally { |
| if (zip != null) |
| try { |
| zip.close(); |
| } catch (IOException ignore) { |
| //Ignore |
| } |
| } |
| } |
| try { |
| aFile = new java.io.File(pathEntry); |
| java.net.URL aUrl = aFile.toURL(); |
| urls.add(aUrl); |
| } catch (java.net.MalformedURLException ex) { |
| inform(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.invalid_cp_file_WARN_, (new Object[]{pathEntry}))); // = "Classpath element "{0}" does not point to a local file" |
| } |
| } |
| java.net.URL[] urlArray = new java.net.URL[urls.size()]; |
| return (java.net.URL[]) urls.toArray(urlArray); |
| } |
| |
| /** |
| * Return a substring of the first parameter, starting at the end of the prefix |
| */ |
| public static String truncateFromFrontIgnoreCase(String aString, String leadingSubString) { |
| if (!aString.toLowerCase().startsWith(leadingSubString.toLowerCase())) |
| return aString; |
| return aString.substring(leadingSubString.length(), aString.length()); |
| } |
| |
| /** |
| * Return a substring of the first parameter, up to the last index of the second |
| */ |
| public static String truncateIgnoreCase(String aString, String trailingSubString) { |
| int index = aString.toLowerCase().lastIndexOf(trailingSubString.toLowerCase()); |
| if (index != -1) |
| return aString.substring(0, index); |
| return aString; |
| } |
| |
| public static String uriToClassName(String uri) { |
| return truncateIgnoreCase(uri.replace('/', '.'), DOT_CLASS); |
| } |
| |
| public static boolean isJ2EE13FastCheck(ModuleFile moduleFile) { |
| if (moduleFile == null) |
| return false; |
| else if (moduleFile.isRARFile()) |
| return true; |
| InputStream in = null; |
| String uri = moduleFile.getDeploymentDescriptorUri(); |
| try { |
| in = moduleFile.getInputStream(uri); |
| |
| DocumentType docType = XmlDocumentReader.readDocumentType(in, uri); |
| if (docType == null) |
| return false; |
| String[] ids = getJ2EE13PublicAndSystemIdFor(moduleFile); |
| if (ids == null) |
| return false; |
| return ids[0].equals(docType.getPublicId()) && ids[1].equals(docType.getSystemId()); |
| } catch (IOException ex) { |
| return false; |
| } finally { |
| try { |
| if (in != null) |
| in.close(); |
| } catch (IOException ex) { |
| //Ignore |
| } |
| } |
| |
| } |
| |
| protected static String[] getJ2EE13PublicAndSystemIdFor(ModuleFile moduleFile) { |
| if (moduleFile.isEARFile()) |
| return new String[]{J2EEConstants.APPLICATION_PUBLICID_1_3, J2EEConstants.APPLICATION_SYSTEMID_1_3}; |
| else if (moduleFile.isEJBJarFile()) |
| return new String[]{J2EEConstants.EJBJAR_PUBLICID_2_0, J2EEConstants.EJBJAR_SYSTEMID_2_0}; |
| else if (moduleFile.isApplicationClientFile()) |
| return new String[]{J2EEConstants.APP_CLIENT_PUBLICID_1_3, J2EEConstants.APP_CLIENT_SYSTEMID_1_3}; |
| else if (moduleFile.isWARFile()) |
| return new String[]{J2EEConstants.WEBAPP_PUBLICID_2_3, J2EEConstants.WEBAPP_SYSTEMID_2_3}; |
| else if (moduleFile.isRARFile()) |
| return new String[]{J2EEConstants.CONNECTOR_PUBLICID_1_0, J2EEConstants.CONNECTOR_SYSTEMID_1_0}; |
| else |
| return null; |
| } |
| |
| //TODO doing the parse with SAX would be faster |
| public static int getFastSpecVersion(ModuleFile moduleFile) { |
| InputStream in = null; |
| String uri = moduleFile.getDeploymentDescriptorUri(); |
| try { |
| in = moduleFile.getInputStream(uri); |
| |
| DocumentType docType = null; |
| |
| InputSource source = new InputSource(in); |
| GeneralXmlDocumentReader aReader = new XmlDocumentReader(source); |
| aReader.setValidate(false); |
| Document aDocument = aReader.parseDocument(); |
| if (aDocument != null) { |
| docType = aDocument.getDoctype(); |
| } |
| int version = -1; |
| if (null != docType) { |
| String publicID = docType.getPublicId(); |
| String systemID = docType.getSystemId(); |
| if (publicID != null && systemID != null) { |
| version = lookupVersion(moduleFile, publicID, systemID); |
| } |
| } |
| if (version == -1) { |
| String schemaName = null; |
| String versionString = null; |
| if (aDocument != null) { |
| if (null == docType) { |
| NamedNodeMap map = aDocument.getDocumentElement().getAttributes(); |
| if (null != map) { |
| Node schemaNode = map.getNamedItem("xsi:schemaLocation"); //$NON-NLS-1$ |
| if (null != schemaNode) { |
| schemaName = schemaNode.getNodeValue(); |
| } |
| Node versionNode = map.getNamedItem("version");//$NON-NLS-1$ |
| if (null != versionNode) { |
| versionString = versionNode.getNodeValue(); |
| } |
| } |
| } |
| } |
| if (null != schemaName) { |
| version = lookupVersion(moduleFile, schemaName); |
| } |
| if (version == -1) { |
| version = parseVersionString(moduleFile, versionString); |
| } |
| } |
| |
| return version; |
| } catch (IOException ex) { |
| return -1; |
| } finally { |
| try { |
| if (in != null) |
| in.close(); |
| } catch (IOException ex) { |
| //Ignore |
| } |
| } |
| } |
| |
| private static int parseVersionString(ModuleFile moduleFile, String versionAttr) { |
| int version = -1; |
| if (moduleFile.isEARFile()) { |
| if (null == versionAttr) { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_1_2_TEXT)) { |
| version = J2EEVersionConstants.J2EE_1_2_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_1_3_TEXT)) { |
| version = J2EEVersionConstants.J2EE_1_3_ID; |
| } else { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } |
| } else if (moduleFile.isEJBJarFile()) { |
| if (null == versionAttr) { |
| version = J2EEVersionConstants.EJB_2_1_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_1_1_TEXT)) { |
| version = J2EEVersionConstants.EJB_1_1_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_2_0_TEXT)) { |
| version = J2EEVersionConstants.EJB_2_0_ID; |
| } else { |
| version = J2EEVersionConstants.EJB_2_1_ID; |
| } |
| } else if (moduleFile.isApplicationClientFile()) { |
| if (null == versionAttr) { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_1_2_TEXT)) { |
| version = J2EEVersionConstants.J2EE_1_2_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_1_3_TEXT)) { |
| version = J2EEVersionConstants.J2EE_1_3_ID; |
| } else { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } |
| } else if (moduleFile.isWARFile()) { |
| if (null == versionAttr) { |
| version = J2EEVersionConstants.WEB_2_4_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_2_2_TEXT)) { |
| version = J2EEVersionConstants.WEB_2_2_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_2_3_TEXT)) { |
| version = J2EEVersionConstants.WEB_2_3_ID; |
| } else { |
| version = J2EEVersionConstants.WEB_2_4_ID; |
| } |
| } else if (moduleFile.isRARFile()) { |
| if (null == versionAttr) { |
| version = J2EEVersionConstants.JCA_1_5_ID; |
| } else if (versionAttr.equals(J2EEVersionConstants.VERSION_1_0_TEXT)) { |
| version = J2EEVersionConstants.JCA_1_0_ID; |
| } else { |
| version = J2EEVersionConstants.JCA_1_5_ID; |
| } |
| } |
| return version; |
| |
| } |
| |
| private static int lookupVersion(ModuleFile moduleFile, String schemaName) { |
| int version = -1; |
| if (moduleFile.isEARFile()) { |
| if (schemaName.equals(J2EEConstants.APPLICATION_SCHEMA_1_4)) { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } |
| } else if (moduleFile.isEJBJarFile()) { |
| if ((schemaName.indexOf(J2EEConstants.EJBJAR_SCHEMA_2_1_NS)) != -1) { |
| version = J2EEVersionConstants.EJB_2_1_ID; |
| } |
| } else if (moduleFile.isApplicationClientFile()) { |
| if (schemaName.equals(J2EEConstants.APP_CLIENT_SCHEMA_1_4)) { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } |
| } else if (moduleFile.isWARFile()) { |
| if (schemaName.equals(J2EEConstants.WEBAPP_SCHEMA_2_4)) { |
| version = J2EEVersionConstants.WEB_2_4_ID; |
| } |
| } else if (moduleFile.isRARFile()) { |
| if (schemaName.equals(J2EEConstants.CONNECTOR_SCHEMA_1_5)) { |
| version = J2EEVersionConstants.JCA_1_5_ID; |
| } |
| } |
| return version; |
| } |
| |
| private static int lookupVersion(ModuleFile moduleFile, String publicID, String systemID) { |
| int version = -1; |
| if (moduleFile.isEARFile()) { |
| if (publicID.equals(J2EEConstants.APPLICATION_PUBLICID_1_3) && (systemID.equals(J2EEConstants.APPLICATION_SYSTEMID_1_3)||systemID.equals(J2EEConstants.APPLICATION_ALT_SYSTEMID_1_3))) { |
| version = J2EEVersionConstants.J2EE_1_3_ID; |
| } else if (publicID.equals(J2EEConstants.APPLICATION_PUBLICID_1_2) && (systemID.equals(J2EEConstants.APPLICATION_SYSTEMID_1_2)||systemID.equals(J2EEConstants.APPLICATION_ALT_SYSTEMID_1_2))) { |
| version = J2EEVersionConstants.J2EE_1_2_ID; |
| } else { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } |
| } else if (moduleFile.isEJBJarFile()) { |
| if (publicID.equals(J2EEConstants.EJBJAR_PUBLICID_2_0) && (systemID.equals(J2EEConstants.EJBJAR_SYSTEMID_2_0)||systemID.equals(J2EEConstants.EJBJAR_ALT_SYSTEMID_2_0))) { |
| version = J2EEVersionConstants.EJB_2_0_ID; |
| } else if (publicID.equals(J2EEConstants.EJBJAR_PUBLICID_1_1) && (systemID.equals(J2EEConstants.EJBJAR_SYSTEMID_1_1)||systemID.equals(J2EEConstants.EJBJAR_ALT_SYSTEMID_1_1))) { |
| version = J2EEVersionConstants.EJB_1_1_ID; |
| } else { |
| version = J2EEVersionConstants.EJB_2_1_ID; |
| } |
| } else if (moduleFile.isApplicationClientFile()) { |
| if (publicID.equals(J2EEConstants.APP_CLIENT_PUBLICID_1_3) && (systemID.equals(J2EEConstants.APP_CLIENT_SYSTEMID_1_3)||systemID.equals(J2EEConstants.APP_CLIENT_ALT_SYSTEMID_1_3))) { |
| version = J2EEVersionConstants.J2EE_1_3_ID; |
| } else if (publicID.equals(J2EEConstants.APP_CLIENT_PUBLICID_1_2) && (systemID.equals(J2EEConstants.APP_CLIENT_SYSTEMID_1_2)||systemID.equals(J2EEConstants.APP_CLIENT_ALT_SYSTEMID_1_2))) { |
| version = J2EEVersionConstants.J2EE_1_2_ID; |
| } else { |
| version = J2EEVersionConstants.J2EE_1_4_ID; |
| } |
| } else if (moduleFile.isWARFile()) { |
| if (publicID.equals(J2EEConstants.WEBAPP_PUBLICID_2_3) && (systemID.equals(J2EEConstants.WEBAPP_SYSTEMID_2_3)||systemID.equals(J2EEConstants.WEBAPP_ALT_SYSTEMID_2_3))) { |
| version = J2EEVersionConstants.WEB_2_3_ID; |
| } else if (publicID.equals(J2EEConstants.WEBAPP_PUBLICID_2_2) && (systemID.equals(J2EEConstants.WEBAPP_SYSTEMID_2_2)||systemID.equals(J2EEConstants.WEBAPP_ALT_SYSTEMID_2_2))) { |
| version = J2EEVersionConstants.WEB_2_2_ID; |
| } else { |
| version = J2EEVersionConstants.WEB_2_4_ID; |
| } |
| } else if (moduleFile.isRARFile()) { |
| if (publicID.equals(J2EEConstants.CONNECTOR_PUBLICID_1_0) && (systemID.equals(J2EEConstants.CONNECTOR_SYSTEMID_1_0)||systemID.equals(J2EEConstants.CONNECTOR_ALT_SYSTEMID_1_0))) { |
| version = J2EEVersionConstants.JCA_1_0_ID; |
| } else { |
| version = J2EEVersionConstants.JCA_1_5_ID; |
| } |
| } |
| return version; |
| } |
| |
| } |