/*******************************************************************************
 * Copyright (c) 2003, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 * Created on Feb 9, 2004
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */



package org.eclipse.jst.j2ee.internal.webservice.helper;

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

import org.eclipse.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.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.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;

/**
 * @author jlanuti
 * 
 * To change the template for this generated type comment go to Window - Preferences - Java - Code
 * Generation - Code and Comments
 */
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;

	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) || J2EEProjectUtilities.isEARProject(project) || J2EEProjectUtilities.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() == 1) {
			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 (J2EEProjectUtilities.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 && !J2EEProjectUtilities.isEARProject(p) && !J2EEProjectUtilities.isStaticWebProject(p)) {
					Job job = new ProcessProjectsWithWSDL(p, EditModelEvent.ADDED_RESOURCE);
					job.setRule(p);
					job.setSystem(true);
					job.schedule();
					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)) {
					Job job = new ProcessProjectsWithWSDL(resource.getProject(), EditModelEvent.LOADED_RESOURCE);
					job.setRule(resource.getProject());
					job.schedule();
				}	
			} 
			// 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 class ProcessProjectsWithWSDL extends Job
	{
		private IProject currentProject;
		private int eventType;
		
		public ProcessProjectsWithWSDL(IProject p, int newEventType)
		{
			super("Loading artifact edit for project");
			currentProject = p;
			eventType = newEventType;
		}
		
		protected IStatus run(IProgressMonitor monitor) {
			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;
	}
}
