/*******************************************************************************
 * Copyright (c) 2001, 2005 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.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.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;

	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;
	}

	/**
	 * 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().toLowerCase(); //$NON-NLS-1$
			
			String resolvedPath = new java.io.File(parent, classpathEntry).getCanonicalPath().toLowerCase();
			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;
			String lowerCaseEntry = resolvedPath.substring(start, resolvedPath.length()).replace(java.io.File.separatorChar, '/');
			
			char [] newEntry = lowerCaseEntry.toCharArray();
			char [] oldEntry = classpathEntry.replace(java.io.File.separatorChar, '/').toCharArray();
			int newIndex = 0;
			int oldIndex = 0;
			while(newIndex < newEntry.length && oldIndex < oldEntry.length){
				char c1 = newEntry[newIndex];
				char c2 = oldEntry[oldIndex];
				if(c1 == c2){
					newIndex ++;
					oldIndex ++;
				} else if(Character.toUpperCase(c1) == c2){
					newEntry[newIndex] = c2;
					newIndex ++;
					oldIndex ++;
				} else {
					oldIndex ++;
				}
			}
			String newEntryStr = new String(newEntry);
			return newEntryStr;
		} 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;
	}

}
