/*******************************************************************************
 * 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.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.IArchiveFactory;
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 implements IArchiveFactory {

	/**
	 * 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 = 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()) {
			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());
			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);
				}
			}
		}
		int type = J2EEVersionConstants.UNKNOWN;
		IArchiveLoadAdapter archiveLoadAdapter = null;
		if (J2EEProjectUtilities.isEARProject(virtualComponent.getProject())) {
			archiveLoadAdapter = new EARComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.APPLICATION_TYPE;
		} else if (J2EEProjectUtilities.isEJBComponent(virtualComponent)) {
			archiveLoadAdapter = new EJBComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.EJB_TYPE;
		} else if (J2EEProjectUtilities.isApplicationClientComponent(virtualComponent)) {
			archiveLoadAdapter = new AppClientComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.APPLICATION_CLIENT_TYPE;
		} else if (J2EEProjectUtilities.isJCAComponent(virtualComponent)) {
			archiveLoadAdapter = new ConnectorComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.CONNECTOR_TYPE;
		} else if (J2EEProjectUtilities.isDynamicWebComponent(virtualComponent)) {
			archiveLoadAdapter = new WebComponentArchiveLoadAdapter(virtualComponent);
			type = J2EEVersionConstants.WEB_TYPE;
		} else if (J2EEProjectUtilities.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;
					}
					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;
					}
					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;
					}
					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;
					}
					break;
				}
				if (version != J2EEVersionConstants.UNKNOWN) {
					archiveToJavaEEQuickPeek.put(archive, new JavaEEQuickPeek(type, version));
				}
			}
			return archive;
		}
		return null;
	}

	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);
		} else {
			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>
	 */
	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 static final String DOT_EAR = ".ear";//$NON-NLS-1$

	private static final String DOT_WAR = ".war";//$NON-NLS-1$

	private static final String DOT_JAR = ".jar";//$NON-NLS-1$

	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 (qp.getVersion() == JavaEEQuickPeek.JEE_5_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 (letting RARs fall through)
							switch (definedType) {
							case J2EEVersionConstants.EJB_TYPE: {
								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;
							}
							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;
							}
							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;
							}
							}
						}
					} 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(DOT_EAR)) {
				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(DOT_WAR)) {
				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(DOT_JAR)) {
				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");
						if (mainClassName != null) {
							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)) {
						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) {
			if (simpleLoadAdapter.containsArchiveResource(modelObjectPath)) {
				return true;
			}
			if (IArchive.EMPTY_MODEL_PATH == modelObjectPath) {
				modelObjectPath = deploymentDescriptorPath;
			}
			return emfHelper.containsModelObject(modelObjectPath);
		}

		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 {
			if (simpleLoadAdapter.containsModelObject(modelObjectPath)) {
				return simpleLoadAdapter.getModelObject(modelObjectPath);
			}
			if (IArchive.EMPTY_MODEL_PATH == modelObjectPath) {
				modelObjectPath = deploymentDescriptorPath;
			}
			return emfHelper.getModelObject(modelObjectPath);
		}

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

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

		public IArchiveLoadAdapter getWrappedLoadAdatper() {
			return simpleLoadAdapter;
		}

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