/*******************************************************************************
 * 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.Iterator;
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.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
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.componentcore.JavaEEBinaryComponentHelper;
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.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
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.Property;
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();
	private static String USE_SINGLE_ROOT_PROPERTY = "useSingleRoot"; //$NON-NLS-1$
	protected IPackageFragmentRoot[] cachedSourceContainers;
	protected IContainer[] cachedOutputContainers;
	protected HashMap cachedOutputMappings;
	protected HashMap cachedSourceOutputPairs;
	protected List classpathComponentDependencyURIs = new ArrayList();
	private boolean isSingleJavaOutputNonSource = false;

	/**
	 * 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++) {
								if (files[j] instanceof IModuleFile)
								{
									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());
				String extension = IJ2EEModuleConstants.JAR_EXT;
				if (J2EEProjectUtilities.isDynamicWebProject(module.getProject())) {
					extension = IJ2EEModuleConstants.WAR_EXT;
				} else if (J2EEProjectUtilities.isJCAProject(module.getProject())) {
					extension = IJ2EEModuleConstants.RAR_EXT;
				}
				IVirtualReference reference = webComp.getReference(module.getProject().getName());
				if(reference != null){
					aURI = ComponentUtilities.getDeployUriOfComponent(reference, extension);
				} else {
					aURI = webComp.getDeployedName() + extension;
				}
			}
			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();
		if (app == null) { // if no application.xml, return false
			return false;
		}
		IVirtualReference reference = getReferenceNamed(references,aComponent.getName());
		// Ensure module URI exists on EAR DD for binary archive
		boolean inDD = app.getFirstModule(reference.getArchiveName()) != null;
		return inDD && JavaEEBinaryComponentHelper.getJavaEEQuickPeek(aComponent).getType() != JavaEEQuickPeek.UNKNOWN;
    }
    
    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]);
						}						
					}
				}
			}
		}
	}
	
    /*
     * If the resource to check is a file then this method will return true if the file is linked. If the resource to
     * check is a folder then this method will return true if it, any of its sub directories, or any file contained
     * with-in this directory of any of it's sub directories are linked. Otherwise false is returned.
     */
    private boolean hasLinkedContent(final IResource resourceToCheck) throws CoreException {

    	if ((resourceToCheck != null) && resourceToCheck.isAccessible()) {
    		// skip non-accessible files
    		if (resourceToCheck.isLinked()) {
    			return true;
    		}
    		else {
    			switch (resourceToCheck.getType()) {
    				case IResource.FOLDER:
    					// recursively check sub directory contents
    					final IResource[] subDirContents = ((IFolder) resourceToCheck).members();
    					for (int i = 0; i < subDirContents.length; i++) {
    						if (hasLinkedContent(subDirContents[i])) {
    							return true;
    						}
    					}
    					break;
    				case IResource.FILE:
    					return resourceToCheck.isLinked();
    				default:
    					// skip as we only care about files and folders
    					break;
    			}
    		}
    	}
    	return false;
    }

    /*
     * This method returns true if the root folders of this component have any linked resources (folder or file);
     * Otherwise false is returned.
     */
    private boolean rootFoldersHaveLinkedContent() {

    	if (this.component != null) {
    		final IContainer[] rootFolders = this.component.getRootFolder().getUnderlyingFolders();
    		for (int i = 0; i < rootFolders.length; i++) {
    			try {
    				boolean hasLinkedContent = this.hasLinkedContent(rootFolders[i]);
    				if (hasLinkedContent) {
    					return true;
    				}
    			}
    			catch (CoreException coreEx) {
    				J2EEPlugin.logError(coreEx);
    			}
    		}
    	}
    	return false;
    }
	
	/**
	 * 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() {
		isSingleJavaOutputNonSource = false;
		StructureEdit edit = null;
		try {
			edit = StructureEdit.getStructureEditForRead(getProject());
			if (edit == null || edit.getComponent() == null)
				return false;
			WorkbenchComponent wbComp = edit.getComponent();
			List resourceMaps = wbComp.getResources();
			
			// 229650 - check to see if the property 'useSingleRoot' is defined. If it is set and
			// the value of the property is true then it will override the logic checks below
			final List componentProperties = wbComp.getProperties();
			if (componentProperties != null) {
				final Iterator componentPropertiesIterator = componentProperties.iterator();
				while (componentPropertiesIterator.hasNext()) {
					Property wbProperty = (Property) componentPropertiesIterator.next();
					if (J2EEFlexProjDeployable.USE_SINGLE_ROOT_PROPERTY.equals(wbProperty.getName())) {
						boolean useSingleRoot = Boolean.valueOf(wbProperty.getValue()).booleanValue();
						if (useSingleRoot) {
							return true;
						}
					}
				}
			}
			
			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 linked resources then this is not a singleroot module
				if (this.rootFoldersHaveLinkedContent()) {
					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 (JavaEEProjectUtilities.isEJBProject(getProject()) || JavaEEProjectUtilities.isJCAProject(getProject())
					|| JavaEEProjectUtilities.isApplicationClientProject(getProject()) || JavaEEProjectUtilities.isUtilityProject(getProject())) {
				// if there are any linked resources then this is not a singleroot module
				if (this.rootFoldersHaveLinkedContent()) {
					return false;
				}
				// Ensure there are only source folder component resource mappings to the root content folder
				if (isRootResourceMapping(resourceMaps,false)) {
					IContainer[] javaOutputFolders = getJavaOutputFolders();
					// Verify only one java outputfolder
					if (javaOutputFolders.length==1) {
						// By the time we get here we know: for any folders defined as source in the 
						// .component file that they are also java source folders.
						if (JavaEEProjectUtilities.isUtilityProject(getProject()) || 
								JavaEEProjectUtilities.isEJBProject(getProject()) || 
								JavaEEProjectUtilities.isApplicationClientProject(getProject())) {
							if (! isSourceContainer(javaOutputFolders[0].getFullPath())) {
								// The single output folder is NOT a source folder so this is single-rooted. Since the
								// output folder (something like classes or bin) is not a source folder, JDT copies all files
								// (including non Java files) to this folder, so every resource needed at runtime is located 
								// in a single directory.
								isSingleJavaOutputNonSource = true;
								return true;
							} else {
// Don't implement at this time. Currently, we claim single-rooted when ejbModlule is the output folder.  However,
// we know this is not true because it cannot contain non Java files unless it is the only source folder. But, fixing
// at this time would break all current users.
//								// The single output folder IS a source folder. If there is more than one source folder
//								// then this cannot be single-rooted because JDT does NOTcopy non Java resources into the
//								// output folder when it is a source folder.
//								if (getSourceContainers().length > 1) {
//									return false;
//								} else {
//									// There is only one source folder and since the output folder is a source folder
//									// this is single-rooted.
//									return true;
//								}
							}
						}
//						// 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 can ONLY be called when the project is single root.
	 * @see isSingleRootStructure().  If the project has an output folder that is also a source folder then,
	 * 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) {
			if (isSingleJavaOutputNonSource) {
				// We determined when testing for a single root structure that this project has
				// one output folder and that output folder is not a source folder. Since the
				// output folder (for example, classes or bin) is not a source folder, JDT copies all files
				// (including non Java files) to this folder, so every resource needed at runtime is located 
				// in that single output directory.
				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);		
		}
	}
}
