/*******************************************************************************
 * 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.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.jst.j2ee.application.Application;
import org.eclipse.jst.j2ee.application.ApplicationFactory;
import org.eclipse.jst.j2ee.application.ApplicationPackage;
import org.eclipse.jst.j2ee.application.ConnectorModule;
import org.eclipse.jst.j2ee.application.EjbModule;
import org.eclipse.jst.j2ee.application.JavaClientModule;
import org.eclipse.jst.j2ee.application.Module;
import org.eclipse.jst.j2ee.application.WebModule;
import org.eclipse.jst.j2ee.client.ApplicationClient;
import org.eclipse.jst.j2ee.client.internal.impl.ApplicationClientResourceFactory;
import org.eclipse.jst.j2ee.common.EjbRef;
import org.eclipse.jst.j2ee.common.SecurityRole;
import org.eclipse.jst.j2ee.common.internal.impl.J2EEResourceFactoryRegistry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchivePackage;
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.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleRef;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ArchiveWrappedException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DeploymentDescriptorLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DuplicateObjectException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.EmptyResourceException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ObjectNotFoundException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ResourceLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseArchive;
import org.eclipse.jst.j2ee.ejb.AssemblyDescriptor;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EJBResource;
import org.eclipse.jst.j2ee.ejb.EjbPackage;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.internal.impl.EJBJarResourceFactory;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.XMLResource;
import org.eclipse.jst.j2ee.jca.Connector;
import org.eclipse.jst.j2ee.jca.internal.impl.ConnectorResourceFactory;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.j2ee.webapplication.internal.impl.WebAppResourceFactory;
import org.eclipse.wst.common.internal.emf.utilities.EtoolsCopyUtility;


/**
 * @generated
 */
public class EARFileImpl extends ModuleFileImpl implements EARFile {

	/**
	 * Internal; clients should use {@link #getModuleRef(Module)}
	 */
	public ModuleFile getModuleFile(Module moduleDescriptor) {
		ModuleRef ref = getModuleRef(moduleDescriptor);
		return (ref == null) ? null : ref.getModuleFile();
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public ModuleFile addCopy(ModuleFile aModuleFile) throws DuplicateObjectException {
		Object result = primAddCopyRef(aModuleFile);
		if (result instanceof ModuleRef)
			return ((ModuleRef) result).getModuleFile();

		return (ModuleFile) result;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected Application deploymentDescriptor = null;
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected EList moduleRefs = null;

	public EARFileImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	protected EClass eStaticClass() {
		return CommonarchivePackage.eINSTANCE.getEARFile();
	}

	public Archive addCopy(Archive anArchive) throws org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DuplicateObjectException {
		if (anArchive.isModuleFile())
			return addCopy((ModuleFile) anArchive);
		Archive copy = super.addCopy(anArchive);
		copy.initializeClassLoader();
		return copy;
	}

	protected Object primAddCopyRef(ModuleFile aModuleFile) throws DuplicateObjectException {
		//force this list to get initialized before the add
		EList refs = getModuleRefs();

		if (aModuleFile.isEARFile())
			//If it's an ear then just treat it like any other archive
			return (ModuleFile) super.addCopy(aModuleFile);
		checkAddValid(aModuleFile);
		ModuleFile copy = getCommonArchiveFactory().copy(aModuleFile);
		Module newModule = createModuleForCopying(aModuleFile);
		getFiles().add(copy);
		copy.initializeClassLoader();
		if (!copy.getURI().equals(newModule.getUri()))
			copy.setURI(newModule.getUri());

		getDeploymentDescriptor().getModules().add(newModule);
		ModuleRef aRef = createModuleRef(newModule, copy);
		refs.add(aRef);
		return aRef;
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public ModuleRef addCopyRef(ModuleFile aModuleFile) throws DuplicateObjectException {
		Object result = primAddCopyRef(aModuleFile);
		if (result instanceof ModuleRef)
			return (ModuleRef) result;

		return null;
	}



	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public SecurityRole addCopy(SecurityRole aRole, Module aModule) throws DuplicateObjectException {
		EObject dd = null;
		try {
			dd = getDeploymentDescriptor(aModule);
		} catch (Exception e) {
			throw new DeploymentDescriptorLoadException(CommonArchiveResourceHandler.getString("dd_in_ear_load_EXC_", (new Object[]{aModule.getUri(), getURI()})), e); //$NON-NLS-1$ = "Exception occurred loading deployment descriptor for module "{0}" in ear file "{1}""
		}
		String roleName = aRole.getRoleName();
		SecurityRole copy = (SecurityRole) EtoolsCopyUtility.createCopy(aRole);
		if (aModule.isEjbModule()) {
			EJBJar ejbJar = (EJBJar) dd;
			if (ejbJar.containsSecurityRole(roleName))
				throw new DuplicateObjectException(CommonArchiveResourceHandler.getString("dup_sec_role_module_EXC_", (new Object[]{aModule.getUri(), roleName})), ejbJar.getAssemblyDescriptor().getSecurityRoleNamed(roleName)); //$NON-NLS-1$ = "Deployment descriptor for {0} already contains a security role named {1}"
			getAssemblyDescriptorAddIfNecessary(ejbJar).getSecurityRoles().add(copy);
		} else if (aModule.isWebModule()) {
			WebApp webApp = (WebApp) dd;
			if (webApp.containsSecurityRole(roleName))
				throw new DuplicateObjectException(CommonArchiveResourceHandler.getString("dup_sec_role_module_EXC_", (new Object[]{aModule.getUri(), roleName})), webApp.getSecurityRoleNamed(roleName));//$NON-NLS-1$ = "Deployment descriptor for {0} already contains a security role named {1}"
			webApp.getSecurityRoles().add(copy);
		}
		addCopyIfNotExists(aRole);
		return copy;
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public SecurityRole addCopyIfNotExists(SecurityRole aRole) {
		Application dd = getDeploymentDescriptor();
		SecurityRole copy = null;
		if (!dd.containsSecurityRole(aRole.getRoleName())) {
			copy = (SecurityRole) EtoolsCopyUtility.createCopy(aRole);
			dd.getSecurityRoles().add(copy);
		}
		return copy;
	}

	protected void checkDuplicate(String aUri) throws DuplicateObjectException {
		if (isDuplicate(aUri))
			throw new DuplicateObjectException(CommonArchiveResourceHandler.getString("dup_resource_EXC_", (new Object[]{aUri, getURI()}))); //$NON-NLS-1$ = "Resource named "{0}" already exists in archive "{1}""
	}


	protected Module createModuleForCopying(ModuleFile aModuleFile) {
		Module aModule = null;
		if (aModuleFile.isWARFile()) {
			aModule = getApplicationFactory().createWebModule();
		} else if (aModuleFile.isEJBJarFile()) {
			aModule = getApplicationFactory().createEjbModule();
		} else if (aModuleFile.isApplicationClientFile()) {
			aModule = getApplicationFactory().createJavaClientModule();
		} else if (aModuleFile.isRARFile()) {
			aModule = getApplicationFactory().createConnectorModule();
		}
		aModule.setUri(aModuleFile.getURI());
		return aModule;
	}

	/**
	 * Retrieves the deployment descriptor root element for the specified module. Takes into account
	 * altDD indirection.
	 * 
	 * @return Only return null if an altDD is not defined.
	 */
	public EObject getAltDeploymentDescriptor(Module aModule) throws FileNotFoundException, ResourceLoadException, EmptyResourceException {
		// Look for altDD
		String altDD = aModule.getAltDD();
		if (ArchiveUtil.isNullOrEmpty(altDD))
			return null;
		if (!isMofResourceLoaded(altDD.trim()))
			registerResourceFactory(aModule, altDD);
		XMLResource ddRes = (XMLResource) getMofResource(altDD.trim());
		if (!ddRes.isAlt()) {
			ddRes.setIsAlt(true);
			ddRes.setApplication(getDeploymentDescriptor());
		}
		return ArchiveUtil.getRoot(ddRes);

	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public java.util.List getApplicationClientFiles() {
		List clientFiles = new ArrayList();
		List fileList = getFiles();
		for (int i = 0; i < fileList.size(); i++) {
			File aFile = (File) fileList.get(i);
			if (aFile.isApplicationClientFile()) {
				clientFiles.add(aFile);
			}
		}
		return clientFiles;
	}

	protected ApplicationFactory getApplicationFactory() {
		return ((ApplicationPackage) EPackage.Registry.INSTANCE.getEPackage(ApplicationPackage.eNS_URI)).getApplicationFactory();
	}

	protected AssemblyDescriptor getAssemblyDescriptorAddIfNecessary(EJBJar ejbJar) {
		AssemblyDescriptor ad = ejbJar.getAssemblyDescriptor();
		if (ad == null) {
			ad = ((EjbPackage) EPackage.Registry.INSTANCE.getEPackage(EjbPackage.eNS_URI)).getEjbFactory().createAssemblyDescriptor();
			ejbJar.setAssemblyDescriptor(ad);
		}
		return ad;
	}


	/**
	 * @throws DeploymentDescriptorLoadException -
	 *             is a runtime exception, because we can't override the signature of the generated
	 *             methods
	 */
	public Application getDeploymentDescriptor() throws DeploymentDescriptorLoadException {
		Application dd = this.getDeploymentDescriptorGen();
		if (dd == null && canLazyInitialize()) {
			try {
				getImportStrategy().importMetaData();
			} catch (Exception e) {
				throw new DeploymentDescriptorLoadException(getDeploymentDescriptorUri(), e);
			}
		}
		return this.getDeploymentDescriptorGen();
	}

	/**
	 * Retrieves the deployment descriptor root element for the specified module. Takes into account
	 * altDD indirection.
	 */
	public Connector getDeploymentDescriptor(ConnectorModule aModule) throws FileNotFoundException, ResourceLoadException, EmptyResourceException {
		return (Connector) getDeploymentDescriptor((Module) aModule);
	}

	/**
	 * Retrieves the deployment descriptor root element for the specified module. Takes into account
	 * altDD indirection.
	 */
	public EJBJar getDeploymentDescriptor(EjbModule aModule) throws FileNotFoundException, ResourceLoadException, EmptyResourceException {
		return (EJBJar) getDeploymentDescriptor((Module) aModule);
	}

	/**
	 * Retrieves the deployment descriptor root element for the specified module. Takes into account
	 * altDD indirection.
	 */
	public ApplicationClient getDeploymentDescriptor(JavaClientModule aModule) throws FileNotFoundException, ResourceLoadException, EmptyResourceException {
		return (ApplicationClient) getDeploymentDescriptor((Module) aModule);
	}

	/**
	 * Retrieves the deployment descriptor root element for the specified module. Takes into account
	 * altDD indirection.
	 */
	public EObject getDeploymentDescriptor(Module aModule) throws FileNotFoundException, ResourceLoadException, EmptyResourceException {
		EObject dd = getAltDeploymentDescriptor(aModule);
		if (dd == null)
			dd = getModuleFile(aModule).getStandardDeploymentDescriptor();
		return dd;
	}

	/**
	 * Retrieves the deployment descriptor root element for the specified module. Takes into account
	 * altDD indirection.
	 */
	public WebApp getDeploymentDescriptor(WebModule aModule) throws FileNotFoundException, ResourceLoadException, EmptyResourceException {
		return (WebApp) getDeploymentDescriptor((Module) aModule);
	}

	/**
	 * @see com.ibm.etools.commonarchive.ModuleFile
	 */
	public java.lang.String getDeploymentDescriptorUri() {
		return J2EEConstants.APPLICATION_DD_URI;
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public java.util.List getEJBJarFiles() {
		List ejbJarFiles = new ArrayList();
		List fileList = getFiles();
		for (int i = 0; i < fileList.size(); i++) {
			File aFile = (File) fileList.get(i);
			if (aFile.isEJBJarFile()) {
				ejbJarFiles.add(aFile);
			}
		}
		return ejbJarFiles;
	}

	/**
	 * Return an enterprise bean referenced by the EjbRef, if one exists. The ejb-link value of the
	 * ref must equate to a named enterprise bean contained in the jar; otherwise return null.
	 * Returns the first hit found; assumption that the ejb names are unique within the scope of the
	 * ear file. This will likely be replaced with a better way for dereferencing ejb refs.
	 * 
	 * Can be used with ejb 1.1 references only.
	 * 
	 * @deprecated {@link#getEnterpiseBeanFromRef(EjbRef ref, String moduleUri )
	 * @param EjbRef
	 *            ref - An ejb reference
	 * @return EnterpriseBean
	 */
	public EnterpriseBean getEnterpiseBeanFromRef(EjbRef ref) {
		String link = ref.getLink();
		if (link == null) {
			return null;
		}
		List jarFiles = getEJBJarFiles();
		for (int i = 0; i < jarFiles.size(); i++) {
			EnterpriseBean bean = ((EJBJarFile) jarFiles.get(i)).getDeploymentDescriptor().getEnterpriseBeanNamed(link);
			if (bean != null) {
				return bean;
			}
		}
		return null;
	}

	/**
	 * Return an enterprise bean referenced by the EjbRef, if one exists. The ejb-link value of the
	 * ref must equate to a named enterprise bean contained in the jar; otherwise return null.
	 * Returns the first hit found; assumption that the ejb names are unique within the scope of the
	 * ear file. This will likely be replaced with a better way for dereferencing ejb refs
	 * 
	 * Can be used with ejb 1.1 & ejb 2.0 references.
	 * 
	 * @param EjbRef
	 *            ref - An ejb reference
	 * @param String
	 *            moduleUri - The module uri
	 * @return EnterpriseBean
	 */
	public EnterpriseBean getEnterpiseBeanFromRef(EjbRef ref, String moduleUri) {
		String link = ref.getLink();
		if (link == null) {
			return null;
		}// if

		if (link.indexOf('#') == -1) {
			EnterpriseBean linkedEJB = null;
			XMLResource res = (XMLResource) ref.eResource();
			if (res instanceof EJBResource) {
				//Must be in an EJB JAR to be here
				EJBJar jar = ((EJBResource) res).getEJBJar();
				if (jar != null)
					linkedEJB = jar.getEnterpiseBeanFromRef(ref);
			}
			if (linkedEJB == null) {
				List jarFiles = getEJBJarFiles();
				for (int i = 0; i < jarFiles.size(); i++) {
					linkedEJB = ((EJBJarFile) jarFiles.get(i)).getDeploymentDescriptor().getEnterpriseBeanNamed(link);
					if (linkedEJB != null) {
						return linkedEJB;
					}// if
				}// for
			} else
				return linkedEJB;
		} else {
			//Grab the ejb name and ejb jar name from the link
			String ejbBeanName = link.substring(link.indexOf("#") + 1, link.length()); //$NON-NLS-1$
			String ejbJarName = link.substring(0, link.indexOf("#")); //$NON-NLS-1$

			if (ejbBeanName != null && ejbJarName != null) {
				//Get the uri of the jar name.
				String ejbJarUri = ArchiveUtil.deriveEARRelativeURI(ejbJarName, moduleUri);
				if (ejbJarUri != null) {
					try {
						//Get the actual jar file
						File aFile = getFile(ejbJarUri);
						if (aFile == null || !aFile.isEJBJarFile())
							return null;

						EJBJarFile jarFile = (EJBJarFile) getFile(ejbJarUri);
						List ejbs = jarFile.getDeploymentDescriptor().getEnterpriseBeans();
						//Check if any of the beans in the list match the given ejb bean name give
						// in
						//the link
						if (ejbs != null && !ejbs.isEmpty()) {
							Iterator it = ejbs.iterator();
							while (it.hasNext()) {
								EnterpriseBean ejbBean = (EnterpriseBean) it.next();
								if (ejbBean != null && ejbBean.getName().equals(ejbBeanName)) {
									return ejbBean;
								}// if
							}// while
						}// if
					} catch (FileNotFoundException fe) {
						return null;
					}// try
				}// if
			}// if
		}// if
		return null;
	}// getEnterpiseBeanFromRef

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public Module getModule(String aUri, String altDD) {
		return getDeploymentDescriptor().getModule(aUri, altDD);
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public ModuleRef getModuleRef(Module moduleDescriptor) {
		List refs = getModuleRefs();
		for (int i = 0; i < refs.size(); i++) {
			ModuleRef ref = (ModuleRef) refs.get(i);
			if (ref.getModule() == moduleDescriptor)
				return ref;
		}
		return null;
	}

	/**
	 * Return a filtered list of the archives
	 */
	public List getModuleFiles() {
		List moduleFiles = new ArrayList();
		List fileList = getFiles();
		for (int i = 0; i < fileList.size(); i++) {
			File aFile = (File) fileList.get(i);
			if (aFile.isModuleFile()) {
				moduleFiles.add(aFile);
			}
		}
		return moduleFiles;
	}

	protected ArchiveOptions getOptionsForOpening(String aUri) throws IOException {

		LoadStrategy strategy = getCommonArchiveFactory().createChildLoadStrategy(aUri, getLoadStrategy());
		return getOptions().cloneWith(strategy, aUri);
	}

	protected ArchiveOptions getOptionsForOpening(LooseArchive loose) throws IOException, OpenFailureException{
		if(loose.getBinariesPath() == null){
			throw new OpenFailureException(CommonArchiveResourceHandler.getString("open_nested_EXC_", (new Object[] {loose.getUri(), getURI()})), null); //$NON-NLS-1$ = "Could not open the nested archive "{0}" in "{1}""
		}
		LoadStrategy strategy = getCommonArchiveFactory().createLoadStrategy(loose.getBinariesPath());
		strategy.setLooseArchive(loose);
		return getOptions().cloneWith(strategy, loose.getUri());
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public java.util.List getRARFiles() {
		List rarFiles = new ArrayList();
		List fileList = getFiles();
		for (int i = 0; i < fileList.size(); i++) {
			File aFile = (File) fileList.get(i);
			if (aFile.isRARFile()) {
				rarFiles.add(aFile);
			}
		}
		return rarFiles;
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public EList getRolesFromAllModules() {
		EList roleList = new org.eclipse.emf.common.util.BasicEList();
		List modules = getDeploymentDescriptor().getModules();
		for (int i = 0, n = modules.size(); i < n; i++) {
			Module aModule = (Module) modules.get(i);
			EList roles = getRolesFromModule(aModule);
			for (int j = 0, m = roles.size(); j < m; j++) {
				roleList.add(roles.get(j));
			}
		}
		return roleList;
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public EList getRolesFromModule(Module aModule) {
		EList roleList = new org.eclipse.emf.common.util.BasicEList();
		try {
			if (aModule.isWebModule())
				roleList = getDeploymentDescriptor((WebModule) aModule).getSecurityRoles();
			else if (aModule.isEjbModule())
				roleList = getAssemblyDescriptorAddIfNecessary(getDeploymentDescriptor((EjbModule) aModule)).getSecurityRoles();
		} catch (Exception e) {
			throw new DeploymentDescriptorLoadException(CommonArchiveResourceHandler.getString("dd_in_ear_load_EXC_", (new Object[]{aModule.getUri(), getURI()})), e); //$NON-NLS-1$ = "Exception occurred loading deployment descriptor for module "{0}" in ear file "{1}""
		}
		return roleList;
	}

	/**
	 * Return the DeployementDescriptor.
	 */
	public EObject getStandardDeploymentDescriptor() throws DeploymentDescriptorLoadException {
		return getDeploymentDescriptor();
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public java.util.List getWARFiles() {
		List warFiles = new ArrayList();
		List fileList = getFiles();
		for (int i = 0; i < fileList.size(); i++) {
			File aFile = (File) fileList.get(i);
			if (aFile.isWARFile()) {
				warFiles.add(aFile);
			}
		}
		return warFiles;
	}

	public void initializeAfterOpen() {
		super.initializeAfterOpen();
	}

	public boolean isDeploymentDescriptorSet() {
		return deploymentDescriptor != null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.File
	 */
	public boolean isEARFile() {
		return true;
	}

	/**
	 * Return true if super returns true, or return whether the app dd contains a module having the
	 * uri
	 */
	public boolean isNestedArchive(String aUri) {
		if (super.isNestedArchive(aUri))
			return true;
		return getDeploymentDescriptor().getFirstModule(aUri) != null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.impl.ModuleFileImpl
	 */
	public org.eclipse.emf.ecore.EObject makeDeploymentDescriptor(XMLResource resource) {
		Application appl = ((ApplicationPackage) EPackage.Registry.INSTANCE.getEPackage(ApplicationPackage.eNS_URI)).getApplicationFactory().createApplication();
		resource.setID(appl, J2EEConstants.APPL_ID);
		setDeploymentDescriptorGen(appl);
		resource.getContents().add(appl);
		return appl;
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive
	 */
	public Archive openNestedArchive(LooseArchive loose) throws OpenFailureException {

		Module m = getDeploymentDescriptor().getFirstModule(loose.getUri());
		if (m == null)
			return super.openNestedArchive(loose);

		try {
			ArchiveOptions archiveOptions = getOptionsForOpening(loose);
			return openNestedArchive(m, archiveOptions);
		} catch (java.io.IOException ex) {
			//Probably the file did not exist; silently fail, per request from WS runtime
			//More than likely a failure is going to occur down the road when a ModuleFile for a
			// Module
			//in the dd is requested
		}
		return null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive
	 */
	public Archive openNestedArchive(String aUri) throws OpenFailureException {

		Module m = getDeploymentDescriptor().getFirstModule(aUri);
		if (m == null)
			return super.openNestedArchive(aUri);

		try {
			ArchiveOptions archiveOptions = getOptionsForOpening(aUri);
			return openNestedArchive(m, archiveOptions);
		} catch (java.io.IOException ex) {
			//Probably the file did not exist; silently fail, per request from WS runtime
			//More than likely a failure is going to occur down the road when a ModuleFile for a
			// Module
			//in the dd is requested
		}
		return null;
	}

	protected Archive openNestedArchive(Module m, ArchiveOptions archiveOptions) throws OpenFailureException {
		String aUri = m.getUri();

		try {
			/*
			 * Since we have a clue about the type of archive to open Use the appropriate open
			 * method, so if a failure occurrs, we can get a more specific message
			 */
			if (m.isWebModule())
				return getCommonArchiveFactory().openWARFile(archiveOptions, aUri);
			else if (m.isEjbModule())
				return getCommonArchiveFactory().openEJBJarFile(archiveOptions, aUri);
			else if (m.isJavaModule())
				return getCommonArchiveFactory().openApplicationClientFile(archiveOptions, aUri);
			else if (m.isConnectorModule())
				return getCommonArchiveFactory().openRARFile(archiveOptions, aUri);

		} catch (OpenFailureException ex) {
			throw new OpenFailureException(CommonArchiveResourceHandler.getString("nested_open_fail_EXC_", (new Object[]{aUri, getURI()})), ex); //$NON-NLS-1$ = "Unable to open module file "{0}" in EAR file "{1}""
		}
		//Should never reach the code below
		return null;
	}

	/**
	 * @see EARFile
	 */
	public void pushDownRole(SecurityRole role) {
		if (role == null)
			throw new IllegalArgumentException(CommonArchiveResourceHandler.getString("Parameter_should_not_be_nu_EXC_")); //$NON-NLS-1$ = "Parameter should not be null"

		List modules = getDeploymentDescriptor().getModules();
		for (int i = 0; i < modules.size(); i++) {
			Module m = (Module) modules.get(i);
			pushDownRole(role, m);
		}
	}

	/**
	 * @see EARFile
	 */
	public void pushDownRole(SecurityRole role, Module aModule) {
		try {
			if (aModule.isWebModule()) {
				WebApp dd = getDeploymentDescriptor((WebModule) aModule);
				if (dd.getSecurityRoleNamed(role.getRoleName()) == null)
					dd.getSecurityRoles().add(EtoolsCopyUtility.createCopy(role));
			} else if (aModule.isEjbModule()) {
				AssemblyDescriptor assembly = getAssemblyDescriptorAddIfNecessary(getDeploymentDescriptor((EjbModule) aModule));
				if (assembly.getSecurityRoleNamed(role.getRoleName()) == null)
					assembly.getSecurityRoles().add(EtoolsCopyUtility.createCopy(role));
			}
		} catch (Exception e) {
			throw new DeploymentDescriptorLoadException(CommonArchiveResourceHandler.getString("dd_in_ear_load_EXC_", (new Object[]{aModule.getUri(), getURI()})), e); //$NON-NLS-1$ = "Exception occurred loading deployment descriptor for module "{0}" in ear file "{1}""
		}
	}

	/**
	 * An alt-dd is about to be loaded; register the appropriate resource factory for the uri so it
	 * will get loaded correctly.
	 */
	protected void registerResourceFactory(Module aModule, String aUri) {
		org.eclipse.emf.ecore.resource.Resource.Factory factory = null;
		if (aModule.isEjbModule())
			factory = EJBJarResourceFactory.getRegisteredFactory();
		else if (aModule.isWebModule())
			factory = WebAppResourceFactory.getRegisteredFactory();
		else if (aModule.isJavaModule())
			factory = ApplicationClientResourceFactory.getRegisteredFactory();
		else if (aModule.isConnectorModule())
			factory = ConnectorResourceFactory.getRegisteredFactory();

		if (factory != null) {
			ResourceSet set = getResourceSet();
			((J2EEResourceFactoryRegistry) set.getResourceFactoryRegistry()).registerLastFileSegment(aUri, factory);
		}
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public void remove(ModuleRef aModuleRef) {
		if (aModuleRef == null)
			return;
		Module aModule = aModuleRef.getModule();

		if (aModule != null)
			getDeploymentDescriptor().getModules().remove(aModule);

		getModuleRefs().remove(aModuleRef);
		if (getModuleRefs(aModuleRef.getModuleFile()).isEmpty())
			getFiles().remove(aModuleRef.getModuleFile());
	}

	/**
	 * @see EARFile
	 */
	public List getModuleRefs(ModuleFile aModuleFile) {
		List refs = getModuleRefs();
		List result = new ArrayList(1);
		for (int i = 0; i < refs.size(); i++) {
			ModuleRef ref = (ModuleRef) refs.get(i);
			if (ref.getModuleFile() == aModuleFile)
				result.add(ref);
		}
		return result;
	}

	protected void renameRolesInModuleDDs(String existingRoleName, String newRoleName) {
		List modules = getDeploymentDescriptor().getModules();
		for (int i = 0; i < modules.size(); i++) {
			Module m = (Module) modules.get(i);
			try {
				if (m.isEjbModule())
					getDeploymentDescriptor((EjbModule) m).renameSecurityRole(existingRoleName, newRoleName);
				else if (m.isWebModule())
					getDeploymentDescriptor((WebModule) m).renameSecurityRole(existingRoleName, newRoleName);
			} catch (Exception e) {
				throw new DeploymentDescriptorLoadException(CommonArchiveResourceHandler.getString("dd_in_ear_load_EXC_", (new Object[]{m.getUri(), getURI()})), e); //$NON-NLS-1$ = "Exception occurred loading deployment descriptor for module "{0}" in ear file "{1}""
			}
		}
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public void renameSecurityRole(String existingRoleName, String newRoleName) throws ObjectNotFoundException, DuplicateObjectException {
		Application app = getDeploymentDescriptor();
		SecurityRole aRole = app.getSecurityRoleNamed(existingRoleName);
		if (aRole == null)
			throw new ObjectNotFoundException(CommonArchiveResourceHandler.getString("no_sec_role_EXC_", (new Object[]{getURI(), existingRoleName}))); //$NON-NLS-1$ = ": EAR File deployment descriptor does not contain a security role named "
		if (app.getSecurityRoleNamed(newRoleName) != null)
			throw new DuplicateObjectException(CommonArchiveResourceHandler.getString("dup_sec_role_EXC_", (new Object[]{getURI(), newRoleName})), app.getSecurityRoleNamed(newRoleName)); //$NON-NLS-1$ = ": EAR File deployment descriptor already contains a security role named "

		aRole.setRoleName(newRoleName);

		renameRolesInModuleDDs(existingRoleName, newRoleName);
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public void rollUpRoles() {
		List modules = getDeploymentDescriptor().getModules();
		for (int i = 0; i < modules.size(); i++) {
			Module aModule = (Module) modules.get(i);
			rollUpRoles(aModule);
		}
	}

	/**
	 * @see com.ibm.etools.commonarchive.EARFile
	 */
	public void rollUpRoles(Module aModule) {
		List securityRoles = null;
		try {
			if (aModule.isWebModule())
				securityRoles = getDeploymentDescriptor((WebModule) aModule).getSecurityRoles();
			else if (aModule.isEjbModule())
				securityRoles = getAssemblyDescriptorAddIfNecessary(getDeploymentDescriptor((EjbModule) aModule)).getSecurityRoles();
		} catch (Exception e) {
			throw new DeploymentDescriptorLoadException(CommonArchiveResourceHandler.getString("dd_in_ear_load_EXC_", (new Object[]{aModule.getUri(), getURI()})), e); //$NON-NLS-1$ = "Exception occurred loading deployment descriptor for module "{0}" in ear file "{1}""
		}

		if (securityRoles == null)
			return;
		for (int i = 0; i < securityRoles.size(); i++) {
			addCopyIfNotExists((SecurityRole) securityRoles.get(i));
		}
	}

	public void setDeploymentDescriptor(Application l) {
		this.setDeploymentDescriptorGen(l);
		replaceRoot(getMofResourceMakeIfNecessary(getDeploymentDescriptorUri()), l);
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public boolean eIsSet(EStructuralFeature eFeature) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case CommonarchivePackage.EAR_FILE__URI:
				return URI_EDEFAULT == null ? uri != null : !URI_EDEFAULT.equals(uri);
			case CommonarchivePackage.EAR_FILE__LAST_MODIFIED:
				return isSetLastModified();
			case CommonarchivePackage.EAR_FILE__SIZE:
				return isSetSize();
			case CommonarchivePackage.EAR_FILE__DIRECTORY_ENTRY:
				return isSetDirectoryEntry();
			case CommonarchivePackage.EAR_FILE__ORIGINAL_URI:
				return ORIGINAL_URI_EDEFAULT == null ? originalURI != null : !ORIGINAL_URI_EDEFAULT.equals(originalURI);
			case CommonarchivePackage.EAR_FILE__LOADING_CONTAINER:
				return loadingContainer != null;
			case CommonarchivePackage.EAR_FILE__CONTAINER:
				return getContainer() != null;
			case CommonarchivePackage.EAR_FILE__FILES:
				return files != null && !files.isEmpty();
			case CommonarchivePackage.EAR_FILE__TYPES:
				return types != null && !types.isEmpty();
			case CommonarchivePackage.EAR_FILE__MODULE_REFS:
				return moduleRefs != null && !moduleRefs.isEmpty();
			case CommonarchivePackage.EAR_FILE__DEPLOYMENT_DESCRIPTOR:
				return deploymentDescriptor != null;
		}
		return eDynamicIsSet(eFeature);
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void eSet(EStructuralFeature eFeature, Object newValue) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case CommonarchivePackage.EAR_FILE__URI:
				setURI((String)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__LAST_MODIFIED:
				setLastModified(((Long)newValue).longValue());
				return;
			case CommonarchivePackage.EAR_FILE__SIZE:
				setSize(((Long)newValue).longValue());
				return;
			case CommonarchivePackage.EAR_FILE__DIRECTORY_ENTRY:
				setDirectoryEntry(((Boolean)newValue).booleanValue());
				return;
			case CommonarchivePackage.EAR_FILE__ORIGINAL_URI:
				setOriginalURI((String)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__LOADING_CONTAINER:
				setLoadingContainer((Container)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__CONTAINER:
				setContainer((Container)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__FILES:
				getFiles().clear();
				getFiles().addAll((Collection)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__TYPES:
				getTypes().clear();
				getTypes().addAll((Collection)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__MODULE_REFS:
				getModuleRefs().clear();
				getModuleRefs().addAll((Collection)newValue);
				return;
			case CommonarchivePackage.EAR_FILE__DEPLOYMENT_DESCRIPTOR:
				setDeploymentDescriptor((Application)newValue);
				return;
		}
		eDynamicSet(eFeature, newValue);
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void eUnset(EStructuralFeature eFeature) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case CommonarchivePackage.EAR_FILE__URI:
				setURI(URI_EDEFAULT);
				return;
			case CommonarchivePackage.EAR_FILE__LAST_MODIFIED:
				unsetLastModified();
				return;
			case CommonarchivePackage.EAR_FILE__SIZE:
				unsetSize();
				return;
			case CommonarchivePackage.EAR_FILE__DIRECTORY_ENTRY:
				unsetDirectoryEntry();
				return;
			case CommonarchivePackage.EAR_FILE__ORIGINAL_URI:
				setOriginalURI(ORIGINAL_URI_EDEFAULT);
				return;
			case CommonarchivePackage.EAR_FILE__LOADING_CONTAINER:
				setLoadingContainer((Container)null);
				return;
			case CommonarchivePackage.EAR_FILE__CONTAINER:
				setContainer((Container)null);
				return;
			case CommonarchivePackage.EAR_FILE__FILES:
				getFiles().clear();
				return;
			case CommonarchivePackage.EAR_FILE__TYPES:
				getTypes().clear();
				return;
			case CommonarchivePackage.EAR_FILE__MODULE_REFS:
				getModuleRefs().clear();
				return;
			case CommonarchivePackage.EAR_FILE__DEPLOYMENT_DESCRIPTOR:
				setDeploymentDescriptor((Application)null);
				return;
		}
		eDynamicUnset(eFeature);
	}

	/**
	 * @generated This field/method will be replaced during code generation
	 */
	public Application getDeploymentDescriptorGen() {
		if (deploymentDescriptor != null && deploymentDescriptor.eIsProxy()) {
			Application oldDeploymentDescriptor = deploymentDescriptor;
			deploymentDescriptor = (Application)eResolveProxy((InternalEObject)deploymentDescriptor);
			if (deploymentDescriptor != oldDeploymentDescriptor) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonarchivePackage.EAR_FILE__DEPLOYMENT_DESCRIPTOR, oldDeploymentDescriptor, deploymentDescriptor));
			}
		}
		return deploymentDescriptor;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public Application basicGetDeploymentDescriptor() {
		return deploymentDescriptor;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setDeploymentDescriptorGen(Application newDeploymentDescriptor) {
		Application oldDeploymentDescriptor = deploymentDescriptor;
		deploymentDescriptor = newDeploymentDescriptor;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonarchivePackage.EAR_FILE__DEPLOYMENT_DESCRIPTOR, oldDeploymentDescriptor, deploymentDescriptor));
	}

	/**
	 * @generated This field/method will be replaced during code generation
	 */
	public EList getModuleRefsGen() {
		if (moduleRefs == null) {
			moduleRefs = new EObjectContainmentWithInverseEList(ModuleRef.class, this, CommonarchivePackage.EAR_FILE__MODULE_REFS, CommonarchivePackage.MODULE_REF__EAR_FILE);
		}
		return moduleRefs;
	}

	public EList getModuleRefs() {
		EList refs = getModuleRefsGen();

		if (refs.isEmpty())
			initRefs(refs);

		return refs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) {
		if (featureID >= 0) {
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
				case CommonarchivePackage.EAR_FILE__CONTAINER:
					if (eContainer != null)
						msgs = eBasicRemoveFromContainer(msgs);
					return eBasicSetContainer(otherEnd, CommonarchivePackage.EAR_FILE__CONTAINER, msgs);
				case CommonarchivePackage.EAR_FILE__FILES:
					return ((InternalEList)getFiles()).basicAdd(otherEnd, msgs);
				case CommonarchivePackage.EAR_FILE__MODULE_REFS:
					return ((InternalEList)getModuleRefs()).basicAdd(otherEnd, msgs);
				default:
					return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
			}
		}
		if (eContainer != null)
			msgs = eBasicRemoveFromContainer(msgs);
		return eBasicSetContainer(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) {
		if (featureID >= 0) {
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
				case CommonarchivePackage.EAR_FILE__CONTAINER:
					return eBasicSetContainer(null, CommonarchivePackage.EAR_FILE__CONTAINER, msgs);
				case CommonarchivePackage.EAR_FILE__FILES:
					return ((InternalEList)getFiles()).basicRemove(otherEnd, msgs);
				case CommonarchivePackage.EAR_FILE__MODULE_REFS:
					return ((InternalEList)getModuleRefs()).basicRemove(otherEnd, msgs);
				default:
					return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
			}
		}
		return eBasicSetContainer(null, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain eBasicRemoveFromContainer(NotificationChain msgs) {
		if (eContainerFeatureID >= 0) {
			switch (eContainerFeatureID) {
				case CommonarchivePackage.EAR_FILE__CONTAINER:
					return eContainer.eInverseRemove(this, CommonarchivePackage.CONTAINER__FILES, Container.class, msgs);
				default:
					return eDynamicBasicRemoveFromContainer(msgs);
			}
		}
		return eContainer.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - eContainerFeatureID, null, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case CommonarchivePackage.EAR_FILE__URI:
				return getURI();
			case CommonarchivePackage.EAR_FILE__LAST_MODIFIED:
				return new Long(getLastModified());
			case CommonarchivePackage.EAR_FILE__SIZE:
				return new Long(getSize());
			case CommonarchivePackage.EAR_FILE__DIRECTORY_ENTRY:
				return isDirectoryEntry() ? Boolean.TRUE : Boolean.FALSE;
			case CommonarchivePackage.EAR_FILE__ORIGINAL_URI:
				return getOriginalURI();
			case CommonarchivePackage.EAR_FILE__LOADING_CONTAINER:
				if (resolve) return getLoadingContainer();
				return basicGetLoadingContainer();
			case CommonarchivePackage.EAR_FILE__CONTAINER:
				return getContainer();
			case CommonarchivePackage.EAR_FILE__FILES:
				return getFiles();
			case CommonarchivePackage.EAR_FILE__TYPES:
				return getTypes();
			case CommonarchivePackage.EAR_FILE__MODULE_REFS:
				return getModuleRefs();
			case CommonarchivePackage.EAR_FILE__DEPLOYMENT_DESCRIPTOR:
				if (resolve) return getDeploymentDescriptor();
				return basicGetDeploymentDescriptor();
		}
		return eDynamicGet(eFeature, resolve);
	}

	public void initRefs(EList refs) {
		List modules = getDeploymentDescriptor().getModules();
		for (int i = 0; i < modules.size(); i++) {
			Module module = (Module) modules.get(i);
			refs.add(createModuleRef(module, null));
		}
	}

	protected ModuleRef createModuleRef(Module aModule, ModuleFile aFile) {
		ModuleRef newRef = null;

		if (aModule.isEjbModule())
			newRef = getCommonArchiveFactory().createEJBModuleRef();
		else if (aModule.isWebModule())
			newRef = getCommonArchiveFactory().createWebModuleRef();
		else if (aModule.isConnectorModule())
			newRef = getCommonArchiveFactory().createConnectorModuleRef();
		else if (aModule.isJavaModule())
			newRef = getCommonArchiveFactory().createClientModuleRef();

		newRef.setModule(aModule);
		newRef.setModuleFile(aFile);

		return newRef;
	}

	/*
	 * @see EARFile#getClientModuleRefs()
	 */
	public List getClientModuleRefs() {
		List result = new ArrayList();
		List refs = getModuleRefs();
		for (int i = 0; i < refs.size(); i++) {
			ModuleRef ref = (ModuleRef) refs.get(i);
			if (ref.isClient())
				result.add(ref);
		}
		return result;
	}

	/*
	 * @see EARFile#getConnectorModuleRefs()
	 */
	public List getConnectorModuleRefs() {
		List result = new ArrayList();
		List refs = getModuleRefs();
		for (int i = 0; i < refs.size(); i++) {
			ModuleRef ref = (ModuleRef) refs.get(i);
			if (ref.isConnector())
				result.add(ref);
		}
		return result;
	}

	/*
	 * @see EARFile#getEJBModuleRefs()
	 */
	public List getEJBModuleRefs() {
		List result = new ArrayList();
		List refs = getModuleRefs();
		for (int i = 0; i < refs.size(); i++) {
			ModuleRef ref = (ModuleRef) refs.get(i);
			if (ref.isEJB())
				result.add(ref);
		}
		return result;
	}

	/*
	 * @see EARFile#getWebModuleRefs()
	 */
	public List getWebModuleRefs() {
		List result = new ArrayList();
		List refs = getModuleRefs();
		for (int i = 0; i < refs.size(); i++) {
			ModuleRef ref = (ModuleRef) refs.get(i);
			if (ref.isWeb())
				result.add(ref);
		}
		return result;
	}

	/*
	 * @see EARFile#getFARFiles()
	 */
	public List getFARFiles() {
		List farFiles = new ArrayList();
		List fileList = getFiles();
		for (int i = 0; i < fileList.size(); i++) {
			File aFile = (File) fileList.get(i);
			if (aFile.isFARFile()) {
				farFiles.add(aFile);
			}
		}
		return farFiles;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.etools.commonarchive.EARFile#getArchivesOfType(java.lang.String)
	 */
	public List getArchivesOfType(String type) {
		return Collections.EMPTY_LIST;
	}

	public Map getEJBReferences(boolean filterLinkedReferences, boolean filterNonLinkedReferences) throws ArchiveWrappedException {
		if (!filterLinkedReferences || !filterNonLinkedReferences) {
			Application app = getDeploymentDescriptor();
			if (app != null) {
				List modules = app.getModules();
				Module module;
				Map references = null;
				for (int i = 0; i < modules.size(); i++) {
					module = (Module) modules.get(i);
					try {
						references = collectEJBReferences(module, filterLinkedReferences, filterNonLinkedReferences, references);
					} catch (ResourceLoadException e) {
						throw new ArchiveWrappedException(e);
					} catch (FileNotFoundException e) {
						throw new ArchiveWrappedException(e);
					} catch (EmptyResourceException e) {
						throw new ArchiveWrappedException(e);
					}
				}
				return references;
			}
		}
		return Collections.EMPTY_MAP;
	}

	/**
	 * @param module
	 * @param filterLinkedReferences
	 * @param filterNonLinkedReferences
	 * @param references
	 * @return
	 */
	private Map collectEJBReferences(Module module, boolean filterLinkedReferences, boolean filterNonLinkedReferences, Map references) throws ResourceLoadException, FileNotFoundException, EmptyResourceException {
		Map myReferences = references;
		List moduleReferences = getEJBReferneces(module);
		if (moduleReferences != null && !moduleReferences.isEmpty()) {
			EjbRef ref = null;
			List filteredRefs = null;
			String link = null;
			for (int i = 0; i < moduleReferences.size(); i++) {
				ref = (EjbRef) moduleReferences.get(i);
				link = ref.getLink();
				if ((link != null && link.length() > 0 && !filterLinkedReferences) || (link == null || link.length() == 0 && !filterNonLinkedReferences)) {
					if (filteredRefs == null)
						filteredRefs = new ArrayList(moduleReferences.size());
					filteredRefs.add(ref);
				}
			}
			if (filteredRefs != null) {
				if (myReferences == null)
					myReferences = new HashMap();
				myReferences.put(module, filteredRefs);
			}
		}
		return myReferences;
	}

	/**
	 * @param module
	 * @return
	 */
	private List getEJBReferneces(Module module) throws ResourceLoadException, FileNotFoundException, EmptyResourceException {
		if (module != null) {
			if (module.isEjbModule()) {
				EJBJar ejbJar = getDeploymentDescriptor((EjbModule) module);
				return getEJBReferences(ejbJar);
			} else if (module.isWebModule()) {
				WebApp webApp = getDeploymentDescriptor((WebModule) module);
				if (webApp != null)
					return webApp.getEjbRefs();
			} else if (module.isJavaModule()) {
				ApplicationClient appClient = getDeploymentDescriptor((JavaClientModule) module);
				if (appClient != null)
					return appClient.getEjbReferences();
			}
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @param ejbJar
	 * @return
	 */
	private List getEJBReferences(EJBJar ejbJar) {
		if (ejbJar != null) {
			List ejbs = ejbJar.getEnterpriseBeans();
			List refs = null;
			EnterpriseBean ejb = null;
			for (int i = 0; i < ejbs.size(); i++) {
				ejb = (EnterpriseBean) ejbs.get(i);
				if (refs == null)
					refs = new ArrayList();
				refs.addAll(ejb.getEjbRefs());
			}
			if (refs != null)
				return refs;
		}
		return Collections.EMPTY_LIST;
	}

}
