/*******************************************************************************
 * Copyright (c) 2003, 2010 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.ws.internal.consumption.ui.helper;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.client.ApplicationClient;
import org.eclipse.jst.j2ee.client.ApplicationClientResource;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EJBResource;
import org.eclipse.jst.j2ee.ejb.EnterpriseBean;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.common.XMLResource;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.internal.webservice.componentcore.util.WSCDDArtifactEdit;
import org.eclipse.jst.j2ee.internal.webservice.componentcore.util.WSDDArtifactEdit;
import org.eclipse.jst.j2ee.internal.webservices.WSDLServiceExtManager;
import org.eclipse.jst.j2ee.internal.webservices.WSDLServiceHelper;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.j2ee.webapplication.WebAppResource;
import org.eclipse.jst.j2ee.webservice.wsclient.ComponentScopedRefs;
import org.eclipse.jst.j2ee.webservice.wsclient.ServiceRef;
import org.eclipse.jst.j2ee.webservice.wsclient.WebServicesClient;
import org.eclipse.jst.j2ee.webservice.wsclient.WebServicesResource;
import org.eclipse.jst.j2ee.webservice.wsdd.PortComponent;
import org.eclipse.jst.j2ee.webservice.wsdd.ServiceImplBean;
import org.eclipse.jst.j2ee.webservice.wsdd.WebServiceDescription;
import org.eclipse.jst.j2ee.webservice.wsdd.WebServices;
import org.eclipse.jst.j2ee.webservice.wsdd.WsddResource;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.wst.common.componentcore.ArtifactEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.ArtifactEditModel;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModelEvent;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModelListener;

/**
 * Internal API class
 * 
 * This utility class is meant to aid in managing webservice(jsr109) metadata related to Java EE 1.4 or earlier
 * 
 * Marking as @frozen to support <= Java EE 1.4
 * 
 */
public class WebServicesManager implements EditModelListener, IResourceChangeListener, IResourceDeltaVisitor {

	private HashMap wsArtifactEdits = new HashMap();
	private HashMap wsClientArtifactEdits = new HashMap();
	private List wsArtifactEditsList;
	private List wsClientArtifactEditsList;
	private static WebServicesManager INSTANCE = null;
	private List listeners;
	private List removedListeners = new ArrayList();
	private boolean isNotifying = false;
	private boolean wsClientElementsChanged = true;
	private boolean wsElementsChanged = true;
	private ProcessProjectsWithWSDL processNewProjects;

	public static final String WSDL_EXT = "wsdl"; //$NON-NLS-1$
	public static final String WSIL_EXT = "wsil"; //$NON-NLS-1$

	public synchronized static WebServicesManager getInstance() {
		if (INSTANCE == null)
			INSTANCE = new WebServicesManager();
		return INSTANCE;
	}

	public static  boolean isFileInteresting(IFile aFile) {
		if (aFile != null && aFile.getFileExtension() != null) {
			String extension = aFile.getFileExtension();
			return extension.equals(WSDL_EXT) || extension.equals(WSIL_EXT) 
			|| aFile.getName().equals(J2EEConstants.WEB_SERVICES_CLIENT_SHORTNAME) 
			|| aFile.getName().equals(J2EEConstants.WEB_SERVICES_DD_URI);
		}
		return false;
	}
	/**
	 * Default Constructor
	 */
	public WebServicesManager() {
		super();
		init();
	}

	private void init() {
		collectArtifactEdits();
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
	}
	
	private void addArtifactEdit(IProject handle) {
		synchronized(wsArtifactEdits) {
			if (!wsArtifactEdits.containsKey(handle)) {
				WSDDArtifactEdit edit = WSDDArtifactEdit.getWSDDArtifactEditForRead(handle);
				if (edit != null) {
					WebServices webServices = edit.getWebServices();
					// If the project has a webservice.xml with internal services or 
					// it has .wsil files with external services, we cache the artifact edit
					if ((webServices != null && !webServices.getWebServiceDescriptions().isEmpty()) || !edit.getWSILResources().isEmpty()) {
						edit.addListener(this);
						wsArtifactEdits.put(handle, edit);
						wsElementsChanged = true;
					// Otherwise, dispose the artifact edit
					} else {
						edit.dispose();
					}
				}
			}
		}
		synchronized (wsClientArtifactEdits) {
			if (!wsClientArtifactEdits.containsKey(handle)) {
				WSCDDArtifactEdit edit = WSCDDArtifactEdit.getWSCDDArtifactEditForRead(handle);
				if (edit != null) {
					WebServicesResource res = edit.getWscddXmiResource();
					boolean isInterested = false;
					// Does the project have 1.3 web service clients?
					if (res != null && res.isLoaded() && res.getWebServicesClient() != null)
						isInterested = true;
					
					// Does the project have 1.4 web service clients?
					List wsClientEdits = new ArrayList();
					wsClientEdits.add(edit);
					//if (!getWorkspace14ServiceRefs(wsClientEdits).isEmpty())
						isInterested = true;
					
					// If project has 1.3 or 1.4 web service clients, cache the artifact edit
					if (isInterested) {
						edit.addListener(this);
						wsClientArtifactEdits.put(handle, edit);
						wsClientElementsChanged = true;
					// Otherwise, dispose the artifact edit	
					} else {
						edit.dispose();
					}
				}
			}
		}
	}
	
	private void removeArtifactEdit(IProject handle) {
		synchronized(wsArtifactEdits) {
			if (wsArtifactEdits.containsKey(handle)) {
				ArtifactEdit edit = (ArtifactEdit) wsArtifactEdits.get(handle);
				if (edit != null) {
					wsArtifactEdits.remove(handle);
					edit.removeListener(this);
					edit.dispose();
					wsElementsChanged = true;
				}
			}
		}
		synchronized (wsClientArtifactEdits) {
			if (wsClientArtifactEdits.containsKey(handle)) {
				ArtifactEdit edit = (ArtifactEdit) wsClientArtifactEdits.get(handle);
				if (edit != null) {
					wsClientArtifactEdits.remove(handle);
					edit.removeListener(this);
					edit.dispose();
					wsClientElementsChanged = true;
				}
			}
		}
	}

	private void collectArtifactEdits() {
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		for (int i = 0; i < projects.length; i++) {
			IProject project = projects[i];
			IVirtualComponent component = ComponentCore.createComponent(project);
			try {
				if (!ModuleCoreNature.isFlexibleProject(project) || JavaEEProjectUtilities.isEARProject(project) || JavaEEProjectUtilities.isStaticWebProject(project))
					continue;
			} catch (Exception e) {
				continue;
			}
			addArtifactEdit(component.getProject());
		}
	}

	/**
	 * @return Returns the artifact edit iterator for web service artifact edits
	 */
	private List getWSArtifactEdits() {
		synchronized (wsArtifactEdits) {
			if (wsElementsChanged) {
				wsArtifactEditsList = new ArrayList();
				wsArtifactEditsList.addAll(wsArtifactEdits.values());
				wsElementsChanged = false;
			}
		}
		return wsArtifactEditsList;
	}
	
	/**
	 * @return Returns the editModels.
	 */
	private List getWSClientArtifactEdits() {
		synchronized (wsClientArtifactEdits) {
			if (wsClientElementsChanged) {
				wsClientArtifactEditsList = new ArrayList();
				wsClientArtifactEditsList.addAll(wsClientArtifactEdits.values());
				wsClientElementsChanged = false;
			}
		}
		return wsClientArtifactEditsList;
	}

	private List getListeners() {
		if (listeners == null)
			listeners = new ArrayList();
		return listeners;
	}

	/**
	 * Add aListener to the list of listeners.
	 */
	public void addListener(WebServiceManagerListener aListener) {
		if (aListener != null && !getListeners().contains(aListener))
			getListeners().add(aListener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.internal.emfworkbench.integration.EditModelListener#editModelChanged(org.eclipse.wst.common.internal.emfworkbench.integration.EditModelEvent)
	 */
	public void editModelChanged(EditModelEvent anEvent) {
		if (anEvent == null)
			return;
		if (anEvent.getEventCode()==EditModelEvent.UNLOADED_RESOURCE) {
			List resources = anEvent.getChangedResources();
			for (int i=0; i<resources.size(); i++) {
				Resource res = (Resource) resources.get(i);
				if (isInterestedInResource(res))
					notifyListeners(anEvent.getEventCode());
			}
		}
		else if (anEvent.getEventCode() == EditModelEvent.PRE_DISPOSE) {
			ArtifactEditModel editModel = (ArtifactEditModel) anEvent.getEditModel();
			if (editModel == null || editModel.getProject() == null)
				return;
			removeArtifactEdit(editModel.getProject());
			notifyListeners(anEvent.getEventCode());
		}
	}


	/**
	 * Notify listeners of
	 * 
	 * @anEvent.
	 */
	protected void notifyListeners(int anEventType) {
		if (listeners == null)
			return;
		synchronized (this) {
			isNotifying = true;
		}
		try {
			WebServiceEvent webServiceEvent = null;
			
			switch (anEventType) {
			case EditModelEvent.UNLOADED_RESOURCE:
			case EditModelEvent.PRE_DISPOSE:
			case EditModelEvent.REMOVED_RESOURCE:
				webServiceEvent = new WebServiceEvent(WebServiceEvent.REMOVE);
				break;
			default:
				if (!getAllWorkspaceServiceRefs().isEmpty() || !getAllWSDLServices().isEmpty())
					webServiceEvent = new WebServiceEvent(WebServiceEvent.REFRESH);
			}
			List list = getListeners();
			if (webServiceEvent!=null) {
				for (int i = 0; i < list.size(); i++) {
					((WebServiceManagerListener) list.get(i)).webServiceManagerChanged(webServiceEvent);
				}
			}
		} finally {
			synchronized (this) {
				isNotifying = false;
				if (removedListeners != null && !removedListeners.isEmpty()) {
					for (int i = 0; i < removedListeners.size(); i++)
						listeners.remove(removedListeners.get(i));
					removedListeners.clear();
				}
			}
		}
	}

	/**
	 * Remove aListener from the list of listeners.
	 */
	public synchronized boolean removeListener(WebServiceManagerListener aListener) {
		if (aListener != null) {
			if (isNotifying)
				return removedListeners.add(aListener);
			return getListeners().remove(aListener);
		}
		return false;
	}

	private void releaseArtifactEdits() {
		synchronized (wsArtifactEdits) {
			Iterator iter = wsArtifactEdits.values().iterator();
			while (iter.hasNext()) {
				WSDDArtifactEdit artifactEdit = (WSDDArtifactEdit) iter.next();
				artifactEdit.removeListener(this);
				artifactEdit.dispose();
			}
			wsArtifactEdits.clear();
		}
		
		synchronized (wsClientArtifactEdits) {
			Iterator iter = wsClientArtifactEdits.values().iterator();
			while (iter.hasNext()) {
				WSCDDArtifactEdit artifactEdit = (WSCDDArtifactEdit) iter.next();
				artifactEdit.removeListener(this);
				artifactEdit.dispose();
			}
			wsClientArtifactEdits.clear();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		acceptDelta(event);
	}


	protected void acceptDelta(IResourceChangeEvent event) {
		IResourceDelta delta = event.getDelta();
		// search for changes to any projects using a visitor
		if (delta != null) {
			try {
				delta.accept(this);
				
			} catch (Exception e) {
				Logger.getLogger().logError(e);
			}
		}
	}

	/**
	 * returns a list of internal web services descriptions in the workspace
	 */
	public List getInternalWebServicesDescriptions() {
		List result = new ArrayList();
		List webServices = getInternalWebServices();
		for (int i = 0; i < webServices.size(); i++) {
			WebServices webService = (WebServices) webServices.get(i);
			if (webService != null)
				result.addAll(webService.getWebServiceDescriptions());
		}
		return result;
	}

	/**
	 * @return all internal web services instances in workspace
	 */
	public List getInternalWebServices() {
		List result = new ArrayList();
		Iterator iter = getWSArtifactEdits().iterator();
		while (iter.hasNext()) {
			WSDDArtifactEdit artifactEdit = (WSDDArtifactEdit) iter.next();
			WebServices webServices = artifactEdit.getWebServices();
			if (webServices != null)
				result.add(webServices);
		}
		return result;
	}

	/**
	 * returns a list of all the internal wsdl services in wsdl's pointed to by wsdd's
	 */
	public List getInternalWSDLServices() {
		return getWSDLServicesFromWSDLResources(getInternalWSDLResources());
	}

	public List getInternalWSDLResources() {
		List result = new ArrayList();
		List wsddWebServices = getInternalWebServicesDescriptions();
		for (int i = 0; i < wsddWebServices.size(); i++) {
			WebServiceDescription webServices = (WebServiceDescription) wsddWebServices.get(i);
			Resource wsdl = getWSDLResource(webServices);
			if (wsdl != null && !result.contains(wsdl))
				result.add(wsdl);
		}
		return result;
	}

		public List getExternalWSDLResources() {
			//TODO fix up for basis off .wsil
			List result = getWorkspaceWSDLResources();
			result.removeAll(getInternalWSDLResources());
			List serviceRefs = getAllWorkspaceServiceRefs();
			for (int i=0; i<serviceRefs.size(); i++) {
				ServiceRef ref = (ServiceRef) serviceRefs.get(i);
				try {
					Resource res = WorkbenchResourceHelperBase.getResource(URI.createURI(ref.getWsdlFile()), true);
					if (res !=null && result.contains(res))
						result.remove(res);
				} catch (Exception e) {
					//Ignore
				}
			}
			return result;
		}
		
	public boolean isServiceInternal(EObject service) {
		return getInternalWSDLResources().contains(getWSDLResource(service));
	}

	private List getWSDLServicesFromWSDLResources(List wsdlResources) {
		List result = new ArrayList();
		for (int i = 0; i < wsdlResources.size(); i++) {
			Resource wsdl = (Resource) wsdlResources.get(i);
			List services = getWSDLServices(wsdl);
			if (wsdl != null && services != null && !services.isEmpty())
				result.addAll(services);
		}
		return result;
	}

	public List getExternalWSDLServices() {
		List result = getWsdlServicesFromWorkspaceWSILs();
		result.removeAll(getInternalWSDLServices());
		return result;
	}

	public List getWsdlServicesFromWorkspaceWSILs() {
		List result = new ArrayList();
		List wsilFiles = getWorkspaceWSILFiles();
		for (int i = 0; i < wsilFiles.size(); i++) {
			IFile wsil = (IFile) wsilFiles.get(i);
			List services = getWsdlServicesFromWsilFile(wsil);
			if (!services.isEmpty())
				result.addAll(services);
		}
	return result;
	}

	public List getWsdlServicesFromWsilFile(IFile wsil) {
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		return serviceHelper.getWsdlServicesFromWsilFile(wsil);
	}

	/**
	 * Returns all WSDL Services, both internal and external
	 */
	public List getAllWSDLServices() {
		List result = new ArrayList();
		result.addAll(getInternalWSDLServices());
		result.addAll(getExternalWSDLServices());
		return result;
	}

	protected void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		releaseArtifactEdits();
		INSTANCE = null;
	}

	public Resource getWSDLResource(WebServiceDescription webService) {
		if (webService == null)
			return null;
		String wsdlFileName = webService.getWsdlFile();
		Resource res = null;
		IVirtualResource[] resources = ComponentCore.createResources(WorkbenchResourceHelper.getFile(webService));
		if (resources == null || resources.length==0) return res;
		WSDDArtifactEdit artifactEdit = getExistingWSDDArtifactEdit(resources[0].getComponent().getProject());
		if (artifactEdit!=null) 
			res = artifactEdit.getWsdlResource(wsdlFileName);
		return res;
	}
	
	private WSDDArtifactEdit getExistingWSDDArtifactEdit(IProject project) {
		List wsEdits = getWSArtifactEdits();
		for (int i=0; i<wsEdits.size(); i++) {
			WSDDArtifactEdit edit = (WSDDArtifactEdit) wsEdits.get(i);
			if (edit !=null && edit.getProject()!= null && edit.getProject().equals(project))
				return edit;
		}
		return null;
	}
	
	private WSCDDArtifactEdit getExistingWSCDDArtifactEdit(IProject project) {
		List wsClientEdits = getWSClientArtifactEdits();
		for (int i=0; i<wsClientEdits.size(); i++) {
			WSCDDArtifactEdit edit = (WSCDDArtifactEdit) wsClientEdits.get(i);
			if (edit !=null && edit.getProject()!= null && edit.getProject().equals(project))
				return edit;
		}
		return null;
	}

	public List getWSDLServices(Resource wsdl) {
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		List result = new ArrayList();
		Object def = serviceHelper.getWSDLDefinition(wsdl);
		if (def == null)
			return result;
		result = new ArrayList(serviceHelper.getDefinitionServices(def).values());
		return result;
	}

	public EObject getWSDLServiceForWebService(WebServiceDescription webService) {
		EObject service = null;
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		Resource wsdl = getWSDLResource(webService);
		if (wsdl == null) return service;
		Object definition = serviceHelper.getWSDLDefinition(wsdl);
		if (definition == null) return service;
		Map services = serviceHelper.getDefinitionServices(definition);
		if (services.isEmpty()) return service;
		PortComponent portComp = null;
		if (webService.getPortComponents()!=null && webService.getPortComponents().size()>0) {
			portComp = (PortComponent) webService.getPortComponents().get(0);
			return getService(portComp);
		}
		return service;
	}

	public Resource getWSDLResource(EObject wsdlService) {
		return wsdlService.eResource();
	}

	public EObject getService(PortComponent port) {
		List services = getInternalWSDLServices();
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		for (int i = 0; i < services.size(); i++) {
			EObject service = (EObject)services.get(i);
			if (serviceHelper.getServicePorts(service).size() == 1) {
				Object wsdlPort = serviceHelper.getServicePorts(service).values().toArray()[0];
				String qName = serviceHelper.getPortBindingNamespaceURI(wsdlPort);
				if (port.getWsdlPort().getNamespaceURI().equals(qName))
					return service;
			}
		}
		return null;
	}

	public PortComponent getPortComponent(String qName) {
		List wsDescs = getInternalWebServicesDescriptions();
		for (int i = 0; i < wsDescs.size(); i++) {
			WebServiceDescription wsDesc = (WebServiceDescription) wsDescs.get(i);
			List ports = wsDesc.getPortComponents();
			for (int j = 0; j < ports.size(); j++) {
				PortComponent portComp = (PortComponent) ports.get(j);
				if (portComp.getWsdlPort().getNamespaceURI().equals(qName))
					return portComp;
			}
		}
		return null;
	}

	public PortComponent getPortComponent(String qName, IProject project) {
		List wsDescs = getInternalWebServicesDescriptions();
		for (int i = 0; i < wsDescs.size(); i++) {
			WebServiceDescription wsDesc = (WebServiceDescription) wsDescs.get(i);
			List ports = wsDesc.getPortComponents();
			for (int j = 0; j < ports.size(); j++) {
				PortComponent portComp = (PortComponent) ports.get(j);
				if (project == ProjectUtilities.getProject(portComp))
					return portComp;
			}
		}
		return null;
	}

	public PortComponent getPortComponent(EObject wsdlService) {
		// If there is only one port in the wsdl service, find the matching port component
		// otherwise if multiple ports return null because we need more information
		WSDLServiceHelper serviceHelper = WSDLServiceExtManager.getServiceHelper();
		if (wsdlService == null || serviceHelper.getServicePorts(wsdlService).isEmpty())
			return null;
		if (serviceHelper.getServicePorts(wsdlService).size() > 0) {
			Object port = serviceHelper.getServicePorts(wsdlService).values().toArray()[0];
			String qName = serviceHelper.getPortBindingNamespaceURI(port);
			return getPortComponent(qName, ProjectUtilities.getProject(wsdlService));
		}
		return null;
	}

	public ServiceImplBean getServiceImplBean(EObject wsdlService) {
		PortComponent port = getPortComponent(wsdlService);
		if (port == null)
			return null;
		return port.getServiceImplBean();
	}

	public WsddResource getWsddResource(EObject wsdlService) {
		PortComponent port = getPortComponent(wsdlService);
		if (port == null)
			return null;
		return (WsddResource) port.eResource();
	}

	public String getServiceEndpointInterface(EObject wsdlService) {
		PortComponent port = getPortComponent(wsdlService);
		if (port == null)
			return null;
		return port.getServiceEndpointInterface();
	}

	public List getAllWorkspaceServiceRefs() {
		List result = new ArrayList();
		result.addAll(getWorkspace13ServiceRefs());
		result.addAll(getWorkspace14ServiceRefs());
		return result;
	}

	public List getWorkspace13ServiceRefs() {
		List result = new ArrayList();
		Iterator iter = getWSClientArtifactEdits().iterator();
		while (iter.hasNext()) {
			WSCDDArtifactEdit artifactEdit = (WSCDDArtifactEdit) iter.next();
			WebServicesResource res = artifactEdit.getWscddXmiResource();
			if (res != null && res.isLoaded() && res.getWebServicesClient() != null) {
				if (JavaEEProjectUtilities.isEJBProject(artifactEdit.getProject())) {
					List scopedBeans = res.getWebServicesClient().getComponentScopedRefs();
					for (Iterator iterator = scopedBeans.iterator(); iterator.hasNext();) {
						ComponentScopedRefs refBean = (ComponentScopedRefs) iterator.next();
						result.addAll(refBean.getServiceRefs());
					}
				} else	result.addAll(res.getWebServicesClient().getServiceRefs());
			}
		}
		return result;
	}

	public List get13ServiceRefs(IProject handle) {
		List result = new ArrayList();
		WSCDDArtifactEdit wsClientArtifactEdit = getExistingWSCDDArtifactEdit(handle);
		if (wsClientArtifactEdit !=null) {
			WebServicesResource res = wsClientArtifactEdit.getWscddXmiResource();
			if (res != null && res.isLoaded() && res.getWebServicesClient() != null)
				result.addAll(res.getWebServicesClient().getServiceRefs());
		}
		return result;
	}

	public List getWorkspace14ServiceRefs() {
		return getWorkspace14ServiceRefs(getWSClientArtifactEdits());
	}
	
	private List getWorkspace14ServiceRefs(List wsClientArtifactEdits) {
		Iterator iter = wsClientArtifactEdits.iterator();
		List result = new ArrayList();
		while (iter.hasNext()) {
			WSCDDArtifactEdit wscArtifactEdit = (WSCDDArtifactEdit) iter.next();
			
			IProject project = wscArtifactEdit.getProject(); 	
			
			String projectType = J2EEProjectUtilities.getJ2EEProjectType(project);
			String projectVersion = J2EEProjectUtilities.getJ2EEProjectVersion(project);
			int    j2eeLevel =  0;
			if(IModuleConstants.JST_EJB_MODULE.equals(projectType)){
				j2eeLevel = J2EEVersionUtil.convertEJBVersionStringToJ2EEVersionID(projectVersion);
			} else if(IModuleConstants.JST_WEB_MODULE.equals(projectType)){
				j2eeLevel = J2EEVersionUtil.convertWebVersionStringToJ2EEVersionID(projectVersion);
			} else if(IModuleConstants.JST_APPCLIENT_MODULE.equals(projectType)){
				j2eeLevel = J2EEVersionUtil.convertAppClientVersionStringToJ2EEVersionID(projectVersion);
			}
			
			// this method needs to check that project's j2ee level is 14
			if(j2eeLevel !=  J2EEVersionConstants.J2EE_1_4_ID)
				continue;
			
			ArtifactEdit artifactEdit = ArtifactEdit.getArtifactEditForRead(project);
			try {
				EObject rootObject = null;
				if (artifactEdit!=null)
					rootObject = artifactEdit.getContentModelRoot();
				// handle EJB project case
				if (rootObject instanceof EJBJar) {
					List cmps = ((EJBJar) rootObject).getEnterpriseBeans();
					for (int j = 0; j < cmps.size(); j++) {
						EnterpriseBean bean = (EnterpriseBean) cmps.get(j);
						if (bean.getServiceRefs() != null && !bean.getServiceRefs().isEmpty())
							result.addAll(bean.getServiceRefs());
					}
				}
				// handle Web Project
				else if (rootObject instanceof WebApp) {
					if (((WebApp) rootObject).getServiceRefs() != null && !((WebApp) rootObject).getServiceRefs().isEmpty())
						result.addAll(((WebApp) rootObject).getServiceRefs());
				}
				// handle App clients
				else if (rootObject instanceof ApplicationClient) {
					if (((ApplicationClient) rootObject).getServiceRefs() != null && !((ApplicationClient) rootObject).getServiceRefs().isEmpty())
						result.addAll(((ApplicationClient) rootObject).getServiceRefs());
				}
			} finally {
				if (artifactEdit != null)
					artifactEdit.dispose();
			}
		}
		return result;
	}

	public boolean isJ2EE14(ServiceRef ref) {
		return !(ref.eContainer() instanceof WebServicesClient);
	}

	public List getWorkspaceWSILFiles() {
		List result = new ArrayList();
		Iterator iter = getWSArtifactEdits().iterator();
		while (iter.hasNext()) {
			WSDDArtifactEdit artifactEdit = (WSDDArtifactEdit) iter.next();
			List files = artifactEdit.getWSILResources();
			for (int j = 0; j < files.size(); j++) {
				IFile file = (IFile) files.get(j);
				if (file != null && WSIL_EXT.equals(file.getFileExtension()))
					result.add(file);
			}
		}
		return result;
	}

	public List getWorkspaceWSDLResources() {
		List result = new ArrayList();
		Iterator iter = getWSArtifactEdits().iterator();
		while (iter.hasNext()) {
			WSDDArtifactEdit artifactEdit = (WSDDArtifactEdit) iter.next();
			IProject project = artifactEdit.getProject();
			if (project != null) {
				List wsdlResources = artifactEdit.getWSDLResources();
				if (wsdlResources != null && !wsdlResources.isEmpty()) {
					for (int j = 0; j < wsdlResources.size(); j++) {
						Resource wsdl = (Resource) wsdlResources.get(j);
						if (!result.contains(wsdl))
							result.add(wsdl);
					}
				}
			}
		}
		return result;
	}

	public List getWSDLServices() {
		List result = new ArrayList();
		List internalWsdls = getInternalWSDLServices();
		if (internalWsdls != null && !internalWsdls.isEmpty())
			result.addAll(internalWsdls);
		//TODO add externals
		return result;
	}

	/**
	 * @param bean
	 * @return
	 */
	public List get13ServiceRefs(EnterpriseBean bean) {
		WSCDDArtifactEdit artifactEdit = null;
		IFile file = WorkbenchResourceHelper.getFile(bean);
		if (file!=null)
			artifactEdit = getExistingWSCDDArtifactEdit(file.getProject());
		if (artifactEdit !=null) {
			WebServicesResource res = artifactEdit.getWscddXmiResource();
			if (res != null && res.getWebServicesClient() != null) {
				String ejbName = bean.getName();
				List scopes = res.getWebServicesClient().getComponentScopedRefs();
				for (Iterator iter = scopes.iterator(); iter.hasNext();) {
					ComponentScopedRefs scope = (ComponentScopedRefs) iter.next();
					if (scope.getComponentName().equals(ejbName))
						return scope.getServiceRefs();
				}
			}
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @param client
	 * @return
	 */
	public List get13ServiceRefs(ApplicationClient client) {
		IProject handle = getComponentProject(WorkbenchResourceHelper.getFile(client));
		if (handle == null)
			return Collections.EMPTY_LIST;
		WSCDDArtifactEdit artifactEdit = getExistingWSCDDArtifactEdit(handle);
		if (artifactEdit !=null) {
			WebServicesResource res = artifactEdit.getWscddXmiResource();
			if (res != null) {
				WebServicesClient webClient = res.getWebServicesClient();
				if (webClient != null)
					return webClient.getServiceRefs();
			}
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @param webapp
	 * @return
	 */
	public List get13ServiceRefs(WebApp webapp) {
		IProject handle = getComponentProject(WorkbenchResourceHelper.getFile(webapp));
		if (handle == null)
			return Collections.EMPTY_LIST;
		WSCDDArtifactEdit artifactEdit = getExistingWSCDDArtifactEdit(handle);
		if (artifactEdit !=null) {
			WebServicesResource res = artifactEdit.getWscddXmiResource();
			if (res != null) {
				WebServicesClient webClient = res.getWebServicesClient();
				if (webClient != null)
					return webClient.getServiceRefs();
			}
		}
		return Collections.EMPTY_LIST;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
	 */
	public boolean visit(IResourceDelta delta) throws CoreException {
		IResource resource = delta.getResource();
		if (resource.getType() == IResource.PROJECT) {
			IProject p = (IProject) resource;
			// Handle project adds and project opens
			if ((delta.getKind()==IResourceDelta.ADDED || (((delta.getFlags() & IResourceDelta.OPEN) != 0) && p.isAccessible()))) {
				IVirtualComponent component = ComponentCore.createComponent(p);
				if (component!=null && !JavaEEProjectUtilities.isEARProject(p) && !JavaEEProjectUtilities.isStaticWebProject(p)) {
					getQueuedJob().addProject(p);
					return false;
				}
			}
			// Handle project close events and removals 
			else if ((delta.getKind() == IResourceDelta.CHANGED  && ((delta.getFlags() & IResourceDelta.OPEN) != 0))
					|| (delta.getKind() == IResourceDelta.REMOVED)){
				removeArtifactEdit(p);
				return false;
			}
		}
		
		else if (resource.getType() == IResource.FILE && isInterrestedInFile((IFile) resource)) {
			// Handle WSIL and WSDL File additions as well as webservice.xml and webserviceclient.xml
			if ((delta.getKind() == IResourceDelta.ADDED) || ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0)) {
				if (resource.getFileExtension().equals(WSDL_EXT))
				    addedWsdl((IFile) resource);
				else if (resource.getFileExtension().equals(WSIL_EXT))
				    addedWsil((IFile)resource);
				else if (resource.getName().equals(J2EEConstants.WEB_SERVICES_CLIENT_SHORTNAME) ||
						resource.getName().equals(J2EEConstants.WEB_SERVICES_DD_URI)) {
					getQueuedJob().addProject(resource.getProject());
				}	
			} 
			// Handle WSIL or WSDL file removals
			else if ((delta.getKind() == IResourceDelta.REMOVED) || ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0)) {
				if (resource.getFileExtension().equals(WSDL_EXT) || resource.getFileExtension().equals(WSIL_EXT))
				notifyListeners(EditModelEvent.UNLOADED_RESOURCE);
			}
			return false;
		}
		return true;
	}

	private ProcessProjectsWithWSDL createProjectsJob() {
		Set newSet = new HashSet();
		ProcessProjectsWithWSDL job = new ProcessProjectsWithWSDL(newSet, EditModelEvent.ADDED_RESOURCE);
		job.setRule(ResourcesPlugin.getWorkspace().getRoot());
		job.setSystem(true);
		return job;
	}

	private ProcessProjectsWithWSDL getQueuedJob() {
		
		if (processNewProjects != null && (processNewProjects.getState() == Job.WAITING)){
			return processNewProjects;
		} 
		processNewProjects = createProjectsJob();
		processNewProjects.schedule();
		return processNewProjects;
	}
	
	private class ProcessProjectsWithWSDL extends Job
	{
		private Set currentProjects;
		private int eventType;
		
		public ProcessProjectsWithWSDL(Set p, int newEventType)
		{
			super(ConsumptionUIMessages.MSG_LOADING_WEB_SERVICE);
			currentProjects = p;
			eventType = newEventType;
		}
		
		public void addProject(IProject p) {
			synchronized(currentProjects) {
				currentProjects.add(p);
			}
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			// Null out job for processing new projects
			synchronized (processNewProjects) {
				if(processNewProjects == this){
					processNewProjects = null;
				}
			}
			for (Iterator iterator = currentProjects.iterator(); iterator.hasNext();) {
				IProject currentProject = (IProject) iterator.next();
				addArtifactEdit(currentProject);
			}
			notifyListeners(eventType);
			
			return Status.OK_STATUS;
		}
	}

	protected void addedWsdl(IFile wsdl) {
		if (!wsdl.exists())
			return;
		IProject handle = getComponentProject(wsdl);
		if (handle != null) {
			addArtifactEdit(handle);
			notifyListeners(EditModelEvent.LOADED_RESOURCE);
		}
	}

	protected void addedWsil(IFile wsil) {
		if (!wsil.exists())
			return;
		IProject handle = getComponentProject(wsil);
		if (handle != null) {
			addArtifactEdit(handle);
			notifyListeners(EditModelEvent.LOADED_RESOURCE);
		}
	}
	
	private IProject getComponentProject(IFile res) {
		if (res==null)
			return null;
		return res.getProject();
	}

	protected boolean isInterrestedInFile(IFile aFile) {
		return isFileInteresting(aFile);
	}
	
	/**
	 * The only resources webservice manager is concerned about are:
	 * webservice.xml, webserviceclient.xml, and J2EE 1.4 web.xml, ejb-jar-xml, and application-client.xml
	 * @param res
	 * @return boolean isInterested
	 */
	private boolean isInterestedInResource(Resource res) {
		if (res instanceof WsddResource || res instanceof WebServicesResource) {
			return true;
		} else if (res instanceof EJBResource || res instanceof WebAppResource || res instanceof ApplicationClientResource) {
			return ((XMLResource)res).getJ2EEVersionID()>J2EEVersionConstants.J2EE_1_3_ID;
		} else {
			return false;
		}
	}

	/**
	 * @param object
	 * @return
	 */
	public Collection getServiceRefs(EJBJar jar) {

		List list = new ArrayList();
		List beans = jar.getEnterpriseBeans();
		try {
			for (int i = 0; i < beans.size(); i++) {
				EnterpriseBean bean = (EnterpriseBean) beans.get(i);
				list.addAll(getServiceRefs(bean));
			}
		} catch (Exception e) {
			//Ignore
		}
		return list;
	}

	public Collection getServiceRefs(EnterpriseBean bean) {
		List list = new ArrayList();
		if (bean.getEjbJar().getJ2EEVersionID() >= J2EEVersionConstants.J2EE_1_4_ID)
			list.addAll(bean.getServiceRefs());
		else
			list.addAll(get13ServiceRefs(bean));
		return list;
	}

	public Collection getServiceRefs(WebApp webapp) {

		List list = new ArrayList();
		try {
			if (webapp.getVersionID() >= J2EEVersionConstants.WEB_2_4_ID)
				list.addAll(webapp.getServiceRefs());
			else
				list.addAll(get13ServiceRefs(webapp));
		} catch (Exception e) {
			//Ignore
		}
		return list;
	}

	public Collection getServiceRefs(ApplicationClient client) {

		List list = new ArrayList();
		try {
			if (client.getJ2EEVersionID() >= J2EEVersionConstants.J2EE_1_4_ID)
				list.addAll(client.getServiceRefs());
			else
				list.addAll(get13ServiceRefs(client));
		} catch (Exception e) {
			//Ignore
		}
		return list;
	}
}
