All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.wst.validation.internal.EventManager Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2001, 2008 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.wst.validation.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;

/**
 * This class manages resource change events for the validation framework.
 */
public class EventManager implements IResourceChangeListener {
	private static EventManager _inst;
	
	// false means that eclipse is not shutting down, and true means that it is shutting down. 
	private boolean _shutdown; 

	private IResourceDeltaVisitor _postAutoBuildVisitor;
	private boolean _isActive; // has the registry been read?
	
	private Set _listeners = new CopyOnWriteArraySet();

	private EventManager() {
	}

	public static EventManager getManager() {
		if (_inst == null)_inst = new EventManager();
		return _inst;
	}
	
	public void addProjectChangeListener(IProjectChangeListener listener){
		Tracing.log("EventManager-03: add listener: ", listener); //$NON-NLS-1$
		_listeners.add(listener);
	}
	
	public void removeProjectChangeListener(IProjectChangeListener listener){
		_listeners.remove(listener);
	}
	
	private void signal(IProject project, int type){
		if (Tracing.isLogging()){
			String name = "Null"; //$NON-NLS-1$
			if (project != null)name = project.getName();
			Tracing.log("EventManager-02: signal project: " + name + ", IProjectChangeListener type: " + type); //$NON-NLS-1$ //$NON-NLS-2$
		}
		for (IProjectChangeListener pcl : _listeners){
			try {
				pcl.projectChanged(project, type);
			}
			catch (Exception e){
				ValidationPlugin.getPlugin().handleException(e);
			}
		}
	}

	public void opening(IProject project) {
		if (project == null || !ValidationPlugin.isActivated())return;
		
		signal(project, IProjectChangeListener.ProjectOpened);

		// When the project is opened, check for any orphaned tasks or tasks whose owners need to be updated.
//		ConfigurationManager.getManager().opening(project);
	}

	public void closing(IProject project) {
		if (project == null || !ValidationPlugin.isActivated())return;
		
		signal(project, IProjectChangeListener.ProjectClosed);
		
		try {
			boolean isMigrated = ConfigurationManager.getManager().isMigrated(project);
			// If it's not migrated, then it hasn't been loaded, and we don't want to load the
			// validator and its prerequisite plug-ins until they're needed.
			if (isMigrated) {
				ValidatorMetaData[] vmds = ConfigurationManager.getManager().getProjectConfiguration(project).getValidators();
				for (ValidatorMetaData vmd : vmds) {

					if (!vmd.isActive()) {
						// If this validator has not been activated, or if it has been shut down,
						// don't activate it again.
						continue;
					}

					IWorkbenchContext helper = null;
					try {
						helper = vmd.getHelper(project);
						helper.closing();
					} catch (InstantiationException e) {
						// Remove the vmd from the reader's list
						ValidationRegistryReader.getReader().disableValidator(vmd);

						ValidationPlugin.getPlugin().handleException(e);
					} catch (Exception e) {
						// If there is a problem with this particular helper, log the error and
						// continue with the next validator.
						ValidationPlugin.getPlugin().handleException(e);
					}
				}

				ConfigurationManager.getManager().closing(project);
			}
		} catch (InvocationTargetException e) {
			ValidationPlugin.getPlugin().handleException(e);
			if (e.getTargetException() != null)
				ValidationPlugin.getPlugin().handleException(e.getTargetException());
		}
	}

	public void deleting(IProject project) {
		if (project == null)return;
		
		signal(project, IProjectChangeListener.ProjectDeleted);

		try {
			boolean isMigrated = ConfigurationManager.getManager().isMigrated(project);
			// If it's not migrated, then it hasn't been loaded, and we don't want to load the
			// validator and its prerequisite plug-ins until they're needed.
			if (isMigrated) {
				ValidatorMetaData[] vmds = ConfigurationManager.getManager().getProjectConfiguration(project).getValidators();
				for (ValidatorMetaData vmd : vmds) {

					if (!vmd.isActive()) {
						// If this validator has not been activated, or if it has been shut down,
						// don't activate it again.
						continue;
					}

					IWorkbenchContext helper = null;
					try {
						helper = vmd.getHelper(project);
						helper.deleting();
					} catch (InstantiationException e) {
						// Remove the vmd from the reader's list
						ValidationRegistryReader.getReader().disableValidator(vmd);
						ValidationPlugin.getPlugin().handleException(e);
						continue;
					} catch (Exception e) {
						// If there is a problem with this particular helper, log the error and
						// continue with the next validator.
						ValidationPlugin.getPlugin().handleException(e);
						continue;
					}
				}

//				ConfigurationManager.getManager().deleting(project);
			}
		} catch (InvocationTargetException e) {
			ValidationPlugin.getPlugin().handleException(e);
			if (e.getTargetException() != null)
				ValidationPlugin.getPlugin().handleException(e.getTargetException());

		}
	}

	/**
	 * If a project's description changes, The project may have changed its nature. Update the cache
	 * to reflect the new natures. The project could be opening. Migrate.
	 */
	private void postAutoChange(IResourceDelta delta) {
		if (_postAutoBuildVisitor == null) {
			_postAutoBuildVisitor = new IResourceDeltaVisitor() {
				public boolean visit(IResourceDelta subdelta) throws CoreException {
					if (subdelta == null)return false;

					IResource resource = subdelta.getResource();
					if (resource instanceof IWorkspaceRoot)return true;
					if (resource instanceof IProject) {
						IProject project = (IProject) resource;
						if ((subdelta.getFlags() & IResourceDelta.DESCRIPTION) == IResourceDelta.DESCRIPTION) {
							signal(project, IProjectChangeListener.ProjectChanged);
							return false;
						}

						if ((subdelta.getFlags() & IResourceDelta.OPEN) == IResourceDelta.OPEN) {
							if (project.isOpen()) {
								// Project was just opened. If project.isOpen() had returned false,
								// project would just have been closed.
								opening(project);
							}
							return false;
						}
						
						if ((subdelta.getFlags() & IResourceDelta.ADDED) == IResourceDelta.ADDED) {
							signal(project, IProjectChangeListener.ProjectAdded);
							return false;
						}
					}

					return false;
				}
			};
		}

		try {
			delta.accept(_postAutoBuildVisitor, true);
		} catch (CoreException exc) {
			ValidationPlugin.getPlugin().handleException(exc);
		}
	}

	/**
	 * Notifies this manager that some resource changes have happened on the platform. If the change
	 * is a project deletion, that project should be removed from the cache.
	 * 
	 * @see IResourceDelta
	 * @see IResource
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		if (_shutdown && !isActive()) {
			// If we're shutting down, and nothing has been activated, don't need to do anything.
			return;
		}

		if (Tracing.isLogging()){
			Tracing.log("Eventmanager-01: IResourceChangeEvent type=" + //$NON-NLS-1$
				Misc.resourceChangeEventType(event.getType()) + 
				", resource=" +  //$NON-NLS-1$
				event.getResource() + ", source=" + event.getSource() + ", delta=" +   //$NON-NLS-1$//$NON-NLS-2$
				event.getDelta());				
		}
		
		if (event.getSource() instanceof IWorkspace) {
			boolean isProject = event.getResource() instanceof IProject;
			if ((event.getType() == IResourceChangeEvent.PRE_DELETE) && isProject) {
				deleting((IProject) event.getResource());
			} else if ((event.getType() == IResourceChangeEvent.PRE_CLOSE) && isProject) {
				closing((IProject) event.getResource());
			} else if (event.getType() == IResourceChangeEvent.PRE_BUILD) {
				postAutoChange(event.getDelta());
			}
		}
	}

	/**
	 * Notifies this manager that the ValidationPlugin is shutting down. (Usually implies that
	 * either the plug-in could not load, or that the workbench is shutting down.)
	 * 

* The manager will then notify all active helpers of the shutdown, so that they may perform any * last-minute writes to disk, cleanup, etc. */ public void shutdown() { try { // resourceChanged(IResourceChangeEvent) needs to know when a shutdown has started. _shutdown = true; // If the validators are loaded, then for every project in the workbench, // we must see if it has been loaded. If it has, every enabled IWorkbenchContext // must be called to clean up. If the project hasn't been loaded, then no // IWorkbenchContext built anything, and there's nothing to clean up. IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot workspaceRoot = workspace.getRoot(); IProject[] projects = workspaceRoot.getProjects(); ProjectConfiguration prjp = null; for (IProject project : projects) { if (!project.isOpen()) { // If the project isn't opened, there's nothing to clean up. // If the project was opened, it would have been migrated, and there's something // to clean up. continue; } try { boolean isMigrated = ConfigurationManager.getManager().isMigrated(project); // If it's not migrated, then it hasn't been loaded, and we don't want to load // the validator and its prerequisite plug-ins until they're needed. if (isMigrated) { prjp = ConfigurationManager.getManager().getProjectConfiguration(project); ValidatorMetaData[] vmdList = prjp.getEnabledValidators(); // if vmdList is null, IProject has never been loaded, so nothing to clean up if (vmdList != null) { for (int j = 0; j < vmdList.length; j++) { ValidatorMetaData vmd = vmdList[j]; if (!vmd.isActive()) { // If this validator has not been activated, or if it has been // shut down, don't activate it again. continue; } IWorkbenchContext helper = vmd.getHelper(project); if (helper != null) { try { helper.shutdown(); } catch (Exception exc) { // Since we're shutting down, ignore the exception. } } } } } } catch (InvocationTargetException e) { ValidationPlugin.getPlugin().handleException(e); if (e.getTargetException() != null) ValidationPlugin.getPlugin().handleException(e.getTargetException()); } } } catch (Exception exc) { // Since we're shutting down, ignore the exception. } } public boolean isActive() { // Have to use this convoluted technique for the shutdown problem. // i.e., when eclipse is shut down, if validation plug-in hasn't been loaded, // the EventManager is activated for the first time, and it // sends many exceptions to the .log. At first, I wrote a // static method on ValidationRegistryReader, which returned true // if the registry had been read, and false otherwise. However, // that didn't solve the exception problem, because eclipse's // class loader failed to load the ValidationRegistryReader class. // // The fix is to keep all shutdown mechanisms in this class. // Track everything in here. return _isActive; } /** * This method should only be called by the ValidationRegistryReader once the registry has been * read. */ public void setActive(boolean b) { _isActive = b; } /** * This method should be used to determine if the workbench is running in UI or Headless. * * @deprecated This plug-in no longer depends on jem. If you need this function use the jem * code directly. */ public static boolean isHeadless() { //return UIContextDetermination.getCurrentContext() == UIContextDetermination.HEADLESS_CONTEXT; return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy