/******************************************************************************* * Copyright (c) 2003, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jst.j2ee.internal.webservice; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; 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.jface.viewers.TreeViewer; import org.eclipse.jst.j2ee.internal.webservice.helper.WebServiceEvent; import org.eclipse.jst.j2ee.internal.webservice.helper.WebServiceManagerListener; import org.eclipse.jst.j2ee.internal.webservice.helper.WebServicesManager; import org.eclipse.jst.j2ee.internal.webservice.plugin.WebServiceUIPlugin; import org.eclipse.jst.j2ee.navigator.internal.IJ2EENavigatorConstants; import org.eclipse.ui.progress.UIJob; import org.eclipse.wst.common.internal.emfworkbench.integration.DynamicAdapterFactory; import org.eclipse.wst.common.project.facet.core.internal.FacetedProjectPropertyTester; import org.eclipse.wst.project.facet.ProductManager; import org.eclipse.jst.j2ee.internal.webservice.WebServiceUIResourceHandler; public class WebServiceViewerSynchronization implements WebServiceManagerListener{ public static final String ARE_THERE_WEBSERVICES = "areThereWebServices"; //$NON-NLS-1$ private WebServicesManager webServicesManager = null; private static final String PROJECT_FACET = "projectFacet"; //$NON-NLS-1$ /* The facets are duplicated here to avoid loading plugins just for constants */ /* package */ static final String EAR_FACET = "jst.ear"; //$NON-NLS-1$ /* package */ static final String APPCLIENT_FACET = "jst.appclient"; //$NON-NLS-1$ /* package */ static final String WEB_FACET = "jst.web"; //$NON-NLS-1$ /* package */ static final String EJB_FACET = "jst.ejb"; //$NON-NLS-1$ /* package */ static final String UTILITY_FACET = "jst.utility"; //$NON-NLS-1$ /* package */ static final String CONNECTOR_FACET = "jst.connector"; //$NON-NLS-1$ /* package */ static final String STATIC_WEB_FACET = "wst.web"; //$NON-NLS-1$ private static final FacetedProjectPropertyTester facetPropertyTester = new FacetedProjectPropertyTester(); private WebServicesNavigatorContentProvider contentProvider; private Job indexJob = new WebServiceIndexJob(); private Job updateJob = new UpdateWebServicesNodeUIJob(); private Job removeJob = new RemoveWebServicesNodeUIJob(); private boolean navigatorGroupAdded = false; boolean indexJobScheduled = false; private boolean initialized = false; public WebServiceViewerSynchronization(WebServicesNavigatorContentProvider provider) { contentProvider = provider; } public void start() { try { getWebServicesManager().addListener(this); // create the default synchronizer for any web service editor to use with view due // to the usage of seperate edit models. WebServicesNavigatorSynchronizer.createInstance( new DynamicAdapterFactory(IJ2EENavigatorConstants.VIEWER_ID), contentProvider); } finally { initialized = true; } } public void stop() { if(initialized) { getWebServicesManager().removeListener(this); // dispose current instance of web service editor/explorer synchronizer WebServicesNavigatorSynchronizer.disposeInstance(); } } public void webServiceManagerChanged(WebServiceEvent anEvent) { switch (anEvent.getEventType()) { case WebServiceEvent.REFRESH: if(!hasNavigatorGroupBeenAdded()) { if(!hasIndexJobBeenScheduled()){ indexJob.schedule(); } if(!hasNavigatorGroupBeenAdded()) addWebServiceNode(); } else { updateJob.schedule(); } break; case WebServiceEvent.REMOVE: if(hasNavigatorGroupBeenAdded()) removeJob.schedule(); } } void addWebServiceNode() { new AddWebServicesNodeUIJob().schedule(); } public void startIndexJob() { indexJob.schedule(); } /** * Employ a Test-And-Set (TST) primitive to ensure the Job is only scheduled once per load. * * @return True if the the index job has been scheduled. The value of indexJobSchedule will * _always_ be true after this method executes, so if false is returned, the job must be * scheduled by the caller. */ /* package */ synchronized boolean hasIndexJobBeenScheduled() { if (!indexJobScheduled) { indexJobScheduled = true; return false; } return true; } /** * Multiple threads access this boolean flag, so we synchronize it to ensure that its value is * consistent across different threads. * * @return True if the WebServicesNavigatorGroup has already been processed and added to the * tree. */ /* package */ synchronized boolean hasNavigatorGroupBeenAdded() { return navigatorGroupAdded; } /* package */ synchronized void setNavigatorGroupAdded(boolean hasBeenAdded) { navigatorGroupAdded = hasBeenAdded; } private WebServicesManager getWebServicesManager() { if (webServicesManager == null) webServicesManager = WebServicesManager.getInstance(); return webServicesManager; } private boolean indexWebServices(IProgressMonitor monitor) { boolean hasChildren = false; if (!monitor.isCanceled()) { try { hasChildren |= getWebServicesManager().getWorkspace13ServiceRefs().size() > 0; } catch (RuntimeException e) { WebServiceUIPlugin.logError(0, e.getMessage(), e); } } else { return hasChildren; } monitor.worked(1); if (!monitor.isCanceled()) { try { hasChildren |= getWebServicesManager().getWorkspace14ServiceRefs().size() > 0; } catch (RuntimeException e) { WebServiceUIPlugin.logError(0, e.getMessage(), e); } } else { return hasChildren; } monitor.worked(1); if (!monitor.isCanceled()) { try { hasChildren |= getWebServicesManager().getInternalWSDLServices().size() > 0; } catch (RuntimeException e) { WebServiceUIPlugin.logError(0, e.getMessage(), e); } } else { return hasChildren; } monitor.worked(1); if (!monitor.isCanceled()) { try { hasChildren |= getWebServicesManager().getExternalWSDLServices().size() > 0; } catch (RuntimeException e) { WebServiceUIPlugin.logError(0, e.getMessage(), e); } } else { return hasChildren; } monitor.worked(1); return hasChildren; } /* package */ static boolean hasFacet(Object element, String facet) { return facetPropertyTester.test(element, PROJECT_FACET, new Object[] {}, facet); } /* package */ boolean webServiceProjectsExist(IProgressMonitor monitor) { boolean ret = false; IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); monitor.beginTask(WebServiceUIResourceHandler.WebServiceViewerSynchronization_Searching_for_web_service_capable_p_, projects.length); for (int i = 0; i < projects.length; i++) { if(isInteresting(projects[i])){ ret = true; break; } } monitor.worked(1); return ret; } public static void setAreThereWebServices(boolean isThereWebServices) { // set the value of WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES so that we do not index in future WebServiceUIPlugin.getDefault().getPluginPreferences().setValue(ARE_THERE_WEBSERVICES, Boolean.toString(isThereWebServices)); WebServiceUIPlugin.getDefault().savePluginPreferences(); } public static boolean areThereWebServices() { if (ProductManager.shouldUseViewerSyncForWebservices()) { String val = WebServiceUIPlugin.getDefault().getPluginPreferences().getString(WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES); return Boolean.parseBoolean(val); } return false; } public static boolean isThereWebServicesPreferenceSet() { return WebServiceUIPlugin.getDefault().getPluginPreferences().contains(WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES); } /* package */ public static boolean isInteresting(IProject project) { return hasFacet(project, WEB_FACET) || hasFacet(project, EJB_FACET) || hasFacet(project, APPCLIENT_FACET); } public class WebServiceIndexJob extends Job { public WebServiceIndexJob() { super(WebServiceUIResourceHandler.WS_NAV_JOB0); // [204833] //setRule(new NonConflictingRule()); setRule(ResourcesPlugin.getWorkspace().getRoot()); setSystem(true); } @Override protected IStatus run(IProgressMonitor monitor) { monitor.beginTask(WebServiceUIResourceHandler.WS_NAV_JOB1, 5); boolean isThereWebServices = false; if (webServiceProjectsExist(monitor)) { isThereWebServices = indexWebServices(monitor); if( isThereWebServices ){ setAreThereWebServices(isThereWebServices); } }else{ setAreThereWebServices(false); } if(!hasNavigatorGroupBeenAdded()){ if(isThereWebServices) addWebServiceNode(); } monitor.done(); return Status.OK_STATUS; } } public class AddWebServicesNodeUIJob extends UIJob { public AddWebServicesNodeUIJob() { super(WebServiceUIResourceHandler.WS_NAV_JOB2); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { TreeViewer viewer = contentProvider.getViewer(); if(!viewer.getControl().isDisposed()) { viewer.add(viewer.getInput(), contentProvider.getNavigatorGroup()); } setNavigatorGroupAdded(true); return Status.OK_STATUS; } } public class UpdateWebServicesNodeUIJob extends UIJob { public UpdateWebServicesNodeUIJob () { super(WebServiceUIResourceHandler.WS_NAV_JOB3); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { TreeViewer viewer = contentProvider.getViewer(); if(!viewer.getControl().isDisposed()) { if(hasNavigatorGroupBeenAdded()) contentProvider.getViewer().refresh(contentProvider.getNavigatorGroup()); else { viewer.add(viewer.getInput(), contentProvider.getNavigatorGroup()); setNavigatorGroupAdded(true); } } return Status.OK_STATUS; } } public class RemoveWebServicesNodeUIJob extends UIJob { public RemoveWebServicesNodeUIJob() { super(WebServiceUIResourceHandler.WS_NAV_JOB4); // [204833] setRule(ResourcesPlugin.getWorkspace().getRoot()); setSystem(true); } @Override public IStatus runInUIThread(IProgressMonitor monitor) { monitor.beginTask(WebServiceUIResourceHandler.WS_NAV_JOB5, 4); TreeViewer viewer = contentProvider.getViewer(); if(!viewer.getControl().isDisposed()) { if(hasNavigatorGroupBeenAdded()){ if (indexWebServices(monitor)) { viewer.refresh(contentProvider.getNavigatorGroup()); setAreThereWebServices(true); } else { viewer.remove(contentProvider.getNavigatorGroup()); setNavigatorGroupAdded(false); setAreThereWebServices(false); if(contentProvider.projectListener != null && !contentProvider.projectListener.isDisposed() && !contentProvider.projectListener.isListening()) contentProvider.projectListener.startListening(); } } } return Status.OK_STATUS; } } }