/*******************************************************************************
 * Copyright (c) 2004, 2021 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060330   124667 kathy@ca.ibm.com - Kathy Chan
 * 20060421   136761 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060424   115690 sengpl@ca.ibm.com - Seng Phung-Lu
 * 20060503   126819 rsinha@ca.ibm.com - Rupam Kuehner
 * 20080122   215866 trungha@ca.ibm.com - Trung Ha
 * 20080303   218696 ericdp@ca.ibm.com - Eric D. Peters, APIs using EJBArtifactEdit not able to deal with some EJB 3.0 beans properly
 * 20080626   236645 kathy@ca.ibm.com - Kathy Chan
 * 20110824   355771 kchong@ca.ibm.com - Keith Chong, Remove unused/dead code as reported in build reports 
 *******************************************************************************/
package org.eclipse.jst.ws.internal.common;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.applicationclient.componentcore.util.AppClientArtifactEdit;
import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.ejb.componentcore.util.EJBArtifactEdit;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.javaee.ejb.SessionBean;
import org.eclipse.jst.ws.internal.plugin.WebServicePlugin;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.common.environment.EnvironmentService;
import org.eclipse.wst.common.environment.ILog;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.model.IURLProvider;

/**
 * This class contains useful methods for working with Eclipse resources.
 */
public final class ResourceUtils {

	// Keeps the IWorkspaceRoot hanging around. See getWorkspaceRoot().
	private static IWorkspaceRoot root_ = null;

	// Keeps the IWorkspace hanging around. See getWorkspace().

	private static IWorkspace workspace_ = null;

	/**
	 * As returned by {@link #getProjectType getProjectType()}, indicates that
	 * the given project has no Java or Web nature.
	 */
	public static byte PROJECT_TYPE_NONE = 0;

	/**
	 * As returned by {@link #getProjectType getProjectType()}, indicates that
	 * the given project has a Java project nature.
	 */
	public static byte PROJECT_TYPE_JAVA = 1;

	/**
	 * As returned by {@link #getProjectType getProjectType()}, indicates that
	 * the given project has a Web project nature.
	 */
	public static byte PROJECT_TYPE_WEB = 2;

	/**
	 * As returned by {@link #getProjectType getProjectType()}, indicates that
	 * the given project has an EJB project nature.
	 */
	public static byte PROJECT_TYPE_EJB = 4;
	
	/**
	 * As returned by {@link #getProjectType getProjectType()}, indicates that
	 * the given project has an Application client project nature.
	 */	
	public static byte PROJECT_TYPE_APPCLIENT = 8;

	/**
	 * The SOAP rpcrouter servlet extension to be added to web project URL
	 */
	public static String SERVLET_EXT = "/servlet/rpcrouter";

	private static final String DEFAULT_CLIENT_WEB_PROJECT_EXT = "Client";
    private static final String DEFAULT_CLIENT_EJB_PROJECT_EXT = "EJBClient";
	private static final String DEFAULT_EJB_PROJECT_NAME = "WebServiceEJBProject";
    private static final String DEFAULT_EJB_COMPONENT_NAME = "WebServiceEJB";
	private static final String DEFAULT_WEB_PROJECT_NAME = "WebServiceProject";
    private static final String DEFAULT_WEB_COMPONENT_NAME = "WebServiceProject";
	private static final String DEFAULT_ROUTER_PROJECT_EXT = "Router";

	private static final String DEFAULT_SERVICE_EAR_PROJECT_NAME = "WebServiceProjectEAR";
    private static final String DEFAULT_SERVICE_EAR_COMPONENT_NAME = "WebServiceProjectEAR";
	private static final String DEFAULT_CLIENT_EAR_PROJECT_NAME = "WebServiceProjectClientEAR";
    private static final String DEFAULT_CLIENT_EAR_COMPONENT_NAME = "WebServiceProjectClientEAR";
    
    private static final String DEFAULT_EAR_EXT = "EAR";

	/**
	 * Returns the IWorkspaceRoot object.
	 * @return The IWorkspaceRoot object.
	 */
	public static IWorkspaceRoot getWorkspaceRoot() {
		if (root_ == null) {
			root_ = ResourcesPlugin.getWorkspace().getRoot();
		}
		return root_;
	}

	/**
	 * Returns the IWorkspace object.
	 * @return The IWorkspace object.
	 */
	public static IWorkspace getWorkspace() {
		if (workspace_ == null) {
			if (root_ == null) {
				root_ = ResourcesPlugin.getWorkspace().getRoot();
			}
			workspace_ = root_.getWorkspace();
		}
		return workspace_;
	}

	/**
	 * Returns an {@link org.eclipse.core.resources.IResource IResource}of the
	 * given absolute pathname or null if no such resource exists.
	 * 
	 * @param absolutePathname
	 *            The absolute path of the resource.
	 * @return The <code>IResource</code>.
	 */
	public static IResource findResource(String absolutePathname) {
		if (absolutePathname == null) {
			return null;
		}
		return findResource(new Path(absolutePathname));
	}

	/**
	 * Returns an {@link org.eclipse.core.resources.IResource IResource}of the
	 * given absolute path or null if no such resource exists.
	 * 
	 * @param absolutePath
	 *            The absolute <code>IPath</code> of the resource.
	 * @return The <code>IResource</code>.
	 */
	public static IResource findResource(IPath absolutePath) {
		if (absolutePath == null) {
			return null;
		}
		return ResourceUtils.getWorkspaceRoot().findMember(absolutePath);
	}

	/**
	 * Returns an {@link org.eclipse.core.resources.IResource IResource}of the
	 * given file system relative pathname and project or null if no such resource exists.
	 *
	 * @param filePath File system relative pathname
	 * @param project Project
	 * @return The <code>IResource</code>.
	 */
	public static IResource findResourceAtLocation(String filePath, IProject project) {
		
		return findResource(findPathAtLocation( new Path(filePath), project));
	}
	
	/**
	 * This method attempts to convert a path that is relative to a file system
	 * to a path that is relative to the workspace. Instead of comparing the
	 * filePath with the install location of the workspace (i.e.
	 * Platform.getLocation()), the filePath is compared with the location of the project
	 * since the project could be in a location other than the the default location relative to the
	 * workspace.
	 * 
	 * @param filePath	File path relative to a file system
	 * @param project	The project the file is in
	 * @return 			Path relative to the workspace
	 */
	public static IPath findPathAtLocation(IPath filePath, IProject project) {
		IPath result = null;

		IPath projectLocation = project.getLocation();

		if (projectLocation.matchingFirstSegments(filePath) == projectLocation
				.segmentCount()) {
			filePath = filePath.removeFirstSegments(projectLocation
					.segmentCount() - 1);
			result = filePath.setDevice(null);
		}

		return result;
	}
	/**
	 * Validates the given string as a name for a resource of the given type(s).
	 * This method obeys the contract of
	 * {@link org.eclipse.core.resources.IWorkspace#validateName IWorkspace.validateName()}.
	 * 
	 * @param segment
	 *            The path to validate.
	 * @param typeMask
	 *            The <code>IResource</code> type or types.
	 * @return The status with a value if <code>IStatus.OK</code> if the path
	 *         is valid, or with appropriate severity and message information if
	 *         the path is not valid.
	 *         
	 * @deprecated not used         
	 */
	public static IStatus validateName(String segment, int typeMask) {
		return getWorkspace().validateName(segment, typeMask);
	}

	/**
	 * Validates the given string as the path of a resource of the given
	 * type(s). This method obeys the contract of
	 * {@link org.eclipse.core.resources.IWorkspace#validatePath IWorkspace.validatePath()}.
	 * 
	 * @param path
	 *            The path to validate.
	 * @param typeMask
	 *            The <code>IResource</code> type or types.
	 * @return The status with a value if <code>IStatus.OK</code> if the path
	 *         is valid, or with appropriate severity and message information if
	 *         the path is not valid.
	 * @deprecated not used 
	 */
	public static IStatus validatePath(String path, int typeMask) {
		return getWorkspace().validatePath(path, typeMask);
	}

	/**
	 * Validates the given Java type name.
	 * 
	 * @param typeName
	 *            The Java type name.
	 * @return The status with a value of <code>IStatus.OK</code> if the name
	 *         is valid, or with appropriate severity and message information if
	 *         name is not valid. The primitive types (boolean, char, byte,
	 *         short, int, long, float, double) are valid. Arrays of valid types
	 *         are themselves valid.
	 * @deprecated use JavaConventions in the jdt core 
	 */
	public static IStatus validateJavaTypeName(String typeName) {
		//
		// Strip off the trailing array bits, if any.
		//
		int a = typeName.indexOf('[');
		if (a > 0) {
			typeName = typeName.substring(0, a);
		}
		//
		// Allow primitives.
		//
		if (isPrimitiveJavaType(typeName)) {
			return new Status(IStatus.OK, WebServicePlugin.ID, 0, "", null);
		}
		//
		// Defer to JavaConventions.
		//
		return JavaConventions.validateJavaTypeName(typeName);
	}

	/**
	 * Returns true if the given <code>typeName</code> is a Java primitive
	 * (boolean, char, byte, short, int, long, float, double).
	 * 
	 * @return True if the type name is a Java primitive.
	 * 
	 * @deprecated
	 */
	public static boolean isPrimitiveJavaType(String typeName) {
		return (typeName.equals("boolean") || typeName.equals("char")
				|| typeName.equals("byte") || typeName.equals("short")
				|| typeName.equals("int") || typeName.equals("long")
				|| typeName.equals("float") || typeName.equals("double"));
	}

	/**
	 * Returns the handle of the IProject at the beginning of the given
	 * <code>absolutePath</code>. Neither the given path nor the project need
	 * exist in the workspace. The path must be absolute, and must consist of at
	 * least one segment.
	 * 
	 * @return An IProject handle for the project at the beginning of the given
	 *         <code>absolutePath</code>, or null if the path does not
	 *         specify a project.
	 */
	public static IProject getProjectOf(IPath absolutePath) {
		if (absolutePath.isAbsolute()) {
			String projectName = absolutePath.segment(0);
			if (projectName != null) {
				return getWorkspaceRoot().getProject(projectName);
			}
		}
		return null;
	}

	/**
	 * 
	 * @param absolutePath
	 * @return
	 */
	public static IVirtualComponent getComponentOf(IPath absolutePath){
		if (absolutePath.isAbsolute()) {
				String projectName = absolutePath.segment(0);
				IProject project = getWorkspaceRoot().getProject(projectName);
				if (projectName != null) {
					return ComponentCore.createComponent(project);
				}
		}
		return null;
	}
	
	public static IVirtualComponent getComponentOf(IResource res)
	{
		IVirtualResource[] vresources = ComponentCore.createResources(res);
		IVirtualComponent vcomp = null;
		if (vresources != null && vresources.length>0)
		{
			IVirtualResource vres = vresources[0];
			vcomp = vres.getComponent();
		}
		return vcomp;
	}
	
	
	/**
	 * Returns true if the given <code>project</code> is a Java Project.
	 * 
	 * @param project
	 *            The project.
	 * @return True if the project is a Java Project.
	 */
	public static boolean isJavaProject(IProject project) {
		try
		{
		  return project.hasNature(JavaCore.NATURE_ID);
		}
		catch (CoreException ce)
		{
			//Return false if CoreException occurs while checking nature.
			return false;
		}
	}

	/**
	 * Returns true if the given <code>project</code> is a Java Project.
	 * 
	 * @param project
	 *            The project.
	 * @return True if the project is a Java Project.
	 */
	public static boolean isTrueJavaProject(IProject project) {
		return (!isWebProject(project) && !isAppClientProject(project) && !isEARProject(project)
				&& !isEJBProject(project) && isJavaProject(project));
		/*
		 * try { String[] natures = project.getDescription().getNatureIds();
		 * return (natures.length == 1 &&
		 * natures[0].equals(JavaCore.NATURE_ID)); } catch (CoreException e) { }
		 * return false;
		 */
	}

	/**
	 * Returns true if the given <code>project</code> is a Web Project.
	 * Note: For components; use J2EEUtils.isWebComponent()
	 * @param project
	 *            The project.
	 * @return True if the project is a Web Project.
   * 
   * @deprecated
	 */
	public static boolean isWebProject(IProject project) {
		boolean isWeb = false;
		StructureEdit mc = null;
		try {
		  mc = StructureEdit.getStructureEditForRead(project);
		  WorkbenchComponent[] wbcs = mc.getWorkbenchModules();
		  if (wbcs.length!=0) {
			  //isWeb = WebArtifactEdit.isValidWebModule(wbcs[0]);
		  }
		}
		catch(Exception ex){
			// handle exception
		}
		finally{
			if (mc!=null)
				mc.dispose();
		}

		return isWeb;
	}

	/**
	 * Note: for components; use J2EEUtils.isEARComponent()
	 * @param project
	 * @return
   * 
   * @deprecated
	 */
	public static boolean isEARProject(IProject project){
		boolean isEAR = false;
		StructureEdit mc = null;
		try {
		  mc = StructureEdit.getStructureEditForRead(project);
		  WorkbenchComponent[] wbcs = mc.getWorkbenchModules();
		  if (wbcs.length!=0) {
			EARArtifactEdit earEdit = null;
			try {
			  //earEdit = EARArtifactEdit.getEARArtifactEditForRead(wbcs[0]);
//			  if (earEdit!=null){
//				isEAR = true;
//			  }
			}
			finally{
				if (earEdit!=null)
					earEdit.dispose();
			}
		  }
		}
		catch(Exception ex){}
		finally{
			if (mc!=null)
				mc.dispose();
		}
		
		return isEAR;
	}
	/**
	 * Returns true if the given <code>project</code> is an EJB 1.1 or EJB 2.0
	 * Project.
	 * Note: for components, use J2EEUtils.isEJBComponent
	 * @param project
	 *            The project.
	 * @return True if the project is an EJB 1.1 or an EJB 2.0 Project.
   * 
   * @deprecated
   * 
	 */
	public static boolean isEJBProject(IProject project) {
		boolean isEJB = false;
		StructureEdit mc = null;
		try {
		  mc = StructureEdit.getStructureEditForRead(project);
		  WorkbenchComponent[] wbcs = mc.getWorkbenchModules();
		  if (wbcs.length!=0) {
			EJBArtifactEdit ejbEdit = null;
			try {
			  //ejbEdit = EJBArtifactEdit.getEJBArtifactEditForRead(wbcs[0]);
//			  if (ejbEdit!=null){
//				isEJB = true;
//			  }
			}
			finally{
				if (ejbEdit!=null)
					ejbEdit.dispose();
			}
		  }
		}
		catch(Exception ex){}
		finally{
			if (mc!=null)
				mc.dispose();
		}
		
		return isEJB;	
	}

	/**
	 * Returns true if the given <code>project</code> is an Application Client
	 * Project.
	 * Note: for components, use J2EEUtils.isAppClientComponent()
	 * @param project
	 *            The project.
	 * @return True if the project is an Application Client Project
   * 
   * @deprecated
	 */
	public static boolean isAppClientProject(IProject project) {
		boolean isAppClient = false;
		StructureEdit mc = null;
		try {
		  mc = StructureEdit.getStructureEditForRead(project);
		  WorkbenchComponent[] wbcs = mc.getWorkbenchModules();
		  if (wbcs.length!=0) {
			AppClientArtifactEdit appClientEdit = null;
			try {
				//appClientEdit = AppClientArtifactEdit.getAppClientArtifactEditForRead(wbcs[0]);
//			  if (appClientEdit!=null){
//				  isAppClient = true;
//			  }
			}
			finally{
				if (appClientEdit!=null)
					appClientEdit.dispose();
			}
		  }
		}
		catch(Exception ex){}
		finally{
			if (mc!=null)
				mc.dispose();
		}
		
		return isAppClient;	
	}

	/**
	 * Returns the type of the given <code>project</code> as a bitmask.
	 * Relevant bitmask values are:
	 * <ol>
	 * <li>{@link #PROJECT_TYPE_JAVA PROJECT_TYPE_JAVA}
	 * <li>{@link #PROJECT_TYPE_WEB PROJECT_TYPE_WEB}
	 * <li>{@link #PROJECT_TYPE_EJB PROJECT_TYPE_EJB}
	 * <li>{@link #PROJECT_TYPE_NONE PROJECT_TYPE_NONE}
	 * </ol>
	 * 
	 * @param project
	 *            The project.
	 * @return The type bitmask of the project.
	 * 
	 * @deprecated use getComponentType
	 */ 
	public static byte getProjectType(IProject project) {
		byte projectType = PROJECT_TYPE_NONE;
		if (ResourceUtils.isJavaProject(project)) {
			projectType |= PROJECT_TYPE_JAVA;
		}
		if (ResourceUtils.isWebProject(project)) {
			projectType |= PROJECT_TYPE_WEB;
		}
		if (ResourceUtils.isEJBProject(project)) {
			projectType |= PROJECT_TYPE_EJB;
		}
		return projectType;
	}

	/**
	 * Returns the component type id as defined in IModuleConstants
	 * i.e. IModuleConstants.JST_WEB_MODULE = "jst.web"
	 * @param project
	 * @return
	 */
	public static String getComponentType(IProject project){
		return J2EEProjectUtilities.getJ2EEProjectType(project);
	}
	
	/**
	 * Returns the component type
	 * @param component
	 * @return
	 */
	public static String getComponentType(IVirtualComponent component){
		return getComponentType(component.getProject());
	}
	
	/**
	 * Returns WebModule Deployable of the <code>project</code> as an
	 * <code>IDeployable</code>, or null if the project has no Web nature.
	 * 
	 * @param project
	 *            The project.
	 * @return WebModule Deployable of the <code>project</code> or null if the
	 *         project has no Web nature.
	 */
	public static IModule getModule(IProject project) {
	return ServerUtil.getModule(project);
}
	
// Workaround for 113621 
//public static IModule getModule(IProject project) {
//	IModule[] modules = ServerUtil.getModules(project);
//	if (modules!=null && modules.length!=0) {
//		return modules[0];
//	}
//	return null;
//}

	/**
	 * Returns the build output location of the <code>project</code> as an
	 * <code>IPath</code>, or null if the project has no Java nature.
	 * i.e. WP\.deployables\webModule\WEB-INF\classes
	 * @param project
	 *            The project.
	 * @return The build output location of the <code>project</code> or null
	 *         if the project has no Java nature.
	 */
	public static IPath getJavaOutputLocation(IProject project) {
		IPath outputLocation = null;
		try {
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				outputLocation = javaProject.getOutputLocation();
			}
		} catch (JavaModelException e) {
		}
		ILog log = EnvironmentService.getEclipseLog();
		log.log(ILog.INFO, 5032, ResourceUtils.class, "getJavaOutputLocation",
				"project=" + project + ",outputLocation=" + outputLocation);

		return outputLocation;
	}

	/**
	 * Returns a build source location of the <code>project</code> as an
	 * <code>IPath</code>, or null if the project either has no Java nature
	 * or if the project's build classpath contains no folders local to the
	 * project. If the project has more than one of its own folders on the build
	 * classpath, then one of them is chosen arbitrarily as the build source
	 * location. To work with all entries on the build classpath, use
	 * {@link #getJavaPackageFragmentRoots getJavaPackageFragmentRoots()}or
	 * {@link #getJavaClasspath getJavaClasspath()}.
	 * 
	 * @param project
	 *            The project.
	 * @return A build source location of the <code>project</code> or null if
	 *         the project has no Java nature or if the project's build
	 *         classpath contains no folders local to the project.
	 */

	public static IPath getJavaSourceLocation(IProject project) {
		IPath sourceLocation = null;
		IPackageFragmentRoot[] fragmentRoots = getJavaPackageFragmentRoots(project);
		for (int i = 0; i < fragmentRoots.length && sourceLocation == null; i++) {
			try {
				IResource fragmentRoot = fragmentRoots[i]
						.getCorrespondingResource();
				if (fragmentRoot != null
						&& (fragmentRoot.getProject().equals(project))
						&& (fragmentRoot.getType() != IResource.FILE)) {
					sourceLocation = fragmentRoot.getFullPath();
				}
			} catch (JavaModelException e) {
			}
		}

		ILog log = EnvironmentService.getEclipseLog();
		log.log(ILog.INFO, 5030, ResourceUtils.class, "getJavaSourceLocation",
				"project=" + project + ",sourceLocation=" + sourceLocation);
		
		return sourceLocation;
	}

	
	/**
	 * Returns the "JavaSource" folder
	 * @param project
	 * @return
	 */
    /*
	public static IPath getJavaSourceLocation(IProject project){
		IVirtualComponent component = ComponentCore.createComponent(project);
		return getJavaSourceLocation(component);			
	}
	*/
	/**
	 * Returns the JavaSource location folder
	 * @param comp
	 * @return
	 */
	public static IPath getJavaSourceLocation(IVirtualComponent comp){
		if (comp!=null){
		   IVirtualFolder folder = comp.getRootFolder().getFolder(new Path("/WEB-INF/classes"));
		   return folder.getWorkspaceRelativePath();
		}
		return null;
	}
	
	/**
	 * Returns the JavaSource locations in each project
	 * @param project
	 * @return
	 */
	public static IPath[] getAllJavaSourceLocations(IProject project) {
		try {
			IClasspathEntry[] entries = JavaCore.create(project).getRawClasspath();
			List<IPath> paths = new ArrayList<IPath>();
			for (int i = 0; i < entries.length; i++) {
				if (IClasspathEntry.CPE_SOURCE == entries[i].getEntryKind()) {
					paths.add(entries[i].getPath());
				}
			}
			return paths.toArray(new IPath[paths.size()]);
		}
		catch (JavaModelException e1) {
			Platform.getLog(WebServicePlugin.getInstance().getBundle()).error(e1.getLocalizedMessage(), e1);
		}

		Vector<IPath> pathVector = new Vector<IPath>();
		IPackageFragmentRoot[] fragmentRoots = getJavaPackageFragmentRoots(project);

		for (int i = 0; i < fragmentRoots.length; i++) {
			try {
				IResource fragmentRoot = fragmentRoots[i].getCorrespondingResource();
				if (fragmentRoot != null && (fragmentRoot.getProject().equals(project))
						&& (fragmentRoot.getType() != IResource.FILE)) {
					pathVector.add(fragmentRoot.getFullPath());
				}
			} catch (JavaModelException e) {
			}
		}
		return (IPath[]) pathVector.toArray(new Path[pathVector.size()]);
	}

	public static IPath[] getAllJavaSourceLocations(IVirtualComponent[] components) {

		if (components!=null){
			List javaSourcePaths = new ArrayList();
			for (int i=0;i<components.length;i++){
				IPath path = getJavaSourceLocation(components[i]);
				javaSourcePaths.add(path);
			}
			return (IPath[])javaSourcePaths.toArray(new IPath[0]);
		}
		return null;
	}
	
	/**
	 * Returns a build source package fragment root of the <code>project</code>
	 * as an <code>IPackageFragmentRoot</code>, or null if the project either
	 * has no Java nature or if the project's build classpath contains no
	 * folders local to the project. If the project has more than one of its own
	 * folders on the build classpath, then one of them is chosen arbitrarily as
	 * the build source location.
	 * 
	 * @param project
	 *            The project.
	 * @return A build source package fragment root of the <code>project</code>
	 *         or null if the project has no Java nature or if the project's
	 *         build classpath contains no folders local to the project.
	 *         
	 * @deprecated not used
	 */
	public static IPackageFragmentRoot getJavaSourcePackageFragmentRoot(IProject project) {
		IPackageFragmentRoot packageFragmentRoot = null;
		IPath javaSourceLocation = getJavaSourceLocation(project);
		try {
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				packageFragmentRoot = javaProject.findPackageFragmentRoot(javaSourceLocation);
			}
		} catch (JavaModelException e) {
		}
		return packageFragmentRoot;
	}

	/**
	 * Returns the package fragment roots of the <code>project</code> as an
	 * array of <code>IPackageFragmentRoot</code> objects. If the project has
	 * no Java nature then the returned array will be of length zero.
	 * 
	 * @param project
	 *            The project.
	 * @return The package fragment roots of the <code>project</code>.
	 */
	public static IPackageFragmentRoot[] getJavaPackageFragmentRoots(IProject project) {
		try {
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				IPackageFragmentRoot[] packageFragmentRoots = javaProject
						.getPackageFragmentRoots();
				return packageFragmentRoots;
			}
		} catch (JavaModelException e) {
		}
		return new IPackageFragmentRoot[0];
	}

	/**
	 * Returns the build classpath entries of the <code>project</code> as an
	 * array of <code>IClasspathEntry</code> objects. If the project has no
	 * Java nature then the returned array will be of length zero.
	 * 
	 * @param project
	 *            The project.
	 * @return The classpath entries of the <code>project</code>.
	 * 
	 * @deprecated not used
	 */
	public static IClasspathEntry[] getJavaClasspath(IProject project) {
		try {
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				IClasspathEntry[] classpathEntries = javaProject.getRawClasspath();
				return classpathEntries;
			}
		} catch (JavaModelException e) {
		}
		return new IClasspathEntry[0];
	}

	/**
	 * 
	 * @param project
	 * @return
	 */
	public static IFolder getWebComponentServerRoot(IProject project){
		
      IFolder webModuleServerRoot = null;
      IVirtualComponent vc = ComponentCore.createComponent(project);
      if (vc.exists())
        webModuleServerRoot = J2EEUtils.getOutputContainerRoot(vc);

	  return webModuleServerRoot;
	}
	
	/**
	 * 
	 * @param project
	 * @return
	 */
	public static IPath getWebComponentServerRootPath(IProject project){
		
      IContainer webModuleServerRoot = null;
      IVirtualComponent vc = ComponentCore.createComponent(project);
      if (vc != null && vc.exists()){
        IContainer[] containers = J2EEProjectUtilities.getOutputContainers(project.getProject());
        if (containers.length > 0)
          webModuleServerRoot = containers[0];
      }
      
      if (webModuleServerRoot != null) 
    	return webModuleServerRoot.getFullPath();
      return null;
	}

	/**
	 * Returns the URL string corresponding to the web server module root of the
	 * project in a server instance or null if the project has no Web nature or
	 * has no association to a server instance.
	 * 
	 * @param project
	 *            The project.
	 * @return The web server module root URL or null if the project has no Web
	 *         nature or has no association to a server instance.
	 * @deprecated use getWebComponentURL(..) which belongs in ServerUtils
	 */
	public static String getWebProjectURL(IProject project,
			String serverFactoryId, IServer server) {

		String webProjectURL = null;
		IModule module = getModule(project);
		if (module != null) {
			IServer serverInstance = ServerUtils.getServerForModule(module,
					serverFactoryId, server, true, new NullProgressMonitor());
			if (serverInstance != null) {
//				URL url = ((IURLProvider) serverInstance.getDelegate()).getModuleRootURL(module);
				URL url = ((IURLProvider)serverInstance.getAdapter(IURLProvider.class)).getModuleRootURL(module);
				if (url != null) {
					String s = url.toString();
					webProjectURL = (s.endsWith("/") ? s.substring(0, s
							.length() - 1) : s);
				}
			}
		}
		
		ILog log = EnvironmentService.getEclipseLog();
		log.log(ILog.INFO, 5036, ResourceUtils.class, "getWebProjectURL",
				"project=" + project + ",webProjectURL=" + webProjectURL);

		return webProjectURL;
	}
	
	/**
	 * Returns the forged URL string corresponding to the web server module root
	 * of the project in a server instance or null if the project has no Web
	 * nature or has no association to a server instance.
	 * 
	 * @param project
	 * @return The web server module root URL or null if the project has no Web
	 *         nature or has no association to a server instance.
	 * @deprecated  not used
	 */
//	public static String getForgedWebProjectURL(IProject project, String serverFactoryId, IServer server){
//  	
//  	String webProjectURL = null;
//  	IModule module = getModule(project);
//  	if (module != null)
//  	{
//  		//IServer serverInstance = ServerUtils.getServerForModule(module,
//		  // serverFactoryId, server, true, new NullProgressMonitor());
//  		if (server != null)
//  		{
//  			String hostname = server.getHost();
//
//  			// get ServerPort
//  			int portNumber = 0;
//
//  	          ServerPort[] ports = server.getServerPorts(null);
//  	          ServerPort port = null;
//  	          for (int it = 0; it<ports.length; it++)
//  	          {
//  	            ServerPort p = ports[it];
//  	            String protocol = p.getProtocol();
//  	            if (protocol != null && protocol.trim().toLowerCase().equals("http"))
//  	            {
//  	              port = p;
//  	              portNumber = p.getPort();
//  	              break;
//  	            }
//  	          }
//  	          
//  	        
//  	        
//  	        URL url = null;
//  	        try {
//  	        	url = new URL("http", hostname, portNumber, "");
//  	        }
//  	        catch(Exception e){
//  	        	e.printStackTrace();
//  	        }
//
//  	        
//  			//URL url = ((IURLProvider) serverInstance.getDelegate()).getModuleRootURL(module);
//  			
//  			if (url != null)
//  			{
//  				String s = url.toString();
//  				webProjectURL = s + "/"+project.getName();
//  				//webProjectURL = (s.endsWith("/") ? s.substring(0,s.length()-1) : s);
//  			}
//  		}
//  	}
// 	ILog log = new EclipseLog();
//    log.log(ILog.INFO, 5036, ResourceUtils.class, "getWebProjectURL", "project="+project+",webProjectURL="+webProjectURL);
//  	return webProjectURL;  	
//  }
	/**
	 * Returns the URL string corresponding to the web server module root of the
	 * project in a server instance or null if the project has no Web nature or
	 * has no association to a server instance.
	 * 
	 * @param project
	 *            The project.
	 * @return The web server module root URL or null if the project has no Web
	 *         nature or has no association to a server instance.
	 * @deprecated belongs in ServerUtils
	 *
	 */
	public static String getWebProjectURL(IProject project) {
		String webProjectURL = null;
		IModule module = getModule(project);
		if (module != null) {
			IServer serverInstance = ServerUtils.getServerForModule(module);
			if (serverInstance != null) {
				URL url = ((IURLProvider)serverInstance.getAdapter(IURLProvider.class)).getModuleRootURL(module);
				if (url != null) {
					String s = url.toString();
					webProjectURL = (s.endsWith("/") ? s.substring(0, s
							.length() - 1) : s);
				}
			}
		}
		ILog log = EnvironmentService.getEclipseLog();
		log.log(ILog.INFO, 5037, ResourceUtils.class, "getWebProjectURL",
				"project=" + project + ",webProjectURL=" + webProjectURL);

		return webProjectURL;
	}

	/**
	 * 
	 * @param project
	 * @return
	 * 
	 * @deprecated should be in ServerUtils
	 */
	public static String getEncodedWebProjectURL(IProject project) {
		String url = getWebProjectURL(project);
		if (url != null) {
			int index = url.lastIndexOf('/');
			if (index != -1) {
				StringBuffer encodedURL = new StringBuffer();
				encodedURL.append(url.substring(0, index + 1));
				try {
					String ctxtRoot = URLEncoder.encode(url.substring(index + 1, url.length()), "UTF-8");
					int plusIndex = ctxtRoot.indexOf('+');
					while (plusIndex != -1) {
						StringBuffer sb = new StringBuffer();
						sb.append(ctxtRoot.substring(0, plusIndex));
						sb.append("%20");
						sb.append(ctxtRoot.substring(plusIndex + 1, ctxtRoot
							.length()));
						ctxtRoot = sb.toString();
						plusIndex = ctxtRoot.indexOf('+');
					}
					encodedURL.append(ctxtRoot);
				}catch (IOException io){
					//handler exception
				}				
				url = encodedURL.toString();
			}
		}
		return url;
	}

	/**
	 * Given the <code>absolutePath</code> of a Java resource, returns the
	 * package name of the resource or null if the resource is not properly
	 * located in a project or folder on the build classpath or that is the
	 * build output path.
	 * 
	 * @param absolutePath
	 *            The absolute path of the Java resource.
	 * @return the package name of the Java resource.
	 */
	public static String getJavaResourcePackageName(IPath absolutePath) {
		try {
			IPath javaFolderPath = absolutePath.removeLastSegments(1);
			IProject project = getProjectOf(absolutePath);
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				IPackageFragment fragment = javaProject
						.findPackageFragment(javaFolderPath);
				if (fragment != null) {
					return fragment.getElementName();
				}
				IPath outputPath = getJavaOutputLocation(project);
				if (outputPath.isPrefixOf(javaFolderPath)) {
					IPath javaPackagePath = javaFolderPath
							.removeFirstSegments(outputPath.segmentCount());
					return javaPackagePath.isEmpty() ? null : javaPackagePath
							.toString().replace(IPath.SEPARATOR, '.');
				}
			}
		} catch (JavaModelException e) {
		}
		return null;
	}

	/**
	 * Given the <code>absolutePath</code> of a Java resource, returns the
	 * package name of the resource as a relative pathname or null if the
	 * resource is not properly located in a project or folder on the build
	 * classpath.
	 * 
	 * @param absolutePath
	 *            The absolute path of the Java resource.
	 * @return the package name of the Java resource as a relative path.
	 */
	public static IPath getJavaResourcePackagePath(IPath absolutePath) {
		String packageName = ResourceUtils
				.getJavaResourcePackageName(absolutePath);
		return (packageName == null ? null : new Path(packageName.replace('.',
				IPath.SEPARATOR)));
	}

	/**
	 * Given the <code>absolutePath</code> of a Java resource, returns the
	 * absolute path of the project or folder that is on the build classpath or
	 * is the build output path and that contains the fully qualified Java
	 * resource, or null if no such project or folder exists.
	 * 
	 * @param absolutePath
	 *            The absolute path of the Java resource.
	 * @return The absolute path of the project or folder containing the fully
	 *         qualified Java resource.
	 * @deprecated not used
	 */
	public static IPath getJavaResourceRootPath(IPath absolutePath) {
		try {
			IProject project = getProjectOf(absolutePath);
			IJavaProject javaProject = JavaCore.create(project);
			if (javaProject != null) {
				IPackageFragmentRoot[] pfrs = javaProject
						.getPackageFragmentRoots();
				for (int i = 0; i < pfrs.length; i++) {
					IResource fragmentRoot = pfrs[i].getCorrespondingResource();
					if (fragmentRoot != null) {
						IPath fragmentPath = fragmentRoot.getFullPath();
						if (fragmentPath.isPrefixOf(absolutePath)) {
							return fragmentPath;
						}
					}
				}
				IPath outputPath = getJavaOutputLocation(project);
				if (outputPath.isPrefixOf(absolutePath)) {
					return outputPath;
				}
			}
		} catch (JavaModelException e) {
		}
		return null;
	}

	/**
	 * Determines an URL (HTTP or FILE) to an Eclipse resource, returning the
	 * URL string if successful and false otherwise. A value of null will
	 * definitely be returned if any of the following conditions are not met:
	 * <ol>
	 * <li>The absolute path begins with a Web Project.
	 * <li>The leading portion of the absolute path matches the path of the
	 * container returned by {#link #getWebModuleServerRoot
	 * getWebModuleServerRoot} for the project.
	 * <li>The path does not lead to the WEB-INF folder or any descendent
	 * thereof.
	 * <li>The Web Project is associated with an explicit or default server
	 * instance.
	 * </ol>
	 * 
	 * @param absolutePath
	 *            The absolute path of the resource.
	 * @return The URL of the file, or null if no URL can be determined.
	 * @deprecated not used
	 */
//	public static String getURLFromPath(IPath absolutePath,
//			String serverFactoryId, IServer server) {
//		return getURLFromPath(absolutePath, getWebProjectURL(
//				getProjectOf(absolutePath), serverFactoryId, server));
//	}

	/**
	 * 
	 * @param absolutePath
	 * @param webProjectURL
	 * @return
	 * @deprecated not used
	 */
//	public static String getURLFromPath(IPath absolutePath, String webProjectURL) {
//		StringBuffer url = new StringBuffer();
//		IProject project = getProjectOf(absolutePath);
//		IContainer webModuleServerRoot = getWebModuleServerRoot(project);
//		if (webModuleServerRoot != null) {
//			IPath webModuleServerRootPath = webModuleServerRoot.getFullPath();
//			if (webModuleServerRootPath.isPrefixOf(absolutePath)) {
//				int numSegment = webModuleServerRootPath.segmentCount();
//				int numSegmentFromPath = absolutePath.segmentCount();
//				if (numSegmentFromPath > numSegment) {
//					String nextSegment = absolutePath.segment(numSegment);
//					// check if the segment after the WebModuleServerRoot is
//					// WEB-INF (ignoring case)
//					if (nextSegment != null	&& !nextSegment.equalsIgnoreCase("WEB-INF")) {
//						IPath relativePath = absolutePath.removeFirstSegments(numSegment);
//						if (webProjectURL != null)
//							url.append(webProjectURL).append(IPath.SEPARATOR).append(relativePath.toString());
//					}
//				} else if (numSegmentFromPath == numSegment)
//					url.append(webProjectURL);
//			}
//		}
//		if (url.length() < 1) {
//			IWorkspaceRoot workspace = getWorkspaceRoot();
//			url.append(getResourceURI(workspace.getFile(absolutePath)));
//		}
//		ILog log = new EclipseLog();
//		log.log(ILog.INFO, 5038, ResourceUtils.class, "getURLFromPath",
//				"absolutePath=" + absolutePath + ",url=" + url);
//
//		return url.toString();
//	}

	/**
	 * Copies a set of files from a plugin's installation location to a native
	 * directory. The files are named in an index file located relative to the
	 * plugin's installation location.
	 * 
	 * @param plugin
	 *            The plugin containing the files to copy. Must not be null.
	 * @param sourcePath
	 *            The path, relative to the <code>plugin</code> install
	 *            location, containing the files to copy. If null, then the
	 *            plugin install location is the source path (ie. null is
	 *            equivalent to ".").
	 * @param indexPathname
	 *            A file containing a whitespace-delimitted list of pathnames of
	 *            the files to copy. The pathnames are relative to the
	 *            <code>plugin sourcePath</code>. Must not be null.
	 * @param targetPath
	 *            The absolute path of the native directory to which the files
	 *            will be copied. The relative pathnames of the files named in
	 *            the <code>indexPathname</code> file are preserved. Must not
	 *            be null.
	 * @param progressMonitor
	 *            The progress monitor for the operation, or null.
	 * @throws IOException
	 *             An exception indicating an IO error has occured.
	 */
	static public void copyIndexedFilesToOS(Plugin plugin, IPath sourcePath,
			IPath indexPathname, IPath targetPath,
			IProgressMonitor progressMonitor) throws IOException {
		InputStream input = plugin.openStream(indexPathname);
		Enumeration filenames = StringUtils.parseFilenamesFromStream(input);
		copyEnumeratedFilesToOS(plugin, sourcePath, filenames, targetPath,
				progressMonitor);
	}

	/**
	 * Copies a set of files from a plugin's installation location to a native
	 * directory. The files are named in an enumeration.
	 * 
	 * @param plugin
	 *            The plugin containing the files to copy. Must not be null.
	 * @param sourcePath
	 *            The path, relative to the <code>plugin</code> install
	 *            location, containing the files to copy. If null, then the
	 *            plugin install location is the source path (ie. null is
	 *            equivalent to ".").
	 * @param pathnames
	 *            An enumeration of pathnames of the files to copy. The
	 *            pathnames are relative to the <code>plugin sourcePath</code>.
	 *            Must not be null.
	 * @param targetPath
	 *            The absolute path of the native directory to which the files
	 *            will be copied. The relative pathnames of the files named in
	 *            the <code>pathnames</code> enumeration are preserved. Must
	 *            not be null.
	 * @param progressMonitor
	 *            The progress monitor for the operation, or null.
	 * @throws IOException
	 *             An exception indicating an IO error has occured.
	 */
	static public void copyEnumeratedFilesToOS(Plugin plugin, IPath sourcePath,
			Enumeration pathnames, IPath targetPath,
			IProgressMonitor progressMonitor) throws IOException {
		while (pathnames.hasMoreElements()) {
			String filename = (String) pathnames.nextElement();
			copyFileToOS(plugin, sourcePath, new Path(filename), targetPath,
					progressMonitor);
		}
	}

	/**
	 * Copies a file from a plugin's installation location to a native
	 * directory.
	 * 
	 * @param plugin
	 *            The plugin containing the files to copy. Must not be null.
	 * @param sourcePath
	 *            The path, relative to the <code>plugin</code> install
	 *            location, containing the files to copy. If null, then the
	 *            plugin install location is the source path (ie. null is
	 *            equivalent to ".").
	 * @param pathname
	 *            The pathname of the file to copy. The pathname is relative to
	 *            the <code>plugin sourcePath</code>. Must not be null.
	 * @param targetPath
	 *            The absolute path of the native directory to which the file
	 *            will be copied. The relative pathname of the file is
	 *            preserved. Must not be null.
	 * @param progressMonitor
	 *            The progress monitor for the operation, or null.
	 * @throws IOException
	 *             An exception indicating an IO error has occured.
	 */
	static public void copyFileToOS(Plugin plugin, IPath sourcePath,
			IPath pathname, IPath targetPath, IProgressMonitor progressMonitor)
			throws IOException {
		IPath target = targetPath.append(pathname);
		IPath source = sourcePath == null ? pathname : sourcePath
				.append(pathname);
		InputStream input = plugin.openStream(source);
		OutputStream output = new FileOutputStream(target.toOSString());
		copyStream(input, output);
		input.close();
		output.close();
	}

	/**
	 * Copies data from one stream to another.
	 * 
	 * @param input
	 *            The input stream.
	 * @param output
	 *            The output stream.
	 * @return The number of bytes copied.
	 * @throws IOException
	 *             An exception if an error occurs while processing either of
	 *             the streams.
	 */
	static public int copyStream(InputStream input, OutputStream output)
			throws IOException {
		int t = 0;
		byte[] buffer = new byte[1024];
		int n = input.read(buffer);
		while (n >= 0) {
			output.write(buffer, 0, n);
			t += n;
			n = input.read(buffer);
		}
		return t;
	}

	/**
	 * Creates a native directory path equal to the parent portion of the given
	 * <code>pathname</code>. If the directory already exists, then no action
	 * is taken.
	 * 
	 * @param pathname
	 *            The pathname to the file whose parent directory should be
	 *            created.
	 * @throws IOException
	 *             An exception if an IO error occurs.
	 */
	static public void createParentDirectoryFor(String pathname)
			throws IOException {
		File file = new File(pathname);
		File parent = file.getParentFile();
		if (parent != null) {
			parent.mkdirs();
		}
	}

	/**
	 * Returns the IResource represented by the given selection.
	 * 
	 * @param object
	 *            The selection
	 * @return IResource if the selection represents an IResource. Returns null
	 *         otherwise.
	 * @throws CoreException
	 */
	static public IResource getResourceFromSelection(Object obj)
			throws CoreException {
		IResource res = null;
		if (obj != null) {
			if (obj instanceof IResource) {
				res = (IResource) obj;
			} else if (obj instanceof IJavaElement) {
				IJavaElement javaElement = (IJavaElement) obj;
				res = javaElement.getCorrespondingResource();
			} else if (obj instanceof EnterpriseBean) {
				EnterpriseBean ejbBean = (EnterpriseBean) obj;
				IProject ejbProject = ProjectUtilities.getProject(ejbBean);
				if (ejbProject != null)
					res = ejbProject;
			} else if (obj instanceof SessionBean) {
				SessionBean JEE5Bean = (SessionBean) obj;
				IProject ejbProject = ProjectUtilities.getProject(JEE5Bean);
				if (ejbProject != null)
					res = ejbProject;
			}

		}

		return res;
	}

	//----------------------------------------------------------------------
	// Naughty bits...
	//----------------------------------------------------------------------

	//
	// Creates a path of folders.
	// Do not call with an absolutePath of less than one segment.
	//
	//  private static IContainer makeFolderPath (
	//        ResourceContext resourceContext,
	//    IPath absolutePath,
	//    IProgressMonitor progressMonitor,
	//    StatusMonitor statusMonitor
	//  )
	//  throws CoreException
	//  {
	//    if (absolutePath.segmentCount() <= 1)
	//    {
	//      return getWorkspaceRoot().getProject(absolutePath.segment(0));
	//    }
	//    else
	//    {
	//      IContainer parent = makeFolderPath(resourceContext,
	// absolutePath.removeLastSegments(1), progressMonitor, statusMonitor);
	//      String folderName = absolutePath.lastSegment();
	//      return makeFolder(resourceContext, parent,folderName, progressMonitor ,
	// statusMonitor);
	//    }
	//  }
	//
	// Creates a folder under a container.
	// The container must already exist.
	//
	// private static IFolder makeFolder (
	//        ResourceContext resourceContext,
	//    IContainer parent,
	//    String folderName,
	//    IProgressMonitor progressMonitor,
	//    StatusMonitor statusMonitor
	//  )
	//  throws CoreException
	//  {
	//    IResource child = parent.findMember(folderName);
	//    if (child == null)
	//    {
	//      if (!resourceContext.isCreateFoldersEnabled()) {
	//        int result = statusMonitor.reportStatus(new
	// Status(IStatus.WARNING,WebServicePlugin.ID,0,
	//                                                         WebServicePlugin.getMessage("%MSG_ERROR_FOLDER_CREATION_DISABLED",
	//                                                         new Object[] {parent.getFullPath().toString(),folderName}),null),
	// getThreeStateFileOptions());
	//        if (result == IStatusDialogConstants.CANCEL_ID)
	//                        return null;
	//
	//          if ( result == IStatusDialogConstants.YES_TO_ALL_ID)
	//                        resourceContext.setCreateFoldersEnabled(true);
	//
	//      }
	//      IFolder folder = parent.getFolder(new Path(folderName));
	//      folder.create(true,true,progressMonitor);
	//      return folder;
	//    }
	//    else if (child.getType() == IResource.FOLDER)
	//    {
	//      return (IFolder)child;
	//    }
	//    else
	//    {
	//      throw new CoreException(new
	// Status(IStatus.ERROR,WebServicePlugin.ID,0,WebServicePlugin.getMessage("%MSG_ERROR_RESOURCE_NOT_FOLDER",new
	// Object[] {parent.getFullPath().append(folderName).toString()}),null));
	//    }
	//  }

	//
	// Creates a file under a container.
	// The container must already exist.
	//
	// private static IFile makeFile (
	//    ResourceContext resourceContext,
	//    IContainer parent,
	//    String fileName,
	//    InputStream inputStream,
	//    IProgressMonitor progressMonitor,
	//    StatusMonitor statusMonitor
	//  )
	//  throws CoreException
	//  {
	//    IResource child = parent.findMember(fileName);
	//    if (child != null)
	//    {
	//      if (child.getType() == IResource.FILE)
	//      {
	//        if (!resourceContext.isOverwriteFilesEnabled()) {
	//          int result = statusMonitor.reportStatus( new
	// Status(IStatus.WARNING,WebServicePlugin.ID,0,
	//                                                         WebServicePlugin.getMessage("%MSG_ERROR_FILE_OVERWRITE_DISABLED",
	//                                                         new Object[] {parent.getFullPath().toString(),fileName}),null),
	// getThreeStateFileOptions());
	//
	//          if (result == IStatusDialogConstants.CANCEL_ID)
	//                        return null;
	//
	//          if ( result == IStatusDialogConstants.YES_TO_ALL_ID)
	//                        resourceContext.setOverwriteFilesEnabled(true);
	//        }
	//        //We have permission to overwrite so check if file is read-only
	//        if (child.isReadOnly())
	//        {
	//          if (!resourceContext.isCheckoutFilesEnabled()) {
	//
	//            int result = statusMonitor.reportStatus( new
	// Status(IStatus.WARNING,WebServicePlugin.ID,0,
	//                                                         WebServicePlugin.getMessage("%MSG_ERROR_FILE_CHECKOUT_DISABLED",
	//                                                         new Object[] {parent.getFullPath().toString(),fileName}),null),
	// getThreeStateFileOptions());
	//
	//            if (result == IStatusDialogConstants.CANCEL_ID)
	//                        return null;
	//
	//            if ( result == IStatusDialogConstants.YES_TO_ALL_ID)
	//                        resourceContext.setCheckoutFilesEnabled(true);
	//          }
	//
	//          IFile[] files = new IFile[1];
	//          files[0] = (IFile)child;
	//
	//          if (
	// !statusMonitor.reportStatus(getWorkspace().validateEdit(files,null)))
	//                                return null;
	//        }
	//
	//        //Change the contents of the existing file.
	//            IFile file = parent.getFile(new Path(fileName));
	//        file.setContents(inputStream,true,true,progressMonitor);
	//        return file;
	//
	//      }
	//      else
	//      {
	//        throw new CoreException(new
	// Status(IStatus.ERROR,WebServicePlugin.ID,0,WebServicePlugin.getMessage("%MSG_ERROR_RESOURCE_NOT_FILE",new
	// Object[] {parent.getFullPath().append(fileName)}),null));
	//      }
	//    }
	//    else
	//    {
	//        //Create a new file.
	//        IFile file = parent.getFile(new Path(fileName));
	//        file.create(inputStream,true,progressMonitor);
	//        return file;
	//    }
	//  }

	/**
	 * Deletes a file under a container. The container must already exist.
	 * 
	 * @param file -
	 *            the IFile to be deleted
	 * @param progressMonitor
	 * @param statusMonitor
	 * @return True if the file does not exist or if it exists and is
	 *         successfully deleted. False otherwise.
	 */
	//  public static boolean deleteFile (
	//        ResourceContext resourceContext,
	//    IFile file,
	//    IProgressMonitor progressMonitor,
	//    StatusMonitor statusMonitor )
	//    throws CoreException
	//    {
	//        if (file.exists())
	//        {
	//                if (!resourceContext.isOverwriteFilesEnabled()) {
	//                        int result = statusMonitor.reportStatus( new
	// Status(IStatus.WARNING,WebServicePlugin.ID,0,
	//                                                                 WebServicePlugin.getMessage("%MSG_ERROR_FILE_OVERWRITE_DISABLED",
	//                                                                 new Object[]
	// {file.getParent().getFullPath().toString(),file.getName()}),null),
	// getThreeStateFileOptions());
	//
	//                            if (result == IStatusDialogConstants.CANCEL_ID)
	//                        return false;
	//
	//                if ( result == IStatusDialogConstants.YES_TO_ALL_ID)
	//                                resourceContext.setOverwriteFilesEnabled(true);
	//                        }
	//                //We have permission to overwrite so check if file is read-only
	//                if (file.isReadOnly())
	//                {
	//                        if (!resourceContext.isCheckoutFilesEnabled()) {
	//                                        int result = statusMonitor.reportStatus( new
	// Status(IStatus.WARNING,WebServicePlugin.ID,0,
	//                                                                 WebServicePlugin.getMessage("%MSG_ERROR_FILE_CHECKOUT_DISABLED",
	//                                                                 new Object[]
	// {file.getParent().getFullPath().toString(),file.getName()}),null),
	// getThreeStateFileOptions());
	//                        if (result == IStatusDialogConstants.CANCEL_ID)
	//                        return false;
	//
	//                        if ( result == IStatusDialogConstants.YES_TO_ALL_ID)
	//                                resourceContext.setCheckoutFilesEnabled(true);
	//
	//                                }
	//                        IFile[] files = new IFile[1];
	//                        files[0] = file;
	//
	//                        if (
	// !statusMonitor.reportStatus(getWorkspace().validateEdit(files,null)))
	//                                            return false;
	//                }
	//                file.delete(true,progressMonitor);
	//                }
	//        //At this point, either the file did not exist or we successfully deleted
	// it. Return success.
	//        return true;
	//  }
	/**
	 * Deletes a folder under a container.
	 * 
	 * @param folder -
	 *            the IFolder to be deleted
	 * @param progressMonitor
	 * @param statusMonitor
	 * @return True if the folder does not exist or if it exists and is
	 *         successfully deleted along with its members. False otherwise.
	 */
	//  public static boolean deleteFolder (
	//    ResourceContext resourceContext,
	//    IFolder folder,
	//    IProgressMonitor progressMonitor,
	//    StatusMonitor statusMonitor
	//  )
	//  throws CoreException
	//  {
	//    if (!folder.exists()) return true;
	//
	//    boolean deleted = true;
	//    IResource[] resources = folder.members();
	//    for (int i=0; i<resources.length; i++)
	//    {
	//      IResource resource = resources[i];
	//      if (resource instanceof IFile)
	//      {
	//        deleted = deleteFile(resourceContext, (IFile)resource, progressMonitor,
	// statusMonitor);
	//      }
	//      if (resource instanceof IFolder)
	//      {
	//        deleted = deleteFolder( resourceContext, (IFolder)resource,
	// progressMonitor, statusMonitor);
	//      }
	//
	//      if (!deleted) break;
	//    }
	//    if (deleted) {
	//      folder.delete(true, true, progressMonitor);
	//      return true;
	//    }
	//    else
	//      return false;
	//
	//  }
	/**
	 * Deletes a set of files that are named in an index file located relative
	 * to the plugin's installation location.
	 * 
	 * @param plugin
	 *            The plugin containing the indexed file Must not be null.
	 * @param sourcePath -
	 *            relative path of the indexed file passing a null in has the
	 *            same effect as passing a "." in
	 * @param indexFilePath -
	 *            the indexed filename Must not be null
	 * @param targetPath -
	 *            path containing the files named in the indexed file Must not
	 *            be null, this path must end with a trailing separator
	 * @param progressMonitor
	 */
	//  public static void deleteIndexFilesFromOS (
	//    Plugin plugin,
	//    IPath indexFilePath,
	//    IPath targetPath
	//  )
	//  throws IOException {
	//    InputStream input = plugin.openStream(indexFilePath);
	//    Enumeration filenames = StringUtils.parseFilenamesFromStream(input);
	//    while (filenames.hasMoreElements()) {
	//      File targetFile =
	// targetPath.append((String)filenames.nextElement()).toFile();
	//      if (targetFile.exists())
	//        targetFile.delete();
	//    }
	//  }
	/**
	 * Returns a URI reference to the given Eclipse resource, or null if no such
	 * reference can be determined (for example, if the resource does not exist
	 * in the underlying filesystem).
	 * 
	 * @param resource
	 *            The resource.
	 * @return The URI as a string, or null if there is no URI to the resource.
	 */
	public static String getResourceURI(IResource resource) {
		String uri = null;
		IPath location = resource.getLocation();
		if (location != null) {
			uri = "file:" + location.toString();
		}
		return uri;
	}

	/**
	 * Returns a URI reference to the given Eclipse resource using the
	 * "platform:" protocol, or null if no such reference can be determined (for
	 * example, if the resource does not exist in the underlying filesystem).
	 * 
	 * @param resource
	 *            The resource.
	 * @return The URI as a string, or null if there is no URI to the resource.
	 */
	public static String getPlatformResourceURI(IResource resource) {
		String uri = null;
		IPath location = resource.getFullPath();
		if (location != null) {
			uri = "platform:/resource" + location.toString();
		}
		return uri;
	}

	/**
	 * Returns the default binding namespace string given a Java bean name
	 * (using the convention used by CTC in GM). e.g. Java bean MyClass result
	 * in binding namespace of
	 * "http://www.myclass.com/definitions/MyClassRemoteInterface"
	 * 
	 * @param beanName
	 *            The java bean.
	 * @return The binding namespace as a string.
	 */
	public static String getBindingNamespace(String beanName) {
		return "http://www." + beanName.toLowerCase() + ".com/definitions/"
				+ beanName + "RemoteInterface";
	}

	/**
	 * Returns the default schema namespace string given a Java bean name (using
	 * the convention used by CTC in GM). e.g. Java bean MyClass result in
	 * schema namespace of
	 * "http://www.myclass.com/schemas/MyClassRemoteInterface"
	 * 
	 * @param beanName
	 *            The java bean.
	 * @return The schemas namespace as a string.
	 */
	public static String getSchemaNamespace(String beanName) {
		return "http://www." + beanName.toLowerCase() + ".com/schemas/"
				+ beanName + "RemoteInterface";
	}

	//  public static Vector getThreeStateFileOptions() {
	//        Vector options = new Vector();
	//    options.add(new
	// StatusOption(IStatusDialogConstants.YES_ID,IStatusDialogConstants.YES_LABEL,"",""));
	//    options.add(new
	// StatusOption(IStatusDialogConstants.YES_TO_ALL_ID,IStatusDialogConstants.YES_TO_ALL_LABEL,"",""));
	//    options.add(new
	// StatusOption(IStatusDialogConstants.CANCEL_ID,IStatusDialogConstants.CANCEL_LABEL,"",""));
	//    return options;
	//  }

	//----------------------------------------------------------------------

	/**
	 * Gets the SOAP rpcrouter servlet URL for the service project
	 * 
	 * @param project
	 *            The project.
	 * @param serverFactoryId
	 *            The server factory id
	 * @param server
	 *            The server
	 * @return The URL, possibly null.
	 */

	public static String getServletURL(IProject project,
			String serverFactoryId, IServer server) {
		return getServletURL(getWebProjectURL(project, serverFactoryId, server));
	}

	public static String getServletURL(String webProjectURL) {
		if (webProjectURL == null)
			return null;
		else
			return webProjectURL + SERVLET_EXT;
	}

	/**
	 * Gets the client Web project name
	 * 
	 * @param projectName
	 *            The project name to base on.
	 * @param typeId the webservice type id.
	 * @return The client Web project name.
	 * 
	 * @deprecated
	 */
	public static String getClientWebProjectName(String projectName, String typeId) 
	{
		String   baseClientWebProjectName = projectName + DEFAULT_CLIENT_WEB_PROJECT_EXT;
		IPath    projectPath;
		IProject project;
		boolean  foundWebProject     = false;
		int      i                   = 1;
		
		if( isSkeletonEJBType( typeId ) )
		{
		  // For the skeleton EJB scenario we need to create a slightly different
		  // base name.  When the EJB project is created another project
		  // is created with "Client" tacked onto the end.  We will
		  // add "WS" to our client so we don't collide with the other
		  // client project.
		  baseClientWebProjectName = projectName + "WS" + DEFAULT_CLIENT_WEB_PROJECT_EXT;    
		}
		
		String  clientWebProjectName = baseClientWebProjectName;
		
		while (!foundWebProject) 
		{
		  projectPath = new Path(clientWebProjectName).makeAbsolute();
		  project = ResourceUtils.getProjectOf(projectPath);
		  
		  if (project.exists() && !ResourceUtils.isWebProject(project)) 
		  {
			clientWebProjectName = baseClientWebProjectName + i;
			i++;
		  }
		  else 
		  {
			foundWebProject = true;
		  }
		}
		
		return clientWebProjectName;
	}

  public static String[] getClientProjectComponentName(String projectName, String componentName, boolean isEJB)
  {
    String clientProjectName = null;
    String clientComponentName = null;
    if (isEJB)
    {
      clientProjectName = projectName + DEFAULT_CLIENT_EJB_PROJECT_EXT;
      clientComponentName = componentName + DEFAULT_CLIENT_EJB_PROJECT_EXT;
    }
    else
    {
      clientProjectName = projectName + DEFAULT_CLIENT_WEB_PROJECT_EXT;
//      String baseName = clientProjectName;
      clientComponentName = componentName + DEFAULT_CLIENT_WEB_PROJECT_EXT;
//      String baseCompName = clientComponentName;
    }
    
    //TODO we may want to remove this if statement once defect 103366 is resolved.
    //TODO:  Defect 107997 - Revisit prject and module creation logic
//    if( !FlexibleJavaProjectPreferenceUtil.getMultipleModulesPerProjectProp() )
//    {
//      clientComponentName = clientProjectName;	
//    }
    
//    boolean  foundWebProject     = false;
//    int      i                   = 1;
//    
//    while (!foundWebProject) 
//    {
//      IPath projectPath = new Path(clientProjectName).makeAbsolute();
//      IProject project = ResourceUtils.getProjectOf(projectPath);
//      
//      if (project.exists()) 
//      {
//        clientProjectName = baseName + i;
//        clientComponentName = baseCompName + i;
//        i++;
//      }
//      else 
//      {
//        foundWebProject = true;
//      }
//    }
    
    return new String[]{clientProjectName, clientComponentName};
  }
  
    /**
     * 
     * @param typeID
     * @return
     * 
     * @deprecated
     */
	public static boolean isSkeletonEJBType( String typeID )
	{
	  return typeID.equals( "org.eclipse.jst.ws.type.wsdl.ejb" );    
	}
	
	public static String getDefaultEJBProjectName() {
		return DEFAULT_EJB_PROJECT_NAME;
	}
  
  public static String getDefaultEJBComponentName() {
    return DEFAULT_EJB_COMPONENT_NAME;
  }  

	public static String getDefaultWebProjectName() {
		return DEFAULT_WEB_PROJECT_NAME;
	}
  
  public static String getDefaultWebComponentName() {
    return DEFAULT_WEB_COMPONENT_NAME;
  }

  public static String getDefaultClientExtension() {
    return DEFAULT_CLIENT_WEB_PROJECT_EXT;
  }
  
	/**
	 * 
	 * @param projectName
	 * @return
	 * 
	 */
	public static String getRouterProjectName(String projectName) {
		return projectName + DEFAULT_ROUTER_PROJECT_EXT;
	}

	public static String getDefaultServiceEARProjectName() {
		return DEFAULT_SERVICE_EAR_PROJECT_NAME;
	}
  
  public static String getDefaultServiceEARComponentName() {
    return DEFAULT_SERVICE_EAR_COMPONENT_NAME;
  }

	public static String getDefaultClientEARProjectName() {
		return DEFAULT_CLIENT_EAR_PROJECT_NAME;
	}

  public static String getDefaultClientEARComponentName() {
    return DEFAULT_CLIENT_EAR_COMPONENT_NAME;
  }
  
  public static String getDefaultEARExtension() {
	    return DEFAULT_EAR_EXT;
	  }
}

