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

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.util.IAnnotation;
import org.eclipse.jdt.core.util.IClassFileAttribute;
import org.eclipse.jdt.core.util.IClassFileReader;
import org.eclipse.jdt.core.util.IRuntimeVisibleAnnotationsAttribute;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualArchiveComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.componentcore.JavaEEBinaryComponentLoadAdapter;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.j2ee.project.WebUtilities;
import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
import org.eclipse.jst.jee.archive.ArchiveModelLoadException;
import org.eclipse.jst.jee.archive.ArchiveOpenFailureException;
import org.eclipse.jst.jee.archive.ArchiveOptions;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.archive.IArchiveLoadAdapter;
import org.eclipse.jst.jee.archive.IArchiveResource;
import org.eclipse.jst.jee.archive.internal.ArchiveFactoryImpl;
import org.eclipse.jst.jee.archive.internal.ArchiveImpl;
import org.eclipse.jst.jee.archive.internal.ArchiveUtil;
import org.eclipse.jst.jee.archive.internal.ZipFileArchiveLoadAdapterImpl;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;

public class JavaEEArchiveUtilities extends ArchiveFactoryImpl {

	/**
	 * Default value = Boolean.TRUE Valid values = Boolean.TRUE or Boolean.FALSE
	 * 
	 * An ArchiveOption used to specify whether
	 * {@link #openArchive(ArchiveOptions)} should attempt to discriminate
	 * between different Java EE archive types. The default behavior is to
	 * always discriminate fully for all types except EJB 3.0 archives
	 * {@link #DISCRIMINATE_EJB_ANNOTATIONS}. In order to fully discriminate
	 * EJB 3.0 archives, it is necessary to set both this flag and
	 * {@link #DISCRIMINATE_EJB_ANNOTATIONS} to true.
	 */
	public static final String DISCRIMINATE_JAVA_EE = "DISCRIMINATE_EJB"; //$NON-NLS-1$

	/**
	 * Default value = Boolean.TRUE Valid values = Boolean.TRUE or Boolean.FALSE
	 * 
	 * An ArchiveOption used to specify whether
	 * {@link #openArchive(ArchiveOptions)} should attempt to fully discriminate
	 * a JAR file from an EJB JAR file. This option is only relevant if the
	 * {@link #DISCRIMINATE_JAVA_EE} option is also set to Boolean.TRUE. If both
	 * options are set to true then as a last resort all .class files byte codes
	 * will be analyzed for EJB annotations in order to discriminate whether the
	 * specified IArchive is an EJB 3.0 jar.
	 */
	public static final String DISCRIMINATE_EJB_ANNOTATIONS = "DISCRIMINATE_EJB_ANNOTATIONS"; //$NON-NLS-1$
	
	/**
	 * Default value = Boolean.TRUE Valid values = Boolean.TRUE or Boolean.FALSE
	 * 
	 * An ArchiveOption used to specify whether
	 * {@link #openArchive(ArchiveOptions)} should attempt to fully discriminate
	 * a JAR file from an Application Client JAR file. This option is only relevant 
	 * if the {@link #DISCRIMINATE_JAVA_EE} option is also set to Boolean.TRUE. If 
	 * both options are set to true then as a last resort the MANIFEST.MF
	 * will be analyzed for a Main-Class entry in order to discriminate whether the
	 * specified IArchive is an Application Client jar.
	 */
	public static final String DISCRIMINATE_MAIN_CLASS = "DISCRIMINATE_MAIN_CLASS"; //$NON-NLS-1$

	/**
	 * Default value = null
	 * 
	 * An ArchiveOption used to specify the original load adapter in the case it
	 * swapped out with an {@link #JavaEEWrappingLoadAdapter}.
	 */
	public static final String WRAPPED_LOAD_ADAPTER = "WRAPPED_LOAD_ADAPTER"; //$NON-NLS-1$
	
	/**
	 * Default value = null
	 * 
	 * An ArchiveOption used to specify the IRuntime of the EAR that the archive
	 * is linked to.
	 */
	public static final String PARENT_RUNTIME = "PARENT_RUNTIME"; //$NON-NLS-1$

	private JavaEEArchiveUtilities() {
	}

	public static JavaEEArchiveUtilities INSTANCE = new JavaEEArchiveUtilities();

	public static final String DOT_JAVA = ".java"; //$NON-NLS-1$

	public static final String DOT_CLASS = ".class"; //$NON-NLS-1$

	public static boolean isJava(IFile iFile) {
		return hasExtension(iFile, DOT_JAVA);
	}

	public static boolean isClass(IFile iFile) {
		return hasExtension(iFile, DOT_CLASS);
	}

	public static boolean hasExtension(IFile iFile, String ext) {
		String name = iFile.getName();
		return hasExtension(name, ext);
	}

	public static boolean hasExtension(String name, String ext) {
		int offset = ext.length();
		return name.regionMatches(true, name.length() - offset, ext, 0, offset);
	}

	public IArchive openArchive(IVirtualComponent virtualComponent) throws ArchiveOpenFailureException {
		if (virtualComponent.isBinary()) {
			return openBinaryArchive(virtualComponent, true);
		}
		int type = J2EEVersionConstants.UNKNOWN;
		IArchiveLoadAdapter archiveLoadAdapter = null;
		if (JavaEEProjectUtilities.isEARProject(virtualComponent.getProject())) {
			archiveLoadAdapter = new EARComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.APPLICATION_TYPE;
		} else if (JavaEEProjectUtilities.isEJBComponent(virtualComponent)) {
			archiveLoadAdapter = new EJBComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.EJB_TYPE;
		} else if (JavaEEProjectUtilities.isApplicationClientComponent(virtualComponent)) {
			archiveLoadAdapter = new AppClientComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.APPLICATION_CLIENT_TYPE;
		} else if (JavaEEProjectUtilities.isJCAComponent(virtualComponent)) {
			archiveLoadAdapter = new ConnectorComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.CONNECTOR_TYPE;
		} else if (JavaEEProjectUtilities.isDynamicWebComponent(virtualComponent)) {
			archiveLoadAdapter = new WebComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.WEB_TYPE;
		} else if (JavaEEProjectUtilities.isUtilityProject(virtualComponent.getProject())) {
			archiveLoadAdapter = new JavaComponentArchiveLoadAdapter(virtualComponent);
		}

		if (archiveLoadAdapter != null) {
			ArchiveOptions options = new ArchiveOptions();
			options.setOption(ArchiveOptions.LOAD_ADAPTER, archiveLoadAdapter);
			IArchive archive = super.openArchive(options);
			if (type != J2EEVersionConstants.UNKNOWN) {
				int version = J2EEVersionConstants.UNKNOWN;
				String versionStr = JavaEEProjectUtilities.getJ2EEDDProjectVersion(virtualComponent.getProject());
				if(versionStr == null){
					versionStr = J2EEProjectUtilities.getJ2EEProjectVersion(virtualComponent.getProject());
				}
				switch (type) {
				case J2EEVersionConstants.APPLICATION_CLIENT_TYPE:
				case J2EEVersionConstants.APPLICATION_TYPE:
					if (versionStr.equals(J2EEVersionConstants.VERSION_1_2_TEXT)) {
						version = J2EEVersionConstants.J2EE_1_2_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_1_3_TEXT)) {
						version = J2EEVersionConstants.J2EE_1_3_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_1_4_TEXT)) {
						version = J2EEVersionConstants.J2EE_1_4_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_5_0_TEXT)) {
						version = J2EEVersionConstants.JEE_5_0_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_6_0_TEXT)) {
						version = J2EEVersionConstants.JEE_6_0_ID;
					}
					break;
				case J2EEVersionConstants.CONNECTOR_TYPE:
					if (versionStr.equals(J2EEVersionConstants.VERSION_1_0_TEXT)) {
						version = J2EEVersionConstants.JCA_1_0_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_1_5_TEXT)) {
						version = J2EEVersionConstants.JCA_1_5_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_1_6_TEXT)) {
						version = J2EEVersionConstants.JCA_1_6_ID;
					}
					break;
				case J2EEVersionConstants.EJB_TYPE:
					if (versionStr.equals(J2EEVersionConstants.VERSION_1_1_TEXT)) {
						version = J2EEVersionConstants.EJB_1_1_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_2_0_TEXT)) {
						version = J2EEVersionConstants.EJB_2_0_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_2_1_TEXT)) {
						version = J2EEVersionConstants.EJB_2_1_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_3_0_TEXT)) {
						version = J2EEVersionConstants.EJB_3_0_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_3_1_TEXT)) {
						version = J2EEVersionConstants.EJB_3_1_ID;
					}
					break;
				case J2EEVersionConstants.WEB_TYPE:
					if (versionStr.equals(J2EEVersionConstants.VERSION_2_2_TEXT)) {
						version = J2EEVersionConstants.WEB_2_2_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_2_3_TEXT)) {
						version = J2EEVersionConstants.WEB_2_3_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_2_4_TEXT)) {
						version = J2EEVersionConstants.WEB_2_4_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_2_5_TEXT)) {
						version = J2EEVersionConstants.WEB_2_5_ID;
					} else if (versionStr.equals(J2EEVersionConstants.VERSION_3_0_TEXT)) {
						version = J2EEVersionConstants.WEB_3_0_ID;
					}
					break;
				}
				if (version != J2EEVersionConstants.UNKNOWN) {
					archiveToJavaEEQuickPeek.put(archive, new JavaEEQuickPeek(type, version));
				}
			}
			return archive;
		}
		return null;
	}

	public IArchive openBinaryArchive(IVirtualComponent virtualComponent, boolean descriminateMainClass) throws ArchiveOpenFailureException {
		JavaEEBinaryComponentLoadAdapter loadAdapter = new JavaEEBinaryComponentLoadAdapter((VirtualArchiveComponent) virtualComponent);
		ArchiveOptions archiveOptions = new ArchiveOptions();
		archiveOptions.setOption(ArchiveOptions.LOAD_ADAPTER, loadAdapter);
		archiveOptions.setOption(ArchiveOptions.ARCHIVE_PATH, loadAdapter.getArchivePath());
		archiveOptions.setOption(DISCRIMINATE_MAIN_CLASS, descriminateMainClass);
		if(descriminateMainClass == true){
			archiveOptions.setOption(JavaEEArchiveUtilities.DISCRIMINATE_JAVA_EE, Boolean.TRUE);
		}
		IArchive parentEARArchive = null;
		boolean foundParentArchive = false;
		try {
			if (JavaEEProjectUtilities.usesJavaEEComponent(virtualComponent)
					&& ((J2EEModuleVirtualArchiveComponent) virtualComponent).isLinkedToEAR()) {
				try {
					IProject earProject = virtualComponent.getProject();
					if(earProject != null && EarUtilities.isEARProject(earProject)){
						IVirtualComponent earComponent = ComponentCore.createComponent(virtualComponent.getProject());
						String earLibDir = EarUtilities.getEARLibDir(earComponent);
						boolean inLibDir = isInLibDir(earComponent, virtualComponent, earLibDir);
						if(inLibDir == true && earLibDir != null){
							archiveOptions.setOption(DISCRIMINATE_JAVA_EE, false);
						}
						if(earComponent != null) {
							parentEARArchive = openArchive(earComponent);
							if(parentEARArchive != null) {
								foundParentArchive = true;
								archiveOptions.setOption(ArchiveOptions.PARENT_ARCHIVE, parentEARArchive);
								IFacetedProject facetedProject = ProjectFacetsManager.create(earProject);
								if (facetedProject != null) {
									IRuntime runtime = facetedProject.getPrimaryRuntime();
									archiveOptions.setOption(PARENT_RUNTIME, runtime);
								}
							}
						}
					}
				} catch(ArchiveOpenFailureException e) {
					org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
				} catch (CoreException e) {
					org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
				}
			}
			if(!foundParentArchive && JavaEEProjectUtilities.usesJavaEEComponent(virtualComponent)){
				IProject webProject = virtualComponent.getProject();
				if(webProject != null && WebUtilities.isDynamicWebProject(webProject)){
					archiveOptions.setOption(DISCRIMINATE_MAIN_CLASS, false);
				}
			}
			return openArchive(archiveOptions);
		} finally {
			if (parentEARArchive != null){
				archiveOptions.removeOption(ArchiveOptions.PARENT_ARCHIVE);
				closeArchive(parentEARArchive);
			}
		}
	}

	private Map<IArchive, JavaEEQuickPeek> archiveToJavaEEQuickPeek = new WeakHashMap<IArchive, JavaEEQuickPeek>();

	/**
	 * Returns a utility for getting the type of Java EE archive, the Java EE
	 * version, and the Module version
	 * 
	 * @param archive
	 * @return
	 */
	public JavaEEQuickPeek getJavaEEQuickPeek(IArchive archive) {
		if (archiveToJavaEEQuickPeek.containsKey(archive)) {
			return archiveToJavaEEQuickPeek.get(archive);
		}
		String[] deploymentDescriptorsToCheck = new String[] { J2EEConstants.APPLICATION_DD_URI, J2EEConstants.APP_CLIENT_DD_URI, J2EEConstants.EJBJAR_DD_URI, J2EEConstants.WEBAPP_DD_URI,
				J2EEConstants.RAR_DD_URI, J2EEConstants.WEBFRAGMENT_DD_URI };
		for (int i = 0; i < deploymentDescriptorsToCheck.length; i++) {
			final IPath deploymentDescriptorPath = new Path(deploymentDescriptorsToCheck[i]);
			if (archive.containsArchiveResource(deploymentDescriptorPath)) {
				InputStream in = null;
				IArchiveResource dd;
				try {
					dd = archive.getArchiveResource(deploymentDescriptorPath);
					in = dd.getInputStream();
					JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(in);
					archiveToJavaEEQuickPeek.put(archive, quickPeek);
					return quickPeek;
				} catch (FileNotFoundException e) {
					ArchiveUtil.warn(e);
				} catch (IOException e) {
					ArchiveUtil.warn(e);
				}
			}
		}
		JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(null);
		archiveToJavaEEQuickPeek.put(archive, quickPeek);
		return quickPeek;
	}

	/**
	 * Returns an IArchive. This method will attempt to discriminate the
	 * specific Java EE archive type based on the following simple rules. Please
	 * note that these rules do not adhere exactly to the Java EE specification
	 * because they are written for a tooling environment rather than a runtime
	 * environment. Thus these rules attempt to compensate for user error with
	 * the understanding that other areas of the tooling environment will help
	 * detect and correct these errors.
	 * 
	 * <ol>
	 * <li> An archive containing a deployment descriptor is considered to be of
	 * that type </li>
	 * <li> An archive whose name ends with '.ear' is considered an EAR </li>
	 * <li> An archive whose name ends with '.war' is considered a WAR </li>
	 * <li> An archive whose name ends with '.jar' and which contains a
	 * META-INF/MANIFEST.MF file containing a Main-class attribute is considered
	 * an Application Client </li>
	 * <li> If the ArchiveOptions specify the
	 * {@link #DISCRIMINATE_EJB_ANNOTATIONS} as Boolean.TRUE then if the archive
	 * contains any .class file with EJB annotations it is considered an EJB
	 * JAR. Be warned that this full check does have performance implications
	 * and is not done by default.</li>
	 * An archive whose name ends with '.jar' is considered a Utility </li>
	 * </ol>
	 */
	@Override
	public IArchive openArchive(ArchiveOptions archiveOptions) throws ArchiveOpenFailureException {
		IArchive simpleArchive = super.openArchive(archiveOptions);
		Object discriminateJavaEE = archiveOptions.getOption(DISCRIMINATE_JAVA_EE);
		if (discriminateJavaEE != null && !((Boolean) discriminateJavaEE).booleanValue()) {
			archiveToJavaEEQuickPeek.put(simpleArchive, new JavaEEQuickPeek(null));
			return simpleArchive;
		}
		return refineForJavaEE(simpleArchive);
	}

	private IArchive refineForJavaEE(final IArchive simpleArchive) {
		boolean isNestedWithinEar5OrAbove = false;		
		String earLibDirectory = null;
		String defaultEARLibDir = new Path(J2EEConstants.EAR_DEFAULT_LIB_DIR).makeRelative().toString();
		
		//Check to see if this archive is actually being opened as a nested archive from within an EAR
		//if it is then the EAR's DD needs to be checked to see exactly what type of archive this is.
		if (simpleArchive.getArchiveOptions().hasOption(ArchiveOptions.PARENT_ARCHIVE)) {
			IArchive parent = (IArchive) simpleArchive.getArchiveOptions().getOption(ArchiveOptions.PARENT_ARCHIVE);
			JavaEEQuickPeek qp = getJavaEEQuickPeek(parent);

			if (qp.getType() == JavaEEQuickPeek.APPLICATION_TYPE) {
				IPath ddPath = new Path(J2EEConstants.APPLICATION_DD_URI);
				if (parent.containsArchiveResource(ddPath)) {
					try {
						Object ddObj = parent.getModelObject(ddPath);
						IPath archivePath = simpleArchive.getPath();
						if (archivePath == null) {
							Object obj = simpleArchive.getArchiveOptions().getOption(ArchiveOptions.ARCHIVE_PATH);
							if (null != obj) {
								archivePath = (IPath) obj;
							}
						}
						int definedType = J2EEVersionConstants.UNKNOWN;
						if(archivePath != null) {
							if (qp.getVersion() == JavaEEQuickPeek.JEE_5_0_ID || qp.getVersion() == JavaEEQuickPeek.JEE_6_0_ID) {
								isNestedWithinEar5OrAbove = true;
								org.eclipse.jst.javaee.application.Application app = (org.eclipse.jst.javaee.application.Application) ddObj;
								// If lib directory is not specified in deployment descriptor, use the default 
								earLibDirectory = app.getLibraryDirectory() == null? defaultEARLibDir : app.getLibraryDirectory();
								org.eclipse.jst.javaee.application.Module module = app.getFirstModule(archivePath.toString());
								//if the archive isn't found, do a smart search for it
								if(module == null){
									IPath noDevicePath = archivePath.setDevice(null);
									for(int i=1; i<noDevicePath.segmentCount() && module == null; i++){
										String stringPath = noDevicePath.removeFirstSegments(i).toString();
										module = app.getFirstModule(stringPath);
									}
								}
								if (null != module) {
									if (module.getEjb() != null) {
										definedType = J2EEVersionConstants.EJB_TYPE;
									} else if (module.getConnector() != null) {
										definedType = J2EEVersionConstants.CONNECTOR_TYPE;
									} else if (module.getJava() != null) {
										definedType = J2EEVersionConstants.APPLICATION_CLIENT_TYPE;
									} else if (module.getWeb() != null) {
										definedType = J2EEVersionConstants.WEB_TYPE;
									}
								}
							} else { //J2EE 1.4 or below, rely solely on DD
								org.eclipse.jst.j2ee.application.Application app = (org.eclipse.jst.j2ee.application.Application) ddObj;
								org.eclipse.jst.j2ee.application.Module module = app.getFirstModule(archivePath.toString());
								//if the archive isn't found, do a smart search for it
								if(module == null){
									IPath noDevicePath = archivePath.setDevice(null);
									for(int i=1; i<noDevicePath.segmentCount() && module == null; i++){
										String stringPath = noDevicePath.removeFirstSegments(i).toString();
										module = app.getFirstModule(stringPath);
									}
								}
								if(module == null) {
									module = getModuleFromURI(app, archivePath.toString());
								}
								if (null != module) {
									if (module.isEjbModule()) {
										definedType = J2EEVersionConstants.EJB_TYPE;
									} else if (module.isConnectorModule()) {
										definedType = J2EEVersionConstants.CONNECTOR_TYPE;
									} else if (module.isJavaModule()) {
										definedType = J2EEVersionConstants.APPLICATION_CLIENT_TYPE;
									} else if (module.isWebModule()) {
										definedType = J2EEVersionConstants.WEB_TYPE;
									}
								} else { //J2EE 1.4 or below, and not in DD, treat as utility
									JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(null);
									archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
									return simpleArchive;
								}
							}
						}
						if (definedType != J2EEVersionConstants.UNKNOWN) {
							String ddToCheck = null;
							switch (definedType) {
							case J2EEVersionConstants.EJB_TYPE:
								ddToCheck = J2EEConstants.EJBJAR_DD_URI;
								break;
							case J2EEVersionConstants.CONNECTOR_TYPE:
								ddToCheck = J2EEConstants.RAR_DD_URI;
								break;
							case J2EEVersionConstants.APPLICATION_CLIENT_TYPE:
								ddToCheck = J2EEConstants.APP_CLIENT_DD_URI;
								break;
							case J2EEVersionConstants.WEB_TYPE:
								ddToCheck = J2EEConstants.WEBAPP_DD_URI;
								break;
							}
							IArchive wrappedForDD = wrapForDD(simpleArchive, definedType, new Path(ddToCheck));
							if (wrappedForDD != null) {
								return wrappedForDD;
							}
							// else there is no DD and we need to decide on a version
							JavaEEQuickPeek quickPeek = null;
							String ddURI = null;
							IRuntime runtime = null;
							Object obj = simpleArchive.getArchiveOptions().getOption(PARENT_RUNTIME);
							if (null != obj) {
								runtime = (IRuntime) obj;
							}
							
							switch (definedType) {
							case J2EEVersionConstants.EJB_TYPE: {
								ddURI = J2EEConstants.EJBJAR_DD_URI;
								if (runtime == null || runtime.supports(IJ2EEFacetConstants.EJB_31)) {
									quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.EJB_TYPE, JavaEEQuickPeek.EJB_3_1_ID, JavaEEQuickPeek.JEE_6_0_ID);
								}
								else {
									quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.EJB_TYPE, JavaEEQuickPeek.EJB_3_0_ID, JavaEEQuickPeek.JEE_5_0_ID);
								}
								break;
							}
							case J2EEVersionConstants.APPLICATION_CLIENT_TYPE: {
								ddURI = J2EEConstants.APPLICATION_DD_URI;
								if (runtime == null || runtime.supports(IJ2EEFacetConstants.APPLICATION_CLIENT_60)) {
									quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_CLIENT_TYPE, JavaEEQuickPeek.JEE_6_0_ID, JavaEEQuickPeek.JEE_6_0_ID);
								}
								else {
									quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_CLIENT_TYPE, JavaEEQuickPeek.JEE_5_0_ID, JavaEEQuickPeek.JEE_5_0_ID);
								}
								break;
							}
							case J2EEVersionConstants.WEB_TYPE: {
								ddURI = J2EEConstants.WEBAPP_DD_URI;
								if (runtime == null || runtime.supports(IJ2EEFacetConstants.DYNAMIC_WEB_30)) {
									quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.WEB_TYPE, JavaEEQuickPeek.WEB_3_0_ID, JavaEEQuickPeek.JEE_6_0_ID);
								}
								else {
									quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.WEB_TYPE, JavaEEQuickPeek.WEB_2_5_ID, JavaEEQuickPeek.JEE_5_0_ID);
								}
								break;
							}
							case J2EEVersionConstants.CONNECTOR_TYPE: {
								ddURI = J2EEConstants.RAR_DD_URI;
								quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.CONNECTOR_TYPE, JavaEEQuickPeek.JCA_1_6_ID, JavaEEQuickPeek.JEE_6_0_ID);
								break;
							}
							}
							
							if (quickPeek != null) {
								archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
								wrapArchive(simpleArchive, new Path(ddURI));
								return simpleArchive;
							}
						}
					} catch (ArchiveModelLoadException e) {
						org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
					}
				}
				else {
					//Parent EAR does not have deployment descriptor, so it is not legacy
					isNestedWithinEar5OrAbove = true;
					earLibDirectory = defaultEARLibDir;
				}
			}			
		}
		IPath archivePath = simpleArchive.getPath();
		if (archivePath == null) {
			Object obj = simpleArchive.getArchiveOptions().getOption(ArchiveOptions.ARCHIVE_PATH);
			if (null != obj) {
				archivePath = (IPath) obj;
			}
		}
		String lastSegment = null == archivePath ? null : archivePath.lastSegment().toLowerCase();
		
		IArchive wrappedArchive = checkJavaEEDD(lastSegment, simpleArchive);
		if(wrappedArchive != null){
			return wrappedArchive;
		}
		
		if (lastSegment != null) {
			if (lastSegment.endsWith(IJ2EEModuleConstants.EAR_EXT)) {
				JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_TYPE, JavaEEQuickPeek.JEE_6_0_ID, JavaEEQuickPeek.JEE_6_0_ID);
				archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
				wrapArchive(simpleArchive, new Path(J2EEConstants.APPLICATION_DD_URI));
				return simpleArchive;
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.RAR_EXT)){
				JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.CONNECTOR_TYPE, JavaEEQuickPeek.JCA_1_6_ID, JavaEEQuickPeek.JEE_6_0_ID);
				archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
				wrapArchive(simpleArchive, new Path(J2EEConstants.RAR_DD_URI));
				return simpleArchive;
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.WAR_EXT)) {
				JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.WEB_TYPE, JavaEEQuickPeek.WEB_3_0_ID, JavaEEQuickPeek.JEE_6_0_ID);
				archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
				wrapArchive(simpleArchive, new Path(J2EEConstants.WEBAPP_DD_URI));
				return simpleArchive;
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.JAR_EXT)) {
				String libPath = null == archivePath ? null : archivePath.removeLastSegments(1).toPortableString();
				// Do not look for main class in manifest.mf if jar is on lib directory of EAR 5 or above
				boolean skipDiscriminateMainClass = isNestedWithinEar5OrAbove && earLibDirectory!= null && earLibDirectory.equals(libPath);
				Object discriminateMainClass = simpleArchive.getArchiveOptions().getOption(DISCRIMINATE_MAIN_CLASS);
				if (!skipDiscriminateMainClass && (null == discriminateMainClass || ((Boolean) discriminateMainClass).booleanValue())) {
					IPath manifestPath = new Path(J2EEConstants.MANIFEST_URI);
					if (simpleArchive.containsArchiveResource(manifestPath)) {
						InputStream in = null;
						try {
							IArchiveResource manifestResource = simpleArchive.getArchiveResource(manifestPath);
							in = manifestResource.getInputStream();
							Manifest manifest = new Manifest(in);
							Attributes attributes = manifest.getMainAttributes();
							String mainClassName = attributes.getValue("Main-Class"); //$NON-NLS-1$
							if (mainClassName != null) {
								JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_CLIENT_TYPE, JavaEEQuickPeek.JEE_6_0_ID, JavaEEQuickPeek.JEE_6_0_ID);
								archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
								wrapArchive(simpleArchive, new Path(J2EEConstants.APPLICATION_DD_URI));
								return simpleArchive;
							}
						} catch (FileNotFoundException e) {
							ArchiveUtil.warn(e);
						} catch (IOException e) {
							ArchiveUtil.warn(e);
						} finally {
							if (in != null) {
								try {
									in.close();
								} catch (IOException e) {
									ArchiveUtil.warn(e);
								}
							}
						}
					}
				}
				Object discriminateEJB30 = simpleArchive.getArchiveOptions().getOption(DISCRIMINATE_EJB_ANNOTATIONS);
				if (null == discriminateEJB30 || ((Boolean) discriminateEJB30).booleanValue()) {
					if (isEJBArchive(simpleArchive)) {
						JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.EJB_TYPE, JavaEEQuickPeek.EJB_3_1_ID, JavaEEQuickPeek.JEE_6_0_ID);
						archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
						wrapArchive(simpleArchive, new Path(J2EEConstants.EJBJAR_DD_URI));
						return simpleArchive;
					}
				}

			}
		}

		return simpleArchive;
	}
	
	private org.eclipse.jst.j2ee.application.Module getModuleFromURI(org.eclipse.jst.j2ee.application.Application app, String uri) {
		if(uri == null)
			return null;
		String archiveName = (new Path(uri)).lastSegment();
		List<org.eclipse.jst.j2ee.application.internal.impl.ModuleImpl> modules = app.getModules();
		for (org.eclipse.jst.j2ee.application.internal.impl.ModuleImpl curModule : modules ){
			if(curModule != null && curModule.getUri() != null) {
				if(new Path(curModule.getUri()).lastSegment().equals(archiveName)) {
					return curModule;
				}
			}
		}
		return null;
	}

	/**
	 * This method checks for the existence of deployment descriptors to
	 * determine the correct Java EE type. The last segment of the file name is
	 * passed in as a hint.
	 * 
	 * @param lastSegment
	 * @param simpleArchive
	 * @return
	 */
	private IArchive checkJavaEEDD(final String lastSegment, final IArchive simpleArchive) {
		class DeploymentDescriptorCheck {
			private String ddString;
			private int typeToVerify;
			private boolean checked = false;

			public DeploymentDescriptorCheck(String ddString, int typeToVerify) {
				this.ddString = ddString;
				this.typeToVerify = typeToVerify;
			}

			public IArchive wrapForDD(IArchive simpleArchive) {
				if (checked) {
					return null;
				}
				checked = true;
				IPath path = new Path(ddString);
				return JavaEEArchiveUtilities.this.wrapForDD(simpleArchive, typeToVerify, path);
			}
		}

		int EAR_INDEX = 0;
		int RAR_INDEX = 1;
		int WAR_INDEX = 2;
		int EJB_INDEX = 3;
		int APP_CLIENT_INDEX = 4;
		int WEB_FRAGMENT_INDEX = 5;

		DeploymentDescriptorCheck[] deploymentDescriptorsToCheck = new DeploymentDescriptorCheck[6];
		deploymentDescriptorsToCheck[EAR_INDEX] = new DeploymentDescriptorCheck(J2EEConstants.APPLICATION_DD_URI, J2EEVersionConstants.APPLICATION_TYPE);
		deploymentDescriptorsToCheck[RAR_INDEX] = new DeploymentDescriptorCheck(J2EEConstants.RAR_DD_URI, J2EEVersionConstants.CONNECTOR_TYPE);
		deploymentDescriptorsToCheck[WAR_INDEX] = new DeploymentDescriptorCheck(J2EEConstants.WEBAPP_DD_URI, J2EEVersionConstants.WEB_TYPE);
		deploymentDescriptorsToCheck[EJB_INDEX] = new DeploymentDescriptorCheck(J2EEConstants.EJBJAR_DD_URI, J2EEVersionConstants.EJB_TYPE);
		deploymentDescriptorsToCheck[APP_CLIENT_INDEX] = new DeploymentDescriptorCheck(J2EEConstants.APP_CLIENT_DD_URI, J2EEVersionConstants.APPLICATION_CLIENT_TYPE);
		deploymentDescriptorsToCheck[WEB_FRAGMENT_INDEX] = new DeploymentDescriptorCheck(J2EEConstants.WEBFRAGMENT_DD_URI, J2EEVersionConstants.WEBFRAGMENT_TYPE);

		if (lastSegment != null) {
			if (lastSegment.endsWith(IJ2EEModuleConstants.EAR_EXT)) {
				IArchive wrappedForDD = deploymentDescriptorsToCheck[EAR_INDEX].wrapForDD(simpleArchive);
				if (wrappedForDD != null) {
					return wrappedForDD;
				}
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.RAR_EXT)) {
				IArchive wrappedForDD = deploymentDescriptorsToCheck[RAR_INDEX].wrapForDD(simpleArchive);
				if (wrappedForDD != null) {
					return wrappedForDD;
				}
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.WAR_EXT)) {
				IArchive wrappedForDD = deploymentDescriptorsToCheck[WAR_INDEX].wrapForDD(simpleArchive);
				if (wrappedForDD != null) {
					return wrappedForDD;
				}
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.JAR_EXT)) {
				IArchive wrappedForDD = deploymentDescriptorsToCheck[EJB_INDEX].wrapForDD(simpleArchive);
				if (wrappedForDD != null) {
					return wrappedForDD;
				}
				wrappedForDD = deploymentDescriptorsToCheck[APP_CLIENT_INDEX].wrapForDD(simpleArchive);
				if (wrappedForDD != null) {
					return wrappedForDD;
				}
				wrappedForDD = deploymentDescriptorsToCheck[WEB_FRAGMENT_INDEX].wrapForDD(simpleArchive);
				if (wrappedForDD != null) {
					return wrappedForDD;
				}
			}
		}

		for (DeploymentDescriptorCheck ddToCheck : deploymentDescriptorsToCheck) {
			IArchive wrappedForDD = ddToCheck.wrapForDD(simpleArchive);
			if (wrappedForDD != null) {
				return wrappedForDD;
			}
		}
		return null;
	}
	
	private IArchive wrapForDD(final IArchive simpleArchive, final int currentType, final IPath deploymentDescriptorPath) {
		if (simpleArchive.containsArchiveResource(deploymentDescriptorPath)) {
			InputStream in = null;
			IArchiveResource dd;
			try {
				dd = simpleArchive.getArchiveResource(deploymentDescriptorPath);
				in = dd.getInputStream();
				JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(in);
				if (quickPeek.getType() == currentType && quickPeek.getVersion() != JavaEEQuickPeek.UNKNOWN){
					if(isBinary(simpleArchive) || !simpleArchive.containsModelObject(deploymentDescriptorPath)){
						archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
						wrapArchive(simpleArchive, deploymentDescriptorPath);
						return simpleArchive;
					}
				}
			} catch (FileNotFoundException e) {
				ArchiveUtil.warn(e);
			} catch (IOException e) {
				ArchiveUtil.warn(e);
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						ArchiveUtil.warn(e);
					}
				}
			}
		}
		return null;
	}
		
	public static boolean isBinary(IArchive anArchive){
		IArchiveLoadAdapter loadAdapter = null;
		if(anArchive.getArchiveOptions().hasOption(WRAPPED_LOAD_ADAPTER)){
			loadAdapter = (IArchiveLoadAdapter)anArchive.getArchiveOptions().getOption(WRAPPED_LOAD_ADAPTER);
		} else {
			loadAdapter = (IArchiveLoadAdapter)anArchive.getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
		}
		if(loadAdapter instanceof JavaEEBinaryComponentLoadAdapter){
			return true;
		} else if(loadAdapter instanceof ZipFileArchiveLoadAdapterImpl){
			return true;
		}
		return false;
	}
	
	public static IArchive findArchive(Object modelObject){
		if(modelObject instanceof EObject){
			EObject eObject = (EObject)modelObject;
			return JavaEEEMFArchiveAdapterHelper.findArchive(eObject);
		}
		return null;
	}
	
	public static IVirtualComponent findComponent(IArchive anArchive){
		IArchiveLoadAdapter loadAdapter = null;
		if(anArchive.getArchiveOptions().hasOption(WRAPPED_LOAD_ADAPTER)){
			loadAdapter = (IArchiveLoadAdapter)anArchive.getArchiveOptions().getOption(WRAPPED_LOAD_ADAPTER);
		} else {
			loadAdapter = (IArchiveLoadAdapter)anArchive.getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
		}
		if(loadAdapter instanceof JavaEEBinaryComponentLoadAdapter){
			return ((JavaEEBinaryComponentLoadAdapter)loadAdapter).getArchiveComponent();
		}
		return null;
	}
	

	public static class JavaEEWrappingLoadAdapter implements IArchiveLoadAdapter {

		private IArchive simpleArchive;
		private IArchiveLoadAdapter simpleLoadAdapter;
		private IPath deploymentDescriptorPath;
		private JavaEEEMFArchiveAdapterHelper emfHelper;

		public JavaEEWrappingLoadAdapter(IArchive simpleArchive, IPath deploymentDescriptorPath) {
			this.simpleArchive = simpleArchive;
			this.simpleLoadAdapter = this.simpleArchive.getLoadAdapter();
			this.deploymentDescriptorPath = deploymentDescriptorPath;
			this.emfHelper = new JavaEEEMFArchiveAdapterHelper(this.simpleArchive);
		}

		public void close() {
			simpleLoadAdapter.close();
		}

		public boolean containsArchiveResource(IPath resourcePath) {
			return simpleLoadAdapter.containsArchiveResource(resourcePath);
		}

		public boolean containsModelObject(IPath modelObjectPath) {
			IPath localModelObjectPath = modelObjectPath;
			if (simpleLoadAdapter.containsArchiveResource(localModelObjectPath)) {
				return true;
			}
			if (IArchive.EMPTY_MODEL_PATH == localModelObjectPath) {
				localModelObjectPath = deploymentDescriptorPath;
			}
			return emfHelper.containsModelObject(localModelObjectPath);
		}

		public IArchiveResource getArchiveResource(IPath resourcePath) throws FileNotFoundException {
			return simpleLoadAdapter.getArchiveResource(resourcePath);
		}

		public List<IArchiveResource> getArchiveResources() {
			return simpleLoadAdapter.getArchiveResources();
		}

		public InputStream getInputStream(IArchiveResource archiveResource) throws IOException, FileNotFoundException {
			return simpleLoadAdapter.getInputStream(archiveResource);
		}

		public Object getModelObject(IPath modelObjectPath) throws ArchiveModelLoadException {
			IPath localModelObjectPath = modelObjectPath;
			if (IArchive.EMPTY_MODEL_PATH != localModelObjectPath 
					&& simpleLoadAdapter.containsModelObject(localModelObjectPath)) {
				return simpleLoadAdapter.getModelObject(localModelObjectPath);
			}
			if (IArchive.EMPTY_MODEL_PATH == localModelObjectPath) {
				localModelObjectPath = deploymentDescriptorPath;
			}
			return emfHelper.getModelObject(localModelObjectPath);
		}

		public IArchive getArchive() {
			return simpleLoadAdapter.getArchive();
		}

		public void setArchive(IArchive archive) {
			simpleLoadAdapter.setArchive(archive);
		}

		public IArchiveLoadAdapter getWrappedLoadAdatper() {
			return simpleLoadAdapter;
		}

		@Override
		public String toString() {
			return simpleLoadAdapter.toString();
		}

	}

	private static void wrapArchive(final IArchive simpleArchive, final IPath deploymentDescriptorPath) {
		IArchiveLoadAdapter wrappingEMFLoadAdapter = new JavaEEWrappingLoadAdapter(simpleArchive, deploymentDescriptorPath);
		simpleArchive.getArchiveOptions().setOption(ArchiveOptions.LOAD_ADAPTER, wrappingEMFLoadAdapter);
		simpleArchive.getArchiveOptions().setOption(WRAPPED_LOAD_ADAPTER, simpleArchive.getLoadAdapter());
		((ArchiveImpl) simpleArchive).setLoadAdapter(wrappingEMFLoadAdapter);
	}

	private static final char[] RUNTIME_VISIBLE = "RuntimeVisibleAnnotations".toCharArray(); //$NON-NLS-1$

	private static final char[] STATELESS = "Ljavax/ejb/Stateless;".toCharArray();//$NON-NLS-1$

	private static final char[] STATEFUL = "Ljavax/ejb/Stateful;".toCharArray();//$NON-NLS-1$

	private static final char[] MESSAGEDRIVEN = "Ljavax/ejb/MessageDriven;".toCharArray();//$NON-NLS-1$

	private static final char[] SINGLETON = "Ljavax/ejb/Singleton;".toCharArray();//$NON-NLS-1$

	
	public boolean isEJBArchive(IArchive archive) {
		// first check for the deployment descriptor
		if (archiveToJavaEEQuickPeek.containsKey(archive)) {
			JavaEEQuickPeek qp = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive);
			if (qp.getType() == JavaEEQuickPeek.EJB_TYPE) {
				return true;
			}
		}

		List<IArchiveResource> archiveResources = archive.getArchiveResources();
		for (IArchiveResource archiveResource : archiveResources) {
			if (archiveResource.getType() == IArchiveResource.FILE_TYPE) {
				if (archiveResource.getPath().lastSegment().endsWith(DOT_CLASS)) {
					InputStream ioStream = null;
					try {
						ioStream = archiveResource.getInputStream();
						IClassFileReader classFileReader = ToolFactory.createDefaultClassFileReader(ioStream, IClassFileReader.CLASSFILE_ATTRIBUTES);
						//classFileReader will be null if this is an invalid java .class file
						if(classFileReader != null){
							IClassFileAttribute[] attributes = classFileReader.getAttributes();
							for (IClassFileAttribute attribute : attributes) {
								char[] attributeName = attribute.getAttributeName();
								if (Arrays.equals(attributeName, RUNTIME_VISIBLE)) {
									IRuntimeVisibleAnnotationsAttribute annotationsAttribute = (IRuntimeVisibleAnnotationsAttribute) attribute;
									IAnnotation[] annotations = annotationsAttribute.getAnnotations();
									for (IAnnotation annotation : annotations) {
										char[] typedName = annotation.getTypeName();
										if (Arrays.equals(typedName, STATELESS) || Arrays.equals(typedName, STATEFUL) || Arrays.equals(typedName, MESSAGEDRIVEN) || Arrays.equals(typedName, SINGLETON)) {
											return true;
										}
									}
								}
							}
						}
					} catch (FileNotFoundException e) {
						ArchiveUtil.warn(e);
					} catch (IOException e) {
						ArchiveUtil.warn(e);
					} finally {
						if (null != ioStream) {
							try {
								ioStream.close();
							} catch (IOException e) {
								ArchiveUtil.warn(e);
							}
						}
						ioStream = null;
					}
				}
			}
		}
		return false;
	}

	public Manifest getManifest(IArchive archive) {
		Manifest manifest = null;
		IPath manifestPath = new Path(J2EEConstants.MANIFEST_URI);
		if (archive.containsArchiveResource(manifestPath)) {
			InputStream in = null;
			try {
				IArchiveResource manifestResource = archive.getArchiveResource(manifestPath);
				in = manifestResource.getInputStream();
				manifest = new Manifest(in);
			} catch (FileNotFoundException e) {
				ArchiveUtil.warn(e);
			} catch (IOException e) {
				ArchiveUtil.warn(e);
			} finally {
				if (in != null) {
					try {
						in.close();
					} catch (IOException e) {
						ArchiveUtil.warn(e);
					}
				}
			}
		}
		return manifest;
	}
	

	private boolean isInLibDir(IVirtualComponent earComp, IVirtualComponent component, String libDir){
		if (libDir != null && libDir.length() > 0) {
			IVirtualReference earRef = earComp.getReference(component.getName());
			IPath libDirPath = new Path(libDir).makeRelative();
			if(earRef != null){
				if(libDirPath.equals(earRef.getRuntimePath().makeRelative())){
					return true;
				}
				IPath fullPath = earRef.getRuntimePath().append(earRef.getArchiveName());
				if(fullPath.removeLastSegments(1).makeRelative().equals(libDirPath)){
					return true;
				}
			}
		}
		return false;
	}
	
}
