/*******************************************************************************
 * 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.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.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.resources.IVirtualComponent;

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$

	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 {
		J2EEModuleVirtualArchiveComponent archiveComponent = (J2EEModuleVirtualArchiveComponent) virtualComponent;
		JavaEEBinaryComponentLoadAdapter loadAdapter = new JavaEEBinaryComponentLoadAdapter(archiveComponent);
		ArchiveOptions archiveOptions = new ArchiveOptions();
		archiveOptions.setOption(ArchiveOptions.LOAD_ADAPTER, loadAdapter);
		archiveOptions.setOption(ArchiveOptions.ARCHIVE_PATH, loadAdapter.getArchivePath());
		archiveOptions.setOption(DISCRIMINATE_MAIN_CLASS, descriminateMainClass);
		IArchive parentEARArchive = null;
		try {
			if(archiveComponent.isLinkedToEAR()){
				try {
					IProject earProject = virtualComponent.getProject();
					if(earProject != null && EarUtilities.isEARProject(earProject)){
						IVirtualComponent earComponent = ComponentCore.createComponent(virtualComponent.getProject());
						if(earComponent != null) {
							parentEARArchive = openArchive(earComponent);
							if(parentEARArchive != null) {
								archiveOptions.setOption(ArchiveOptions.PARENT_ARCHIVE, parentEARArchive);
							}
						}
					}
				} catch(ArchiveOpenFailureException e) {
					org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
				}
			}
			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 };
		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()) {
			return simpleArchive;
		}
		return refineForJavaEE(simpleArchive);
	}

	private IArchive refineForJavaEE(final IArchive simpleArchive) {
		//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) {
								org.eclipse.jst.javaee.application.Application app = (org.eclipse.jst.javaee.application.Application) ddObj;
								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 (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
							switch (definedType) {
							case J2EEVersionConstants.EJB_TYPE: {
								//EE6TODO
								JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.EJB_TYPE, JavaEEQuickPeek.EJB_3_0_ID, JavaEEQuickPeek.JEE_5_0_ID);
								archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
								wrapArchive(simpleArchive, new Path(J2EEConstants.EJBJAR_DD_URI));
								return simpleArchive;
							}
							//EE6TODO
							case J2EEVersionConstants.APPLICATION_CLIENT_TYPE: {
								JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_CLIENT_TYPE, JavaEEQuickPeek.JEE_5_0_ID, JavaEEQuickPeek.JEE_5_0_ID);
								archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
								wrapArchive(simpleArchive, new Path(J2EEConstants.APPLICATION_DD_URI));
								return simpleArchive;
							}
							//EE6TODO
							case J2EEVersionConstants.WEB_TYPE: {
								JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.WEB_TYPE, JavaEEQuickPeek.WEB_2_5_ID, JavaEEQuickPeek.JEE_5_0_ID);
								archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
								wrapArchive(simpleArchive, new Path(J2EEConstants.WEBAPP_DD_URI));
								return simpleArchive;
							}
							case J2EEVersionConstants.CONNECTOR_TYPE: {
								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;
							}
							}
						}
					} catch (ArchiveModelLoadException e) {
						org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
					}
				}
			}
		}
		
		
		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 };
		int[] typeToVerify = new int[] { J2EEVersionConstants.APPLICATION_TYPE, J2EEVersionConstants.APPLICATION_CLIENT_TYPE, J2EEVersionConstants.EJB_TYPE, J2EEVersionConstants.WEB_TYPE,
				J2EEConstants.CONNECTOR_TYPE };
		for (int i = 0; i < deploymentDescriptorsToCheck.length; i++) {
			final int currentType = typeToVerify[i];
			final IPath deploymentDescriptorPath = new Path(deploymentDescriptorsToCheck[i]);
			IArchive wrappedForDD = wrapForDD(simpleArchive, currentType, deploymentDescriptorPath);
			if(wrappedForDD != null){
				return wrappedForDD;
			}
		}
		IPath archivePath = simpleArchive.getPath();
		if (archivePath == null) {
			Object obj = simpleArchive.getArchiveOptions().getOption(ArchiveOptions.ARCHIVE_PATH);
			if (null != obj) {
				archivePath = (IPath) obj;
			}
		}

		if (archivePath != null) {
			String lastSegment = archivePath.lastSegment().toLowerCase();
			if (lastSegment.endsWith(IJ2EEModuleConstants.EAR_EXT)) {
				//EE6TODO
				JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_TYPE, JavaEEQuickPeek.JEE_5_0_ID, JavaEEQuickPeek.JEE_5_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)) {
				//EE6TODO
				JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.WEB_TYPE, JavaEEQuickPeek.WEB_2_5_ID, JavaEEQuickPeek.JEE_5_0_ID);
				archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
				wrapArchive(simpleArchive, new Path(J2EEConstants.WEBAPP_DD_URI));
				return simpleArchive;
			} else if (lastSegment.endsWith(IJ2EEModuleConstants.JAR_EXT)) {
				Object discriminateMainClass = simpleArchive.getArchiveOptions().getOption(DISCRIMINATE_MAIN_CLASS);
				if (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) {
								//EE6TODO
								JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.APPLICATION_CLIENT_TYPE, JavaEEQuickPeek.JEE_5_0_ID, JavaEEQuickPeek.JEE_5_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)) {
						//EE6TODO
						JavaEEQuickPeek quickPeek = new JavaEEQuickPeek(JavaEEQuickPeek.EJB_TYPE, JavaEEQuickPeek.EJB_3_0_ID, JavaEEQuickPeek.JEE_5_0_ID);
						archiveToJavaEEQuickPeek.put(simpleArchive, quickPeek);
						wrapArchive(simpleArchive, new Path(J2EEConstants.EJBJAR_DD_URI));
						return simpleArchive;
					}
				}

			}
		}

		return simpleArchive;
	}

	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 (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$

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