/*******************************************************************************
 * Copyright (c) 2001, 2004 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.impl.EFactoryImpl;
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.looseconfig.LooseArchive;
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;


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


	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"); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * @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("file_not_found_EXC_", (new Object[]{uri, file.getAbsolutePath()}))); //$NON-NLS-1$ = "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);
			tempFile.deleteOnExit();
			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("make_temp_file_WARN_", (new Object[]{uri})) + ex.getLocalizedMessage()); //$NON-NLS-1$ = "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 {
			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("open_nested_EXC_", (new Object[]{uri, parent.getURI()})), ex); //$NON-NLS-1$ = "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("open_nested_EXC_", (new Object[]{uri, parent.getURI()})), ex); //$NON-NLS-1$ = "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("could_not_find_dir_EXC_", (new Object[]{uri}))); //$NON-NLS-1$ = "Unable to open directory "
		if (!aFile.isDirectory())
			throw new IOException(CommonArchiveResourceHandler.getString("not_a_dir_EXC_", (new Object[]{uri}))); //$NON-NLS-1$ = "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("could_not_open_EXC_", (new Object[]{uri})), ex); //$NON-NLS-1$ = "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 -->
	 * 
	 * @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;
	}

}
