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

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.application.Application;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualArchiveComponent;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.internal.EjbModuleExtensionHelper;
import org.eclipse.jst.j2ee.internal.IEJBModelExtenderManager;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyManifestUtil;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.server.core.IApplicationClientModule;
import org.eclipse.jst.server.core.IConnectorModule;
import org.eclipse.jst.server.core.IEJBModule;
import org.eclipse.jst.server.core.IEnterpriseApplication;
import org.eclipse.jst.server.core.IJ2EEModule;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.wst.common.componentcore.ArtifactEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.internal.ModuleFile;
import org.eclipse.wst.server.core.internal.ModuleFolder;
import org.eclipse.wst.server.core.model.IModuleFile;
import org.eclipse.wst.server.core.model.IModuleFolder;
import org.eclipse.wst.server.core.model.IModuleResource;
import org.eclipse.wst.web.internal.deployables.ComponentDeployable;
/**
 * J2EE module superclass.
 */
public class J2EEFlexProjDeployable extends ComponentDeployable implements IJ2EEModule, IEnterpriseApplication, IApplicationClientModule, IConnectorModule, IEJBModule, IWebModule {
	protected static final IPath WEB_CLASSES_PATH = new Path(J2EEConstants.WEB_INF_CLASSES);
	protected static final IPath MANIFEST_PATH = new Path(J2EEConstants.MANIFEST_URI);
	protected static IPath WEBLIB = new Path(J2EEConstants.WEB_INF_LIB).makeAbsolute();
	protected IPackageFragmentRoot[] cachedSourceContainers;
	protected IContainer[] cachedOutputContainers;
	protected HashMap cachedOutputMappings;
	protected HashMap cachedSourceOutputPairs;
	protected List classpathComponentDependencyURIs = new ArrayList();

	/**
	 * Constructor for J2EEFlexProjDeployable.
	 * 
	 * @param project
	 * @param aComponent
	 */
	public J2EEFlexProjDeployable(IProject project, IVirtualComponent aComponent) {
		super(project, aComponent);
	}
	

	/**
	 * Constructor for J2EEFlexProjDeployable.
	 * 
	 * @param project
	 */
	public J2EEFlexProjDeployable(IProject project) {
		super(project);
	}

	/**
	 * Returns the root folders for the resources in this module.
	 * 
	 * @return a possibly-empty array of resource folders
	 */
	public IContainer[] getResourceFolders() {
		List result = new ArrayList();
		IVirtualComponent vc = ComponentCore.createComponent(getProject());
		if (vc != null) {
			IVirtualFolder vFolder = vc.getRootFolder();
			if (vFolder != null) {
				IContainer[] underlyingFolders = vFolder.getUnderlyingFolders();
				result.addAll(Arrays.asList(underlyingFolders));
			}
		}
		return (IContainer[]) result.toArray(new IContainer[result.size()]);
	}

	/**
	 * Returns the root folders containing Java output in this module.
	 * 
	 * @return a possibly-empty array of Java output folders
	 */
	public IContainer[] getJavaOutputFolders() {
		if (cachedOutputContainers == null)
			cachedOutputContainers = getJavaOutputFolders(getProject());
		return cachedOutputContainers;
	}
	
	public IContainer[] getJavaOutputFolders(IProject project) {
		if (project == null)
			return new IContainer[0];
		return J2EEProjectUtilities.getOutputContainers(project);
	}

	protected boolean shouldIncludeUtilityComponent(IVirtualComponent virtualComp,IVirtualReference[] references, ArtifactEdit edit) {
		// If the component module is an EAR we know all archives are filtered out of virtual component members
		// and we will return only those archives which are not binary J2EE modules in the EAR DD.  These J2EE modules will
		// be returned by getChildModules()
		if (J2EEProjectUtilities.isEARProject(component.getProject())) {
			return virtualComp != null && virtualComp.isBinary() && !isNestedJ2EEModule(virtualComp, references, (EARArtifactEdit)edit);
		} else { 
			return super.shouldIncludeUtilityComponent(virtualComp, references, edit);
		}
	}
	
	protected void addUtilMember(IVirtualComponent parent, IVirtualReference reference, IPath runtimePath) {
		// do not add classpath dependencies whose runtime path (../) maps to the parent component or that represent
		// class folders
		if (!runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH) 
				&& !ClasspathDependencyUtil.isClassFolderReference(reference)) {
			super.addUtilMember(parent, reference, runtimePath);
		}
	}
	
	protected IModuleResource[] getBinaryModuleMembers() {
		IPath archivePath = ((J2EEModuleVirtualArchiveComponent)component).getWorkspaceRelativePath();
		ModuleFile mf = null;
		if (archivePath != null) { //In Workspace
			IFile utilFile = ResourcesPlugin.getWorkspace().getRoot().getFile(archivePath);
			mf = new ModuleFile(utilFile, utilFile.getName(), ((J2EEModuleVirtualArchiveComponent)component).getRuntimePath().makeRelative());
		} else {
			File extFile = ((J2EEModuleVirtualArchiveComponent)component).getUnderlyingDiskFile();
			mf = new ModuleFile(extFile, extFile.getName(), ((J2EEModuleVirtualArchiveComponent)component).getRuntimePath().makeRelative());
		}
		return new IModuleResource[] {mf};
	}
	
	public IModuleResource[] members() throws CoreException {
		members.clear();
		classpathComponentDependencyURIs.clear();

		// Handle binary components
		if (component instanceof J2EEModuleVirtualArchiveComponent)
			return getBinaryModuleMembers();

		if (J2EEProjectUtilities.isEARProject(component.getProject())) {
			// If an EAR, add classpath contributions for all referenced modules
			addReferencedComponentClasspathDependencies(component, false);
		} else {
			if (J2EEProjectUtilities.isDynamicWebProject(component.getProject())) {
				// If a web, add classpath contributions for all WEB-INF/lib modules
				addReferencedComponentClasspathDependencies(component, true);
			}
			if (canExportClasspathComponentDependencies(component)){
				saveClasspathDependencyURIs(component);
			}
			// Add all Java output folders that have publish/export attributes
			addClassFolderDependencies(component);
		}
		
		// If j2ee project structure is a single root structure, just return optimized members
		if (isSingleRootStructure()) {
			final IModuleResource[] resources = getOptimizedMembers();
			if (!classpathComponentDependencyURIs.isEmpty()) {
				for (int i = 0; i < resources.length; i++) {
					if (resources[i] instanceof IModuleFolder) {
						IModuleFolder folder = (IModuleFolder) resources[i];
						if (folder.getName().equals(J2EEConstants.META_INF)) {
							IModuleResource[] files = folder.members();
							for (int j = 0; j < files.length; j++) {
								files[j] = replaceManifestFile((IModuleFile) files[j]);								
							}
						}
					}
				}
			}
			// add to any potentially mapped Java class folders
			for (int i = 0; i < resources.length; i++) {
				members.add(resources[i]);
			}
			return (IModuleResource[]) members.toArray(new IModuleResource[members.size()]);
		}
		
		cachedSourceContainers = J2EEProjectUtilities.getSourceContainers(getProject());
		try {
			IPath javaPath = Path.EMPTY;
			if (J2EEProjectUtilities.isDynamicWebProject(component.getProject()))
				javaPath = WEB_CLASSES_PATH;
			
			if (component != null) {
				IVirtualFolder vFolder = component.getRootFolder();
				IModuleResource[] mr = getMembers(vFolder, Path.EMPTY);
				int size = mr.length;
				for (int j = 0; j < size; j++) {
					members.add(mr[j]);
				}
			}
			
			IContainer[] javaCont = getJavaOutputFolders();		
			int size = javaCont.length;
			for (int i = 0; i < size; i++) {
				//If the java output is in the scope of the virtual component, ignore to avoid duplicates
				if (ComponentCore.createResources(javaCont[i]).length > 0) 
					continue;
				IModuleResource[] mr = getMembers(javaCont[i], javaPath, javaPath, javaCont);
				int size2 = mr.length;
				for (int j = 0; j < size2; j++) {
					members.add(mr[j]);
				}
			}
									
			if (component != null) {
				addUtilMembers(component);
				List consumableMembers = getConsumableReferencedMembers(component);
				if (!consumableMembers.isEmpty())
					members.addAll(consumableMembers);
			}
			
			IModuleResource[] mr = new IModuleResource[members.size()];
			members.toArray(mr);
			return mr;
		} finally {
			cachedSourceContainers = null;
			cachedOutputContainers = null;
			cachedOutputMappings = null;
			cachedSourceOutputPairs = null;
		}
	}
	
	protected IModuleFile createModuleFile(IFile file, IPath path) {
		// if this is the MANIFEST.MF file and we have classpath component dependencies, 
		// update it
		return replaceManifestFile(super.createModuleFile(file, path));
	}
	
	protected IModuleFile replaceManifestFile(IModuleFile moduleFile) {
		final IFile file = (IFile) moduleFile.getAdapter(IFile.class);
		final IPath path = moduleFile.getModuleRelativePath();
		// if the MANIFEST.MF is being requested and we have classpath component dependencies, 
		// dynamically generate a customized MANIFEST.MF and return that 
		if (path.append(file.getName()).equals(MANIFEST_PATH) && !classpathComponentDependencyURIs.isEmpty()) {
			final IProject project = file.getProject();
			final IPath workingLocation = project.getWorkingLocation(J2EEPlugin.PLUGIN_ID);
			// create path to temp MANIFEST.MF
			final IPath tempManifestPath = workingLocation.append(MANIFEST_PATH);
			final File fsFile = tempManifestPath.toFile();
			if (!fsFile.exists()) {
				// create parent dirs for temp MANIFEST.MF
				final File parent = fsFile.getParentFile();
				if (!parent.exists()) {
					if (!parent.mkdirs()) {
						return moduleFile;
					}
				}
			}
			// create temp MANIFEST.MF using util method
			try {
				ClasspathDependencyManifestUtil.updateManifestClasspath(file, classpathComponentDependencyURIs, new FileOutputStream(fsFile));
				// create new ModuleFile that points to temp MANIFEST.MF
				return new ModuleFile(fsFile, file.getName(), path);
			} catch (IOException ioe) {
				return moduleFile;
			}
		}
		return moduleFile;
	}
	
	protected IModuleResource[] handleJavaPath(IPath path, IPath javaPath, IPath curPath, IContainer[] javaCont, IModuleResource[] mr, IContainer cc) throws CoreException {
		if (curPath.equals(javaPath)) {
			int size = javaCont.length;
			for (int i = 0; i < size; i++) {
				IModuleResource[] mr2 = getMembers(javaCont[i], path.append(cc.getName()), null, null);
				IModuleResource[] mr3 = new IModuleResource[mr.length + mr2.length];
				System.arraycopy(mr, 0, mr3, 0, mr.length);
				System.arraycopy(mr2, 0, mr3, mr.length, mr2.length);
				mr = mr3;
			}
		} else {
			boolean containsFolder = false;
			String name = javaPath.segment(curPath.segmentCount());
			int size = mr.length;
			for (int i = 0; i < size && !containsFolder; i++) {
				if (mr[i] instanceof IModuleFolder) {
					IModuleFolder mf2 = (IModuleFolder) mr[i];
					if (name.equals(mf2.getName())) {
						containsFolder = true;
					}
				}
			}
			
			if (!containsFolder && javaCont.length > 0) {
				ModuleFolder mf2 = new ModuleFolder(javaCont[0], name, curPath);
				IModuleResource[] mrf = new IModuleResource[0];
				size = javaCont.length;
				for (int i = 0; i < size; i++) {
					IModuleResource[] mrf2 = getMembers(javaCont[i], javaPath, null, null);
					IModuleResource[] mrf3 = new IModuleResource[mrf.length + mrf2.length];
					System.arraycopy(mrf, 0, mrf3, 0, mrf.length);
					System.arraycopy(mrf2, 0, mrf3, mrf.length, mrf2.length);
					mrf = mrf3;
				}
				
				mf2.setMembers(mrf);
				
				IModuleResource[] mr3 = new IModuleResource[mr.length + 1];
				System.arraycopy(mr, 0, mr3, 0, mr.length);
				mr3[mr.length] = mf2;
				mr = mr3;
			}
		}
		return mr;
	}

    /**
     * Returns the classpath as a list of absolute IPaths.
     * 
     * @return an array of paths
     */
    public IPath[] getClasspath() {
		List paths = new ArrayList();
        IJavaProject proj = JemProjectUtilities.getJavaProject(getProject());
        URL[] urls = JemProjectUtilities.getClasspathAsURLArray(proj);
		for (int i = 0; i < urls.length; i++) {
			URL url = urls[i];
			paths.add(Path.fromOSString(url.getPath()));
		}
        return  (IPath[]) paths.toArray(new IPath[paths.size()]);
    }
    
    public String getJNDIName(String ejbName) {
    	if (!J2EEProjectUtilities.isEJBProject(component.getProject()))
    		return null;
		EjbModuleExtensionHelper modHelper = null;
		EJBJar jar = null;
		ArtifactEdit ejbEdit = null;
		try {
			ejbEdit = ComponentUtilities.getArtifactEditForRead(component);
			if (ejbEdit != null) {
				jar = (EJBJar) ejbEdit.getContentModelRoot();
				modHelper = IEJBModelExtenderManager.INSTANCE.getEJBModuleExtension(null);
				return modHelper == null ? null : modHelper.getJNDIName(jar, jar.getEnterpriseBeanNamed(ejbName));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ejbEdit != null)
				ejbEdit.dispose();
		}
		return null;
	}

    /**
     * This method will handle a number of J2EE related scenarios.  If this is an ear and a child module is passed in,
     * the URI for that child module will be returned.  If no child module was passed, the URI of the EAR is returned.
     * If this is a child component and the module passed in is the EAR, we grab the module uri for this compared to that
     * EAR.  If no ear module is passed in we look for one and use it and return URI relative to found EAR.  If no EAR's 
     * are found the URI is returned in a default manner.
     * 
     * @return URI string
     */
    public String getURI(IModule module) {
    	// If the component is an ear and the module passed in is a child module
    	if (component!=null && module!=null && J2EEProjectUtilities.isEARProject(component.getProject()))
 			return getContainedURI(module);

    	IVirtualComponent ear = null;
    	String aURI = null;
    	// If the component is a child module and the module passed in is the ear
    	if (module != null && J2EEProjectUtilities.isEARProject(module.getProject()))
    		ear = ComponentCore.createComponent(module.getProject());
    	// else if the component is a child module and the module passed in is null, search for first ear
    	else if (module==null && component != null) {
    		IProject[] earProjects = J2EEProjectUtilities.getReferencingEARProjects(component.getProject());
	        if (earProjects.length>0)
	        	ear = ComponentCore.createComponent(earProjects[0]);
    	}
    	// We have a valid ear and the component is a valid child
    	if (ear != null && component != null) {
    		EARArtifactEdit earEdit = null;
			try {
				earEdit = EARArtifactEdit.getEARArtifactEditForRead(ear);
				if (earEdit != null)
					aURI = earEdit.getModuleURI(component);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (earEdit != null)
					earEdit.dispose();
			}
    	} 
    	// We have an ear component and no child module
    	else if (component!=null && J2EEProjectUtilities.isEARProject(component.getProject())) {
			aURI = component.getDeployedName()+IJ2EEModuleConstants.EAR_EXT;
    	} 
    	// We have child components but could not find valid ears
    	else if (component != null && J2EEProjectUtilities.isDynamicWebProject(component.getProject())) {
			if (module != null) {
				IVirtualComponent webComp = ComponentCore.createComponent(component.getProject());
				IVirtualReference reference = webComp.getReference(module.getProject().getName());
				if (J2EEProjectUtilities.isDynamicWebProject(module.getProject())) {
					aURI = ComponentUtilities.getDeployUriOfComponent(reference, IJ2EEModuleConstants.WAR_EXT);
				}
				else if (J2EEProjectUtilities.isJCAProject(module.getProject())) {
					aURI = ComponentUtilities.getDeployUriOfComponent(reference, IJ2EEModuleConstants.RAR_EXT);
				}
				else {
					aURI = ComponentUtilities.getDeployUriOfComponent(reference, IJ2EEModuleConstants.JAR_EXT);
				}
			}
			else {
				aURI = component.getDeployedName() + IJ2EEModuleConstants.WAR_EXT;
			}
		} 
    	else if (component!=null && (J2EEProjectUtilities.isEJBProject(component.getProject()) || J2EEProjectUtilities.isApplicationClientProject(component.getProject()))) {
    		aURI = component.getDeployedName()+IJ2EEModuleConstants.JAR_EXT;
    	} 
    	else if (component!=null && J2EEProjectUtilities.isJCAProject(component.getProject())) {
    		aURI = component.getDeployedName()+IJ2EEModuleConstants.RAR_EXT;
    	}
    	
    	if (aURI !=null && aURI.length()>1 && aURI.startsWith("/")) //$NON-NLS-1$
    		aURI = aURI.substring(1);
    	return aURI;
	}
    
    protected boolean isBinaryModuleArchive(IModule module) {
    	if (module!=null && module.getName().endsWith(IJ2EEModuleConstants.JAR_EXT) || module.getName().endsWith(IJ2EEModuleConstants.WAR_EXT) ||
    			module.getName().endsWith(IJ2EEModuleConstants.RAR_EXT)) {
    		if (component!=null && J2EEProjectUtilities.isEARProject(component.getProject()))
    			return true;
    	}
    	return false;
    }
    
    private String getContainedURI(IModule module) {
    	if (component instanceof J2EEModuleVirtualArchiveComponent || isBinaryModuleArchive(module))
    		return new Path(module.getName()).lastSegment();
    	
    	IVirtualComponent comp = ComponentCore.createComponent(module.getProject());
    	String aURI = null;
    	if (comp!=null && component!=null && J2EEProjectUtilities.isEARProject(component.getProject())) {
			EARArtifactEdit earEdit = null;
			try {
				earEdit = EARArtifactEdit.getEARArtifactEditForRead(component);
				if (earEdit != null)
					aURI = earEdit.getModuleURI(comp);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (earEdit != null)
					earEdit.dispose();
			}
    	}
    	if (aURI !=null && aURI.length()>1 && aURI.startsWith("/")) //$NON-NLS-1$
    		aURI = aURI.substring(1);
    	return aURI;
	}
    
    /**
     * This method returns the context root property from the deployable project's .component file
     */
    public String getContextRoot() {
		Properties props = component.getMetaProperties();
		if(props.containsKey(J2EEConstants.CONTEXTROOT))
			return props.getProperty(J2EEConstants.CONTEXTROOT);
	    return component.getName();
    }
    
    /**
     * This method is applicable for a web deployable.  The module passed in should either be null or
     * the EAR module the web deployable is contained in.  It will return the context root from the EAR
     * if it has one or return the .component value in the web project if it is standalone.
     *  
     * @param module
     * @return contextRoot String
     */
    public String getContextRoot(IModule earModule) {
    	IProject deployProject = component.getProject();
    	String contextRoot = null;
    	if (earModule == null)
    		return getContextRoot();
    	else if (J2EEProjectUtilities.isEARProject(earModule.getProject()) && J2EEProjectUtilities.isDynamicWebProject(deployProject)) {
    		EARArtifactEdit edit = null;
    		try {
    			edit = EARArtifactEdit.getEARArtifactEditForRead(earModule.getProject());
    			contextRoot = edit.getWebContextRoot(deployProject);
    		} finally {
    			if (edit!=null)
    				edit.dispose();
    		}
    	}
    	return contextRoot;
    }
    
    /**
     * Find the source container, if any, for the given file.
     * 
     * @param file
     * @return IPackageFragmentRoot sourceContainer for IFile
     */
    protected IPackageFragmentRoot getSourceContainer(IFile file) {
    	if (file == null)
    		return null;
    	IPackageFragmentRoot[] srcContainers = getSourceContainers();
    	for (int i=0; i<srcContainers.length; i++) {
    		IPath srcPath = srcContainers[i].getPath();
    		if (srcPath.isPrefixOf(file.getFullPath()))
    			return srcContainers[i];
    	}
    	return null;
    }
    
    /**
     * Either returns value from cache or stores result as value in cache for the corresponding
     * output container for the given source container.
     * 
     * @param sourceContainer
     * @return IContainer output container for given source container
     */
    protected IContainer getOutputContainer(IPackageFragmentRoot sourceContainer) {
    	if (sourceContainer == null)
    		return null;
    	
    	HashMap pairs = getCachedSourceOutputPairs();
    	IContainer output = (IContainer) pairs.get(sourceContainer);
    	if (output == null) {
    		output = J2EEProjectUtilities.getOutputContainer(getProject(), sourceContainer);
    		pairs.put(sourceContainer,output);
    	}
    	return output;
    }
    
	private IPackageFragmentRoot[] getSourceContainers() {
		if (cachedSourceContainers != null)
			return cachedSourceContainers;
		return J2EEProjectUtilities.getSourceContainers(getProject());
	}
    
    protected List getConsumableReferencedMembers(IVirtualComponent vc) throws CoreException {
		List consumableMembers = new ArrayList();
		IVirtualReference[] refComponents = vc.getReferences();
    	for (int i = 0; i < refComponents.length; i++) {
    		IVirtualReference reference = refComponents[i];
    		if (reference != null && reference.getDependencyType()==IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
    			IVirtualComponent consumedComponent = reference.getReferencedComponent();
    			if (consumedComponent!=null && isProjectOfType(consumedComponent.getProject(),IModuleConstants.JST_UTILITY_MODULE)) {
    				if (consumedComponent != null && consumedComponent.getRootFolder()!=null) {
    					IVirtualFolder vFolder = consumedComponent.getRootFolder();
    					IModuleResource[] mr = getMembers(vFolder, reference.getRuntimePath().makeRelative());
    					int size = mr.length;
    					for (int j = 0; j < size; j++) {
    						if (!members.contains(mr[j]))
    							members.add(mr[j]);
    					}
    					addUtilMembers(consumedComponent);
    					List childConsumableMembers = getConsumableReferencedMembers(consumedComponent);
    					if (!childConsumableMembers.isEmpty())
    						members.addAll(childConsumableMembers);
    				}
    				
    				IContainer[] javaCont = getJavaOutputFolders(consumedComponent.getProject());		
    				int size = javaCont.length;
    				for (int j = 0; j < size; j++) {
    					IModuleResource[] mr = getMembers(javaCont[j], reference.getRuntimePath(), reference.getRuntimePath(), javaCont);
    					int size2 = mr.length;
    					for (int k = 0; k < size2; k++) {
    						if (!members.contains(mr[k]))
    							members.add(mr[k]);
    					}
    				}
    			}
    		}
    	}
		return consumableMembers;
	}
    
    protected IModule gatherModuleReference(IVirtualComponent component, IVirtualComponent targetComponent ) {
    	IModule module = super.gatherModuleReference(component, targetComponent);
    	// Handle binary module components
    	if (targetComponent instanceof J2EEModuleVirtualArchiveComponent) {
    		if (J2EEProjectUtilities.isEARProject(component.getProject()) || targetComponent.getProject()!=component.getProject())
    			module = ServerUtil.getModule(J2EEDeployableFactory.ID+":"+targetComponent.getName()); //$NON-NLS-1$
    	}
		return module;
    }
    
    /**
     * Determine if the component is nested J2EE module on the application.xml of this EAR
     * @param aComponent
     * @return boolean is passed in component a nested J2EE module on this EAR
     */
    private boolean isNestedJ2EEModule(IVirtualComponent aComponent, IVirtualReference[] references, EARArtifactEdit edit) {
    	if (edit==null) 
			return false;
		Application app = edit.getApplication();
		IVirtualReference reference = getReferenceNamed(references,aComponent.getName());
		// Ensure module URI exists on EAR DD for binary archive
		return app.getFirstModule(reference.getArchiveName()) != null;
    }
    
    protected IVirtualReference getReferenceNamed(IVirtualReference[] references, String name) {
    	for (int i=0; i<references.length; i++) {
    		if (references[i].getReferencedComponent().getName().equals(name))
    			return references[i];
    	}
    	return null;
    }
    
    protected ArtifactEdit getComponentArtifactEditForRead() {
		return EARArtifactEdit.getEARArtifactEditForRead(component.getProject());
	}
    
    /**
     * The references for J2EE module deployment are only those child modules of EARs or web modules
     */
    protected IVirtualReference[] getReferences(IVirtualComponent aComponent) {
    	if (aComponent == null || aComponent.isBinary()) {
    		return new IVirtualReference[] {};
    	} else if (J2EEProjectUtilities.isDynamicWebProject(aComponent.getProject())) {
    		return getWebLibModules((J2EEModuleVirtualComponent)aComponent);
    	} else if (J2EEProjectUtilities.isEARProject(aComponent.getProject())) {
    		return super.getReferences(aComponent);
    	} else {
    		return new IVirtualReference[] {};
    	}
    }
    
    /**
	 * This method will return the list of dependent modules which are utility jars in the web lib
	 * folder of the deployed path of the module. It will not return null.
	 * 
	 * @return array of the web library dependent modules
	 */
	private IVirtualReference[] getWebLibModules(J2EEModuleVirtualComponent comp) {
		List result = new ArrayList();
		IVirtualReference[] refComponents = comp.getNonManifestReferences();
		// Check the deployed path to make sure it has a lib parent folder and matchs the web.xml
		// base path
		for (int i = 0; i < refComponents.length; i++) {
			if (refComponents[i].getRuntimePath().equals(WEBLIB))
				result.add(refComponents[i]);
		}
		return (IVirtualReference[]) result.toArray(new IVirtualReference[result.size()]);
	}
	
	/*
	 * Add any classpath component dependencies from this component
	 */
	private void addReferencedComponentClasspathDependencies(final IVirtualComponent component, final boolean web) {
		final IVirtualReference[] refs = component.getReferences();
		final Set absolutePaths = new HashSet();
		for (int i = 0; i < refs.length; i++) {
			final IVirtualReference reference = refs[i];
			final IPath runtimePath = reference.getRuntimePath();
			final IVirtualComponent referencedComponent = reference.getReferencedComponent();
			
			// if we are adding to a web project, only process references with the /WEB-INF/lib runtime path
			if (web && !runtimePath.equals(WEBLIB)) {
				continue;
			}

			// if the reference cannot export dependencies, skip
			if (!canExportClasspathComponentDependencies(referencedComponent)) {
				continue;
			}
			
			if (!referencedComponent.isBinary() && referencedComponent instanceof J2EEModuleVirtualComponent) {
				final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) referencedComponent).getJavaClasspathReferences();
				for (int j = 0; j < cpRefs.length; j++) {
					final IVirtualReference cpRef = cpRefs[j];
					IPath cpRefRuntimePath = cpRef.getRuntimePath();

					if (cpRef.getReferencedComponent() instanceof ClasspathDependencyVirtualComponent) {
						// want to avoid adding dups
						ClasspathDependencyVirtualComponent cpComp = (ClasspathDependencyVirtualComponent) cpRef.getReferencedComponent();
						// don't want to process class folder refs here
						if (cpComp.isClassFolder()) {
							continue;
						}
						if (cpRefRuntimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
							// runtime path within deployed app will be runtime path of parent component
							cpRefRuntimePath = runtimePath;
						} 						
						final IPath absolutePath = ClasspathDependencyUtil.getClasspathVirtualReferenceLocation(cpRef);
						if (absolutePaths.contains(absolutePath)) {
							// have already added a member for this archive
							continue;
						} else {
							addUtilMember(component, cpRef, cpRefRuntimePath);
							absolutePaths.add(absolutePath);
						}
					}
				}
			}
		}
	}
	
	private boolean canExportClasspathComponentDependencies(IVirtualComponent component) {
		final IProject project = component.getProject();
		// check for valid project type
		if (J2EEProjectUtilities.isEJBProject(project) 
				|| J2EEProjectUtilities.isDynamicWebProject(project)
				|| J2EEProjectUtilities.isJCAProject(project)
    			|| J2EEProjectUtilities.isUtilityProject(project)) {
			return true;
		}
		return false;
	}
	
	private void saveClasspathDependencyURIs(IVirtualComponent component) {
		if (!component.isBinary() && component instanceof J2EEModuleVirtualComponent) {
			final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) component).getJavaClasspathReferences();
			for (int j = 0; j < cpRefs.length; j++) {
				final IVirtualReference cpRef = cpRefs[j];
				// if we are adding to an EAR project, only process references with the root mapping
				if (!cpRef.getRuntimePath().equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
					// fails the runtime path test
					continue;
				}
				if (cpRef.getReferencedComponent() instanceof VirtualArchiveComponent) {
					classpathComponentDependencyURIs.add(cpRef.getArchiveName());
				}
			}
		}
	}
	
	private void addClassFolderDependencies(final IVirtualComponent component) throws CoreException {
		if (!component.isBinary() && component instanceof J2EEModuleVirtualComponent) {
			final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) component).getJavaClasspathReferences();
			for (int i = 0; i < cpRefs.length; i++) {
				final IVirtualReference cpRef = cpRefs[i];
				final IPath runtimePath = cpRef.getRuntimePath();
				final IVirtualComponent comp = cpRef.getReferencedComponent();
				if (comp instanceof ClasspathDependencyVirtualComponent) {
					final ClasspathDependencyVirtualComponent cpComp = (ClasspathDependencyVirtualComponent) comp;
					if (cpComp.isClassFolder()) {
						IPath targetPath = null;
						if (runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_COMPONENT_PATH)) {
							targetPath = Path.EMPTY;
						} else if (runtimePath.equals(IClasspathDependencyConstants.WEB_INF_CLASSES_PATH)) {
							targetPath =  WEB_CLASSES_PATH;
						} else {
							continue;
						}
						final IContainer container = cpComp.getClassFolder();
						final IModuleResource[] mr = getMembers(container, targetPath, targetPath, new IContainer[]{container});
						for (int j = 0; j < mr.length; j++) {
							members.add(mr[j]);
						}						
					}
				}
			}
		}
	}
	
	/**
	 * Returns <code>true</code> if this module has a simple structure based on a
	 * single root folder, and <code>false</code> otherwise.
	 * <p>
	 * In a single root structure, all files that are contained within the root folder
	 * are part of the module, and are already in the correct module structure. No
	 * module resources exist outside of this single folder.
	 * 
	 * For J2EE, this method will check if the project is already in J2EE spec standard output form.  
	 * The project must follow certain rules, but in general, the project's content roots must be source folders
	 * and the output folder must also be the the content root folder.
	 * </p>
	 * 
	 * @return <code>true</code> if this module has a single root structure, and
	 *    <code>false</code> otherwise
	 */
	public boolean isSingleRootStructure() {
		StructureEdit edit = null;
		try {
			edit = StructureEdit.getStructureEditForRead(getProject());
			if (edit == null || edit.getComponent() == null)
				return false;
			WorkbenchComponent wbComp = edit.getComponent();
			List resourceMaps = wbComp.getResources();
			
			if (J2EEProjectUtilities.isEARProject(getProject())) {
				// Always return false for EARs so that members for EAR are always calculated and j2ee modules
				// are filtered out
				return false;
			} else if (J2EEProjectUtilities.isDynamicWebProject(getProject())) {
				// If there are any web lib jar references, this is not a standard project
				IVirtualReference[] references = ((J2EEModuleVirtualComponent)component).getNonManifestReferences();
				for (int i=0; i<references.length; i++) {
					if (references[i].getReferencedComponent().isBinary())
						return false;
				}
				// Ensure there are only basic component resource mappings -- one for the content folder 
				// and any for src folders mapped to WEB-INF/classes
				if (hasDefaultWebResourceMappings(resourceMaps)) {
					// Verify only one java output folder
					if (getJavaOutputFolders().length==1) {
						// Verify the java output folder is to <content root>/WEB-INF/classes
						IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
						IPath compRootPath = component.getRootFolder().getUnderlyingFolder().getProjectRelativePath();
						if (compRootPath.append(J2EEConstants.WEB_INF_CLASSES).equals(javaOutputPath)) 
							return true;
					}
				}
				return false;
			} else if (J2EEProjectUtilities.isEJBProject(getProject()) || J2EEProjectUtilities.isJCAProject(getProject())
					|| J2EEProjectUtilities.isApplicationClientProject(getProject()) || J2EEProjectUtilities.isUtilityProject(getProject())) {
				// Ensure there are only source folder component resource mappings to the root content folder
				if (isRootResourceMapping(resourceMaps,false)) {
					// Verify only one java outputfolder
					if (getJavaOutputFolders().length==1) {
						// At this point for utility projects, this project is optimized, we can just use the output folder
						if (J2EEProjectUtilities.isUtilityProject(getProject()))
							return true;
						// Verify the java output folder is the same as one of the content roots
						IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
						IContainer[] rootFolders = component.getRootFolder().getUnderlyingFolders();
						for (int i=0; i<rootFolders.length; i++) {
							IPath compRootPath = rootFolders[i].getProjectRelativePath();
							if (javaOutputPath.equals(compRootPath))
								return true;
						}
					}
				}
				return false;
			}
			return true;
		} finally {
			if (edit !=null)
				edit.dispose();
		}
	}
	
	/**
	 * Ensure that any component resource mappings are for source folders and 
	 * that they map to the root content folder
	 * 
	 * @param resourceMaps
	 * @return boolean
	 */
	private boolean isRootResourceMapping(List resourceMaps, boolean isForEAR) {
		// If the list is empty, return false
		if (resourceMaps.size()<1)
			return false;
		
		for (int i=0; i<resourceMaps.size(); i++) {
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
			// Verify it maps to "/" for the content root
			if (!resourceMap.getRuntimePath().equals(Path.ROOT))
				return false;
			// If this is not for an EAR, verify it is also a src container
			if (!isForEAR) {
				IPath sourcePath = getProject().getFullPath().append(resourceMap.getSourcePath());
				if (!isSourceContainer(sourcePath))
					return false;
			}
		}
		return true;
	}
	
	/**
	 * Checks if the path argument is to a source container for the project.
	 * 
	 * @param a workspace relative full path
	 * @return is path a source container?
	 */
	private boolean isSourceContainer(IPath path) {
		IPackageFragmentRoot[] srcContainers = getSourceContainers();
		for (int i=0; i<srcContainers.length; i++) {
			if (srcContainers[i].getPath().equals(path))
				return true;
		}
		return false;
	}
	
	/**
	 * Ensure the default web setup is correct with one resource map and any number of java 
	 * resource maps to WEB-INF/classes
	 * 
	 * @param resourceMaps
	 * @return boolean
	 */
	private boolean hasDefaultWebResourceMappings(List resourceMaps) {
		int rootValidMaps = 0;
		int javaValidRoots = 0;
		
		// If there aren't at least 2 maps, return false
		if (resourceMaps.size()<2)
			return false;
		
		IPath webInfClasses = new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
		for (int i=0; i<resourceMaps.size(); i++) {
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
			IPath sourcePath = getProject().getFullPath().append(resourceMap.getSourcePath());
			
			// Verify if the map is for the content root
			if (resourceMap.getRuntimePath().equals(Path.ROOT)) {
				rootValidMaps++;
			// Verify if the map is for a java src folder and is mapped to "WEB-INF/classes"
			} else if (resourceMap.getRuntimePath().equals(webInfClasses) && isSourceContainer(sourcePath)) {
				javaValidRoots++;
			// Otherwise we bail because we have a non optimized map
			} else {
				return false;
			}
		}
		// Make sure only one of the maps is the content root, and that at least one is for the java folder
		return rootValidMaps==1 && javaValidRoots>0;
	}
	
	/**
	 * This method is added for performance reasons.
	 * It assumes the virtual component is not using any flexible features and is in a standard J2EE format
	 * with one component root folder and an output folder the same as its content folder.  This will bypass 
	 * the virtual component API and just return the module resources as they are on disk.
	 * 
	 * @return array of ModuleResources
	 * @throws CoreException
	 */
	private IModuleResource[] getOptimizedMembers() throws CoreException {
		if (component != null) {
			// For java utility modules, we can just use the output container, at this point we know there is only one
			if (J2EEProjectUtilities.isUtilityProject(getProject())) {
				return getModuleResources(Path.EMPTY, getJavaOutputFolders()[0]);
			}
			// For J2EE modules, we use the contents of the content root
			else {
				IVirtualFolder vFolder = component.getRootFolder();
				return getModuleResources(Path.EMPTY, vFolder.getUnderlyingFolder());
			}
		}
		return new IModuleResource[] {};
	}
	
	/**
	 * This method will return from cache or add to cache whether or not an output container
	 * is mapped in the virtual component.
	 * 
	 * @param outputContainer
	 * @return if output container is mapped
	 */
	private boolean isOutputContainerMapped(IContainer outputContainer) {
		if (outputContainer == null)
			return false;
		
		HashMap outputMaps = getCachedOutputMappings();
		Boolean result = (Boolean) outputMaps.get(outputContainer);
		if (result == null) {
			// If there are any component resources for the container, we know it is mapped
			if (ComponentCore.createResources(outputContainer).length > 0)
				result = Boolean.TRUE;	
			// Otherwise it is not mapped
			else
				result = Boolean.FALSE;
			// Cache the result in the map for this output container
			outputMaps.put(outputContainer, result);
		}
		return result.booleanValue();
	}
	
	/**
	 * Lazy initialize the cached output mappings
	 * @return HashMap
	 */
	private HashMap getCachedOutputMappings() {
		if (cachedOutputMappings==null)
			cachedOutputMappings = new HashMap();
		return cachedOutputMappings;
	}
	
	/**
	 * Lazy initialize the cached source - output pairings
	 * @return HashMap
	 */
	private HashMap getCachedSourceOutputPairs() {
		if (cachedSourceOutputPairs==null)
			cachedSourceOutputPairs = new HashMap();
		return cachedSourceOutputPairs;
	}
	
	/**
	 * This file should be added to the members list from the virtual component maps only if:
	 * a) it is not in a source folder
	 * b) it is in a source folder, and the corresponding output folder is a mapped component resource
	 * 
	 * @return boolean should file be added to members
	 */
	protected boolean shouldAddComponentFile(IFile file) {
		IPackageFragmentRoot sourceContainer = getSourceContainer(file);
		// If the file is not in a source container, return true
		if (sourceContainer==null) {
			return true;
		// Else if it is a source container and the output container is mapped in the component, return true
		// Otherwise, return false.
		} else {
			IContainer outputContainer = getOutputContainer(sourceContainer);
			return outputContainer!=null && isOutputContainerMapped(outputContainer);		
		}
	}
}
