/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.commonarchivecore.internal.impl;



import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.impl.EFactoryImpl;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ApplicationClientFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ArchiveTypeDiscriminatorRegistry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ClientModuleRef;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveFactoryRegistry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchivePackage;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ConnectorModuleRef;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Container;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBModuleRef;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.RARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ReadOnlyDirectory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WebModuleRef;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveTypeDiscriminator;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.AppClient12ImportStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.DirectoryArchiveLoadStrategy;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.DirectoryArchiveLoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.Ear12ImportStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.EjbJar11ImportStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.NestedArchiveLoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.NullLoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.RarImportStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ReadOnlyDirectoryLoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.TempZipFileLoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.War22ImportStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.DeleteOnExitUtility;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseArchive;


/**
 * @generated
 */
public class CommonarchiveFactoryImpl extends EFactoryImpl implements CommonarchiveFactory {


	/**
	 * Creates the default factory implementation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public static CommonarchiveFactory init() {
		try {
			CommonarchiveFactory theCommonarchiveFactory = (CommonarchiveFactory)EPackage.Registry.INSTANCE.getEFactory("commonarchive.xmi"); 
			if (theCommonarchiveFactory != null) {
				return theCommonarchiveFactory;
			}
		}
		catch (Exception exception) {
			EcorePlugin.INSTANCE.log(exception);
		}
		return new CommonarchiveFactoryImpl();
	}

	protected Map openArchives;
	private static boolean delegateNeedsInit = true;
	private CommonarchiveFactory delegate = null;

	static {
		initPrereqs();
	}

	/**
	 *  
	 */
	public CommonarchiveFactoryImpl() {
		super();
		initDelegate();
	}

	/**
	 *  
	 */
	private void initDelegate() {
		if (delegateNeedsInit) {
			delegateNeedsInit = false;
			delegate = new CommonarchiveFactoryImpl() {

				public ApplicationClientFile createApplicationClientFile() {
					return createApplicationClientFileGen();
				}


				public ClientModuleRef createClientModuleRef() {
					return createClientModuleRefGen();
				}

				public ConnectorModuleRef createConnectorModuleRef() {
					return createConnectorModuleRefGen();
				}

				public EARFile createEARFile() {
					return createEARFileGen();
				}

				public EJBJarFile createEJBJarFile() {
					return createEJBJarFileGen();
				}

				public EJBModuleRef createEJBModuleRef() {
					return createEJBModuleRefGen();
				}

				public RARFile createRARFile() {
					return createRARFileGen();
				}

				public WARFile createWARFile() {
					return createWARFileGen();
				}

				public WebModuleRef createWebModuleRef() {
					return createWebModuleRefGen();
				}
			};
		}

	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public EObject create(EClass eClass) {
		switch (eClass.getClassifierID()) {
			case CommonarchivePackage.FILE: return createFile();
			case CommonarchivePackage.ARCHIVE: return createArchive();
			case CommonarchivePackage.EJB_JAR_FILE: return createEJBJarFile();
			case CommonarchivePackage.WAR_FILE: return createWARFile();
			case CommonarchivePackage.EAR_FILE: return createEARFile();
			case CommonarchivePackage.APPLICATION_CLIENT_FILE: return createApplicationClientFile();
			case CommonarchivePackage.READ_ONLY_DIRECTORY: return createReadOnlyDirectory();
			case CommonarchivePackage.RAR_FILE: return createRARFile();
			case CommonarchivePackage.EJB_MODULE_REF: return createEJBModuleRef();
			case CommonarchivePackage.WEB_MODULE_REF: return createWebModuleRef();
			case CommonarchivePackage.CLIENT_MODULE_REF: return createClientModuleRef();
			case CommonarchivePackage.CONNECTOR_MODULE_REF: return createConnectorModuleRef();
			default:
				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
		}
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public void archiveClosed(Archive aClosedArchive) {
		getOpenArchives().remove(aClosedArchive);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public void archiveOpened(Archive anOpenArchive) {
		getOpenArchives().put(anOpenArchive, null);
	}

	/**
	 * @deprecated Use {@link #getOpenArchivesDependingOn(Archive)}
	 */
	public boolean canClose(Archive anArchive) {
		return !getOpenArchivesDependingOn(anArchive).isEmpty();
	}

	public void closeOpenArchives() {
		if (getOpenArchives().isEmpty())
			return;
		List opened = new ArrayList(getOpenArchives().size());
		Iterator it = getOpenArchives().keySet().iterator();
		while (it.hasNext()) {
			opened.add(it.next());
		}
		for (int i = 0; i < opened.size(); i++) {
			Archive anArchive = (Archive) opened.get(i);
			anArchive.close();
		}
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public Archive copy(Archive anArchive) {
		return new ArchiveCopyUtility().copy(anArchive);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public ModuleFile copy(ModuleFile aModuleFile) {
		return new ArchiveCopyUtility().copy(aModuleFile);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public ApplicationClientFile createApplicationClientFileInitialized(java.lang.String uri) {
		ApplicationClientFile clientFile = createApplicationClientFile();
		initializeNewApplicationClientFile(clientFile, uri);
		return clientFile;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public Archive createArchiveInitialized(java.lang.String uri) {
		Archive anArchive = createArchive();
		initializeNewArchive(anArchive, uri);
		return anArchive;

	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public Archive createArchiveInitialized(ArchiveOptions options, java.lang.String uri) {
		Archive anArchive = createArchive();
		initializeNewArchive(anArchive, uri, options);
		return anArchive;

	}

	public LoadStrategy createChildLoadStrategy(String uri, LoadStrategy parent) throws java.io.IOException, java.io.FileNotFoundException {

		LoadStrategy childStrategy = null;
		if (parent.isDirectory()) {
			String dirName = ((DirectoryArchiveLoadStrategy) parent).getDirectoryUri();
			String qualifiedUri = ArchiveUtil.getOSUri(dirName, uri);
			childStrategy = createLoadStrategy(qualifiedUri);
		} else {
			childStrategy = createNestedLoadStrategy(uri, parent);
		}
		return childStrategy;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EARFile createEARFileInitialized(java.lang.String uri) {
		EARFile earFile = createEARFile();
		initializeNewEARFile(earFile, uri);
		return earFile;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EARFile createEARFileInitialized(ArchiveOptions options, java.lang.String uri) {
		EARFile earFile = createEARFile();
		initializeNewEARFile(earFile, uri, options);
		return earFile;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile createEJBJarFileInitialized(java.lang.String uri) {
		EJBJarFile ejbJarFile = createEJBJarFile();
		initializeNewEJBJarFile(ejbJarFile, uri);
		return ejbJarFile;

	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile createEJBJarFileInitialized(ArchiveOptions options, java.lang.String uri) {
		EJBJarFile ejbJarFile = createEJBJarFile();
		initializeNewEJBJarFile(ejbJarFile, uri, options);
		return ejbJarFile;

	}

	/**
	 * Returns a NullLoadStrategyImpl; used for new archives
	 */
	public LoadStrategy createEmptyLoadStrategy() {
		return new NullLoadStrategyImpl();
	}

	/**
	 * Helper method to dynamically build a load strategy from the file system. Determines whether
	 * the uri points to a jar file or directory and returns the appropriate strategy
	 */
	public LoadStrategy createLoadStrategy(String uri) throws FileNotFoundException, IOException {
		String filename = uri.replace('/', java.io.File.separatorChar);
		java.io.File file = new java.io.File(filename);
		if (!file.exists()) {
			throw new FileNotFoundException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.file_not_found_EXC_, (new Object[]{uri, file.getAbsolutePath()}))); // = "URI Name: {0}; File name: {1}"
		}
		if (file.isDirectory()) {
			return new DirectoryArchiveLoadStrategyImpl(uri);
		}
		return new org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl(file);
	}

	/**
	 * Create a load strategy for a nested archive; by default will extract the nested archive to a
	 * temp file for performance reasons. This is because random access to the zip entries in a
	 * nested archive is not supported by the java.util.zip package, and if the archive's contents
	 * are being modified, copied, etc, this is much faster. If a temp file can not be created, or
	 * if the archive is opened read only (for runtime), then use a NestedArchiveLoadStrategy, which
	 * retrieves the contents of a zip entry by sequentially searching a zip input stream
	 */
	public LoadStrategy createNestedLoadStrategy(String uri, LoadStrategy parent) {
		LoadStrategy loadStrategy = null;
		ArchiveOptions options = ((Archive) parent.getContainer()).getOptions();

		if (!options.isReadOnly(uri))
			loadStrategy = createTempZipFileStrategyIfPossible(uri, parent);

		if (loadStrategy == null)
			return new NestedArchiveLoadStrategyImpl(parent);
		return loadStrategy;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public RARFile createRARFileInitialized(java.lang.String uri) {
		RARFile rarFile = createRARFile();
		initializeNewRARFile(rarFile, uri);
		return rarFile;
	}

	public LoadStrategy createTempZipFileStrategyIfPossible(String uri, LoadStrategy parent) {

		if (!ArchiveUtil.shouldUseTempDirectoryForRead())
			return null;

		try {
			java.io.File tempFile = ArchiveUtil.createTempFile(uri);
			DeleteOnExitUtility.markForDeletion(tempFile);
			InputStream in = parent.getInputStream(uri);
			OutputStream out = new FileOutputStream(tempFile);
			ArchiveUtil.copy(in, out);
			return new TempZipFileLoadStrategyImpl(tempFile);
		} catch (IOException ex) {
			ArchiveUtil.inform(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.make_temp_file_WARN_, (new Object[]{uri})) + ex.getLocalizedMessage()); // = "Warning: Unable to create temp file for {0}.  This will impact performance."
		}
		return null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public WARFile createWARFileInitialized(java.lang.String uri) {
		WARFile warFile = createWARFile();
		initializeNewWARFile(warFile, uri);
		return warFile;
	}

	protected ArchiveOptions defaultOptions(LoadStrategy aLoadStrategy) {
		ArchiveOptions options = new ArchiveOptions();
		options.setLoadStrategy(aLoadStrategy);
		return options;
	}

	public static CommonarchiveFactory getActiveFactory() {
		CommonarchivePackage pkg = getPackage();
		if (pkg != null)
			return pkg.getCommonarchiveFactory();
		return null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public java.lang.String[] getManifestClassPathValues(java.lang.String uri) throws org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		String[] result = anArchive.getManifest().getClassPathTokenized();
		anArchive.close();
		return result;
	}

	/**
	 * Insert the method's description here. Creation date: (02/23/01 2:35:55 PM)
	 * 
	 * @return java.util.Map
	 */
	public java.util.Map getOpenArchives() {
		if (openArchives == null)
			openArchives = new WeakHashMap();
		return openArchives;
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public Set getOpenArchivesDependingOn(Archive anArchive) {
		Set dependents = new HashSet();
		Iterator opened = getOpenArchives().keySet().iterator();
		while (opened.hasNext()) {
			Archive openedArchive = (Archive) opened.next();
			if (openedArchive == anArchive)
				continue;
			if (!openedArchive.isIndexed())
				//**********Optimization***********
				//If the file list has never been built for the archive, we don't want to trigger
				// it now,
				//and we are sure that the archive is not preventing the parameter from closing
				continue;
			List files = openedArchive.getFiles();
			for (int i = 0; i < files.size(); i++) {
				File aFile = (File) files.get(i);
				if (aFile.getLoadingContainer() == anArchive) {
					Archive outermost = openedArchive;
					Container c = openedArchive.getContainer();
					while (c != null && c.isArchive()) {
						outermost = (Archive) c;
						c = c.getContainer();
					}
					dependents.add(outermost);
				}
			}
		}
		//Elements from one of the children (e.g., a module file in an ear) may have been copied to
		//another archive
		List nestedArchives = anArchive.getArchiveFiles();
		for (int i = 0; i < nestedArchives.size(); i++) {
			dependents.addAll(getOpenArchivesDependingOn((Archive) nestedArchives.get(i)));
		}
		return dependents;
	}

	protected static void initPrereqs() {
		org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveInit.invokePrereqInits(true);
		ArchiveTypeDiscriminator disc = RootArchiveTypeDescriminatorImpl.singleton();
		disc.addChild(Ear12ImportStrategyImpl.getDiscriminator());
		disc.addChild(War22ImportStrategyImpl.getDiscriminator());
		disc.addChild(AppClient12ImportStrategyImpl.getDiscriminator());
		disc.addChild(RarImportStrategyImpl.getDiscriminator());
		disc.addChild(RootEJBJarDescriminatorImpl.singleton());
	}

	public void initializeNewApplicationClientFile(ApplicationClientFile anArchive, String uri) {
		initializeNewModuleFile(anArchive, uri);
	}

	public void initializeNewArchive(Archive anArchive, String uri) {
		anArchive.setURI(uri);
		anArchive.setSize(0);
		anArchive.setLastModified(System.currentTimeMillis());
		anArchive.setDirectoryEntry(false);
		anArchive.setLoadStrategy(createEmptyLoadStrategy());
	}

	public void initializeNewEARFile(EARFile anArchive, String uri) {
		initializeNewModuleFile(anArchive, uri);
	}

	public void initializeNewEJBJarFile(EJBJarFile anArchive, String uri) {
		initializeNewModuleFile(anArchive, uri);
	}

	public void initializeNewModuleFile(ModuleFile anArchive, String uri) {
		initializeNewArchive(anArchive, uri);
		anArchive.makeDeploymentDescriptorResource();
	}

	public void initializeNewRARFile(RARFile anArchive, String uri) {
		initializeNewModuleFile(anArchive, uri);
	}

	public void initializeNewWARFile(WARFile anArchive, String uri) {
		initializeNewModuleFile(anArchive, uri);
	}

	public void initializeNewApplicationClientFile(ApplicationClientFile anArchive, String uri, ArchiveOptions options) {
		initializeNewModuleFile(anArchive, uri, options);
	}

	public void initializeNewArchive(Archive anArchive, String uri, ArchiveOptions options) {
		if (options.getLoadStrategy() == null) {
			try {
				options.setLoadStrategy(createEmptyLoadStrategy());
			} catch (Exception ex) {
				Logger.getLogger().logError(ex);
			}
		}

		anArchive.setURI(uri);
		anArchive.setSize(0);
		anArchive.setLastModified(System.currentTimeMillis());
		anArchive.setDirectoryEntry(false);
		anArchive.setLoadStrategy(options.getLoadStrategy());
		anArchive.setOptions(options);

	}

	public void initializeNewEARFile(EARFile anArchive, String uri, ArchiveOptions options) {
		initializeNewModuleFile(anArchive, uri, options);
	}

	public void initializeNewEJBJarFile(EJBJarFile anArchive, String uri, ArchiveOptions options) {
		initializeNewModuleFile(anArchive, uri, options);
	}

	public void initializeNewModuleFile(ModuleFile anArchive, String uri, ArchiveOptions options) {
		initializeNewArchive(anArchive, uri, options);
		anArchive.makeDeploymentDescriptorResource();
	}

	public void initializeNewRARFile(RARFile anArchive, String uri, ArchiveOptions options) {
		initializeNewModuleFile(anArchive, uri, options);
	}

	public void initializeNewWARFile(WARFile anArchive, String uri, ArchiveOptions options) {
		initializeNewModuleFile(anArchive, uri, options);
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public ApplicationClientFile openApplicationClientFile(ArchiveOptions options, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		ArchiveTypeDiscriminator disc = AppClient12ImportStrategyImpl.getDiscriminator();
		return (ApplicationClientFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public ApplicationClientFile openApplicationClientFile(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		ArchiveTypeDiscriminator disc = AppClient12ImportStrategyImpl.getDiscriminator();
		return (ApplicationClientFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public ApplicationClientFile openApplicationClientFile(String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		ArchiveTypeDiscriminator disc = AppClient12ImportStrategyImpl.getDiscriminator();
		return (ApplicationClientFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public Archive openArchive(ArchiveOptions options, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		return openSpecificArchive(anArchive, RootArchiveTypeDescriminatorImpl.singleton());
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public Archive openArchive(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		return openSpecificArchive(anArchive, RootArchiveTypeDescriminatorImpl.singleton());
	}

	/**
	 * openArchive(String uri) - open the archive by the passed name, setting up the appropriate
	 * strategies. Name may be a path to a jar, a zip, or a directory return the appropriate Archive
	 * type
	 */
	public Archive openArchive(java.lang.String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		return openSpecificArchive(anArchive, RootArchiveTypeDescriminatorImpl.singleton());
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public Archive openArchive(String uri, String extraClassPath) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		anArchive.setExtraClasspath(extraClassPath);
		return openSpecificArchive(anArchive, RootArchiveTypeDescriminatorImpl.singleton());
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public EARFile openEARFile(ArchiveOptions options, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		ArchiveTypeDiscriminator disc = Ear12ImportStrategyImpl.getDiscriminator();
		return (EARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EARFile openEARFile(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		ArchiveTypeDiscriminator disc = Ear12ImportStrategyImpl.getDiscriminator();
		return (EARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EARFile openEARFile(String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		ArchiveTypeDiscriminator disc = Ear12ImportStrategyImpl.getDiscriminator();
		return (EARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public EJBJarFile openEJB11JarFile(ArchiveOptions options, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		ArchiveTypeDiscriminator disc = EjbJar11ImportStrategyImpl.getDiscriminator();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile openEJB11JarFile(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		ArchiveTypeDiscriminator disc = EjbJar11ImportStrategyImpl.getDiscriminator();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile openEJB11JarFile(String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		ArchiveTypeDiscriminator disc = EjbJar11ImportStrategyImpl.getDiscriminator();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public EJBJarFile openEJBJarFile(ArchiveOptions options, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		RootEJBJarDescriminatorImpl disc = (RootEJBJarDescriminatorImpl) RootEJBJarDescriminatorImpl.singleton();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile openEJBJarFile(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		RootEJBJarDescriminatorImpl disc = (RootEJBJarDescriminatorImpl) RootEJBJarDescriminatorImpl.singleton();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile openEJBJarFile(LoadStrategy aLoadStrategy, String uri, String extraClassPath) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		anArchive.setExtraClasspath(extraClassPath);
		RootEJBJarDescriminatorImpl disc = (RootEJBJarDescriminatorImpl) RootEJBJarDescriminatorImpl.singleton();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile openEJBJarFile(String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		RootEJBJarDescriminatorImpl disc = (RootEJBJarDescriminatorImpl) RootEJBJarDescriminatorImpl.singleton();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public EJBJarFile openEJBJarFile(String uri, String extraClassPath) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		anArchive.setExtraClasspath(extraClassPath);
		RootEJBJarDescriminatorImpl disc = (RootEJBJarDescriminatorImpl) RootEJBJarDescriminatorImpl.singleton();
		return (EJBJarFile) openSpecificArchive(anArchive, disc);
	}

	public Archive openNestedArchive(LooseArchive loose, Archive parent) throws OpenFailureException {
		String uri = loose.getUri();
		try {
			if(loose.getBinariesPath() == null){
				throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.open_nested_EXC_, (new Object[] {uri,parent.getURI()})), null); // = "Could not open the nested archive "{0}" in "{1}""
			}
			LoadStrategy childStrategy = createLoadStrategy(loose.getBinariesPath());
			childStrategy.setLooseArchive(loose);
			ArchiveOptions options = parent.getOptions().cloneWith(childStrategy, loose.getUri());
			return primOpenArchive(options, uri);
		} catch (IOException ex) {
			throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.open_nested_EXC_, (new Object[]{uri, parent.getURI()})), ex); // = "Could not open the nested archive "{0}" in "{1}""
		}
	}

	/**
	 * @see CommonarchiveFactory
	 */
	public Archive openNestedArchive(String uri, Archive parent) throws OpenFailureException {
		try {
			LoadStrategy childStrategy = createChildLoadStrategy(uri, parent.getLoadStrategy());
			ArchiveOptions options = parent.getOptions().cloneWith(childStrategy, uri);
			if (options.shouldDiscriminateNestedArchives())
				return openArchive(options, uri);
			return primOpenArchive(options, uri);
		} catch (IOException ex) {
			throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.open_nested_EXC_, (new Object[]{uri, parent.getURI()})), ex); // = "Could not open the nested archive "{0}" in "{1}""
		}
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public RARFile openRARFile(ArchiveOptions options, java.lang.String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		ArchiveTypeDiscriminator disc = RarImportStrategyImpl.getDiscriminator();
		return (RARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public RARFile openRARFile(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		ArchiveTypeDiscriminator disc = RarImportStrategyImpl.getDiscriminator();
		return (RARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public RARFile openRARFile(String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		ArchiveTypeDiscriminator disc = RarImportStrategyImpl.getDiscriminator();
		return (RARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * openReadOnlyDirectory method comment.
	 */
	public ReadOnlyDirectory openReadOnlyDirectory(java.lang.String uri) throws java.io.IOException {
		java.io.File aFile = new java.io.File(uri);
		if (!aFile.exists())
			throw new FileNotFoundException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.could_not_find_dir_EXC_, (new Object[]{uri}))); // = "Unable to open directory "
		if (!aFile.isDirectory())
			throw new IOException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.not_a_dir_EXC_, (new Object[]{uri}))); // = "Unable to open directory because file is not a directory :"
		LoadStrategy strategy = new ReadOnlyDirectoryLoadStrategyImpl(uri);
		ReadOnlyDirectory container = createReadOnlyDirectory();
		container.setURI(uri);
		container.setLoadStrategy(strategy);
		container.setLastModified(aFile.lastModified());
		return container;
	}

	/**
	 * Take the primitive archive and run it through the list of discriminators to convert it to the
	 * correct specialized type; after after conversion, tell the archive to initalize itself if
	 * necessary.
	 */
	protected Archive openSpecificArchive(Archive anArchive, ArchiveTypeDiscriminator disc) throws OpenFailureException {
		if (!disc.canImport(anArchive)) {
			anArchive.close();
			throw new OpenFailureException(disc.getUnableToOpenMessage());
		}
		Archive specificArchive = disc.openArchive(anArchive);
		specificArchive.initializeAfterOpen();
		return specificArchive;
	}

	/**
	 * Special case for ejb jar files, because of the need to support non-compliant 1.0 jars
	 */
	protected Archive openSpecificArchive(Archive anArchive, RootEJBJarDescriminatorImpl disc) throws OpenFailureException {
		Archive specific = openSpecificArchive(anArchive, (ArchiveTypeDiscriminator) disc);
		if (specific == anArchive) {
			//The discriminator failed to convert the archve to an ejb jar file
			anArchive.close();
			throw new OpenFailureException(disc.getUnableToOpenMessage());
		}
		return specific;
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public WARFile openWARFile(ArchiveOptions options, java.lang.String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(options, uri);
		ArchiveTypeDiscriminator disc = War22ImportStrategyImpl.getDiscriminator();
		return (WARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public WARFile openWARFile(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(aLoadStrategy, uri);
		ArchiveTypeDiscriminator disc = War22ImportStrategyImpl.getDiscriminator();
		return (WARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public WARFile openWARFile(String uri) throws OpenFailureException {
		Archive anArchive = primOpenArchive(uri);
		ArchiveTypeDiscriminator disc = War22ImportStrategyImpl.getDiscriminator();
		return (WARFile) openSpecificArchive(anArchive, disc);
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public Archive primOpenArchive(ArchiveOptions options, String uri) throws OpenFailureException {
		if (options.getLoadStrategy() == null) {
			try {
				options.setLoadStrategy(createLoadStrategy(uri));
			} catch (IOException ex) {
				throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.could_not_open_EXC_, (new Object[]{uri})), ex); // = "Could not open "
			}
		}
		Archive anArchive = createArchive();
		anArchive.setURI(uri);
		anArchive.setOriginalURI(uri);
		anArchive.setLoadStrategy(options.getLoadStrategy());
		anArchive.setOptions(options);
		ArchiveTypeDiscriminatorRegistry.getInstance().contributeTypes(anArchive);
		return anArchive;
	}

	/**
	 * open the archive, setting up the appropriate strategies, using the loadStrategy passed in;
	 * URI still necessary so the archive has a name, but it will not be used for io.
	 */
	public Archive primOpenArchive(LoadStrategy aLoadStrategy, String uri) throws OpenFailureException {
		return primOpenArchive(defaultOptions(aLoadStrategy), uri);
	}

	/**
	 * @see com.ibm.etools.commonarchive.CommonarchiveFactory
	 */
	public Archive primOpenArchive(String uri) throws OpenFailureException {
		return primOpenArchive(new ArchiveOptions(), uri);
	}

	protected void setOpenArchives(java.util.Map newOpenArchives) {
		openArchives = newOpenArchives;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public WARFile createWARFileGen() {
		WARFileImpl warFile = new WARFileImpl();
		return warFile;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public EJBJarFile createEJBJarFileGen() {
		EJBJarFileImpl ejbJarFile = new EJBJarFileImpl();
		return ejbJarFile;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public ApplicationClientFile createApplicationClientFileGen() {
		ApplicationClientFileImpl applicationClientFile = new ApplicationClientFileImpl();
		return applicationClientFile;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public EARFile createEARFileGen() {
		EARFileImpl earFile = new EARFileImpl();
		return earFile;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public RARFile createRARFileGen() {
		RARFileImpl rarFile = new RARFileImpl();
		return rarFile;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public File createFile() {
		FileImpl file = new FileImpl();
		return file;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public ReadOnlyDirectory createReadOnlyDirectory() {
		ReadOnlyDirectoryImpl readOnlyDirectory = new ReadOnlyDirectoryImpl();
		return readOnlyDirectory;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public CommonarchivePackage getCommonarchivePackage() {
		return (CommonarchivePackage)getEPackage();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @deprecated
	 * @generated
	 */
	public static CommonarchivePackage getPackage() {
		return CommonarchivePackage.eINSTANCE;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public EJBModuleRef createEJBModuleRefGen() {
		EJBModuleRefImpl ejbModuleRef = new EJBModuleRefImpl();
		return ejbModuleRef;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public WebModuleRef createWebModuleRefGen() {
		WebModuleRefImpl webModuleRef = new WebModuleRefImpl();
		return webModuleRef;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public ClientModuleRef createClientModuleRefGen() {
		ClientModuleRefImpl clientModuleRef = new ClientModuleRefImpl();
		return clientModuleRef;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public ConnectorModuleRef createConnectorModuleRefGen() {
		ConnectorModuleRefImpl connectorModuleRef = new ConnectorModuleRefImpl();
		return connectorModuleRef;
	}

	public ClientModuleRef createClientModuleRef(ApplicationClientFile clientFile) {
		ClientModuleRef ref = createClientModuleRef();
		ref.setModuleFile(clientFile);
		return ref;
	}

	/*
	 * @see CommonarchiveFactory#createConnectorModuleRef(RARFile)
	 */
	public ConnectorModuleRef createConnectorModuleRef(RARFile rarFile) {
		ConnectorModuleRef ref = createConnectorModuleRef();
		ref.setModuleFile(rarFile);
		return ref;

	}

	/*
	 * @see CommonarchiveFactory#createEJBModuleRef(EJBJarFile)
	 */
	public EJBModuleRef createEJBModuleRef(EJBJarFile ejbJarFile) {
		EJBModuleRef ref = createEJBModuleRef();
		ref.setModuleFile(ejbJarFile);
		return ref;
	}

	/*
	 * @see CommonarchiveFactory#createWebModuleRef(WARFile)
	 */
	public WebModuleRef createWebModuleRef(WARFile warFile) {
		WebModuleRef ref = createWebModuleRef();
		ref.setModuleFile(warFile);
		return ref;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public Archive createArchive() {
		ArchiveImpl archive = new ArchiveImpl();
		return archive;
	}

	public ApplicationClientFile createApplicationClientFile() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createApplicationClientFile();
	}


	public ClientModuleRef createClientModuleRef() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createClientModuleRef();
	}

	public ConnectorModuleRef createConnectorModuleRef() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createConnectorModuleRef();
	}

	public EARFile createEARFile() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createEARFile();
	}

	public EJBJarFile createEJBJarFile() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createEJBJarFile();
	}

	public EJBModuleRef createEJBModuleRef() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createEJBModuleRef();
	}

	public RARFile createRARFile() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createRARFile();
	}

	public WARFile createWARFile() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createWARFile();
	}

	public WebModuleRef createWebModuleRef() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory().createWebModuleRef();
	}

	/**
	 * @return
	 */
	public CommonarchiveFactory getDelegate() {
		return delegate;
	}

}
