/*******************************************************************************
 * Copyright (c) 2001, 2006 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.jem.workbench.utility;

/*
 * $RCSfile: JavaModelListener.java,v $ $Revision: 1.7 $ $Date: 2008/06/30 21:06:41 $
 */

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.*;

import org.eclipse.jem.internal.core.JEMPlugin;

/**
 * An element change listener to listen for Java Model changes. It breaks the notification up into individual method calls to make it easier to walk
 * the notification tree.
 * 
 * @since 1.2.0
 */
public abstract class JavaModelListener implements IElementChangedListener {

	/**
	 * Construct with listening only for {@link ElementChangedEvent#POST_CHANGE} events.
	 * 
	 * 
	 * @since 1.2.0
	 */
	private HashMap resolvedContainers = new HashMap();
	public JavaModelListener() {
		this(ElementChangedEvent.POST_CHANGE);
	}

	/**
	 * Construct with supplying the type of events to listen for.
	 * 
	 * @param eventsToListen
	 *            or'd together event listening types. See {@link ElementChangedEvent} for the types.
	 * 
	 * @since 1.2.0
	 */
	public JavaModelListener(int eventsToListen) {
		JavaCore.addElementChangedListener(this, eventsToListen);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
	 */
	public void elementChanged(ElementChangedEvent event) {
		
		processDelta((IJavaElementDelta) event.getSource());
		
	}

	/**
	 * Generally dispatch the children of the delta. Normally this method should not be overridden.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processChildren(IJavaElement element, IJavaElementDelta delta) {
		IJavaElementDelta[] children = delta.getAffectedChildren();
		for (int i = 0; i < children.length; i++) {
			processDelta(children[i]);
		}
	}

	/**
	 * Source content has changed. The default is to do nothing. Subclasses may override to perform own functions.
	 * 
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processContentChanged(IJavaElementDelta delta) {
	}

	/**
	 * Dispatch the java element delta. This method should normally not be overridden. One
	 * usage would be to add delta types that are to be processed and dispatched by the
	 * subclasses. For example also dispatch on {@link IJavaElement#IMPORT_CONTAINER}. Subclasses
	 * should call <code>super.processDelta(IJavaElementDelta)</code> if it is not one they
	 * are interested in.
	 * 
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	public void processDelta(IJavaElementDelta delta) {
		IJavaElement element = delta.getElement();
		// if the class path has changed we refresh the resolved container cache
		int flags= delta.getFlags();
		if (((flags & IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED) != 0) && !resolvedContainers.isEmpty()){
			resolvedContainers.clear();			
		}

		switch (element.getElementType()) {
			case IJavaElement.JAVA_MODEL:
				processJavaElementChanged((IJavaModel) element, delta);
				break;
			case IJavaElement.JAVA_PROJECT:
				processJavaElementChanged((IJavaProject) element, delta);
				break;
			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
				processJavaElementChanged((IPackageFragmentRoot) element, delta);
				break;
			case IJavaElement.PACKAGE_FRAGMENT:
				processJavaElementChanged((IPackageFragment) element, delta);
				break;
			case IJavaElement.COMPILATION_UNIT:
				processJavaElementChanged((ICompilationUnit) element, delta);
				processContentChanged(delta);
				break;
			case IJavaElement.CLASS_FILE:
				processJavaElementChanged((IClassFile) element, delta);
				break;
			case IJavaElement.TYPE:
				processJavaElementChanged((IType) element, delta);
				break;
			// Note: if we are to update the Method/Field adapters, we should process the
			// IJavaElement.METHOD and IJavaElement.FIELD
		}
	}

	/**
	 * Process the classfile changed event. The default is to do nothing. It will not walk any children of the delta either. Subclasses may override
	 * to perform their own functions.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(IClassFile element, IJavaElementDelta delta) {
	}

	/**
	 * Process the compilation unit changed event. The default is to process the children of the delta. Subclasses may override to perform their own
	 * functions. If they wish to walk the children they should then also call
	 * <code>super.processJavaElementChanged(ICompilationUnit, IJavaElementDelta)</code>.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(ICompilationUnit element, IJavaElementDelta delta) {
		processChildren(element, delta);
	}

	/**
	 * Process the java model changed event. The default is to process the children of the delta. Subclasses may override to perform their own
	 * functions. If they wish to walk the children they should then also call
	 * <code>super.processJavaElementChanged(IJavaModel, IJavaElementDelta)</code>.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(IJavaModel element, IJavaElementDelta delta) {
		processChildren(element, delta);
	}

	/**
	 * Process the java project changed event. The default is to process the children of the delta. Subclasses may override to perform their own
	 * functions. If they wish to walk the children they should then also call
	 * <code>super.processJavaElementChanged(IJavaProject, IJavaElementDelta)</code>.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(IJavaProject element, IJavaElementDelta delta) {
		processChildren(element, delta);
	}

	/**
	 * Process the package fragment changed event. The default is to process the children of the delta. Subclasses may override to perform their own
	 * functions. If they wish to walk the children they should then also call
	 * <code>super.processJavaElementChanged(IPackageFragment, IJavaElementDelta)</code>.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(IPackageFragment element, IJavaElementDelta delta) {
		processChildren(element, delta);
	}

	/**
	 * Process the package fragment root changed event. The default is to process the children of the delta. Subclasses may override to perform their
	 * own functions. If they wish to walk the children they should then also call
	 * <code>super.processJavaElementChanged(IPackageFragmentRoot, IJavaElementDelta)</code>.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(IPackageFragmentRoot element, IJavaElementDelta delta) {
		processChildren(element, delta);
	}

	/**
	 * Process the IType changed event. The default is to do nothing. It will not walk any children of the delta either. Subclasses may override to
	 * perform their own functions.
	 * 
	 * @param element
	 * @param delta
	 * 
	 * @since 1.2.0
	 */
	protected void processJavaElementChanged(IType element, IJavaElementDelta delta) {
	}

	/**
	 * Answers whether this element delta is a classpath change. I.e. something added/removed/moved around for the classpath. This should only be
	 * called for a delta that is for an {@link IPackageFragmentRoot}. Should be called from an override of
	 * {@link #processJavaElementChanged(IPackageFragmentRoot, IJavaElementDelta)}
	 * 
	 * @param delta
	 * @return <code>true</code> if it is classpath change or <code>false</code> if not.
	 * 
	 * @since 1.2.0
	 */
	protected boolean isClassPathChange(IJavaElementDelta delta) {
		int flags = delta.getFlags();
		return (delta.getKind() == IJavaElementDelta.CHANGED && ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0)
				|| ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) || ((flags & IJavaElementDelta.F_REORDER) != 0));
	}

	/**
	 * Answer whether the change is this is a raw classpath change, or if a file that is in the root of the project was changed that also can mean a
	 * raw classpath change. This must only be called for a delta that is for an {@link IJavaProject}.
	 * <p>
	 * See {@link IJavaElementDelta.#F_CLASSPATH_CHANGED} and {@link #isAlsoClasspathChange(IPath)} for details.
	 * 
	 * @param delta
	 * @return
	 * 
	 * @since 1.2.0
	 */
	protected boolean isClasspathResourceChange(IJavaElementDelta delta) {
		if ((delta.getFlags() & IJavaElementDelta.F_CLASSPATH_CHANGED) != 0)
			return true;
		IResourceDelta[] resources = delta.getResourceDeltas();
		if (resources == null)
			return false;
		IPath path = null;
		for (int i = 0; i < resources.length; i++) {
			if (resources[i].getKind() == IResourceDelta.CHANGED) {
				path = resources[i].getProjectRelativePath();
				if (isAlsoClasspathChange(path))
					return true;
			}
		}
		return false;
	}

	/**
	 * Answers whether the file specified by the path is one that when changed can result in a classpath change. This is called from
	 * {@link #isClasspathResourceChange(IJavaElementDelta)}. The file must be in the root of the project. The default is <code>false</code>.
	 * Subclasses may override.
	 * 
	 * @param path
	 * @return <code>true</code> if this file being changed would result in a classpath change, <code>false</code> if not.
	 * 
	 * @since 1.2.0
	 */
	protected boolean isAlsoClasspathChange(IPath path) {
		return false;
	}

	/**
	 * Answers whether the given java project is in the classpath (including recursive). This currently will not walk through containers (such as the
	 * PDE container). Only through the direct and recursive project references. The java project is determined by subclasses, see
	 * {@link #getJavaProject()}.
	 * 
	 * @param javaProject
	 * @return <code>true</code> if project is in classpath or <code>false</code> if not.
	 * 
	 * @since 1.2.0
	 */
	protected boolean isInClasspath(IJavaProject javaProject) {
		IJavaProject listenerJavaProject = getJavaProject();
		if (javaProject.equals(listenerJavaProject))
			return true;
		return isInClasspath(javaProject, listenerJavaProject, true, new HashSet());
	}

	/**
	 * The java project for this listener. Subclasses must provide a java project.
	 * 
	 * @return the java project. <code>null</code> is not valid.
	 * 
	 * @since 1.2.0
	 */
	protected abstract IJavaProject getJavaProject();

	/*
	 * test to see if the testProject is in the classpath (including from any referenced projects) of the target project. Keep track of those already
	 * visited so as not to visit again. Too late to make private. But it should not be overridden.
	 */
	protected boolean isInClasspath(IJavaProject testProject, IJavaProject targetProject, boolean isFirstLevel, Set visited) {
		if (visited.contains(targetProject))
			return false;
		visited.add(targetProject);
		IClasspathEntry[] entries = null;
		try {
			entries = targetProject.getRawClasspath();
		} catch (JavaModelException e) {
			return false;
		}
		List projects = null;
		for (int i = 0; i < entries.length; i++) {
			IClasspathEntry entry;
			entry = entries[i];
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_PROJECT:
					IJavaProject entryProject = getVisibleJavaProject(entry, isFirstLevel);
					if (entryProject != null) {
						if (entryProject.equals(testProject)) {
							return true;
						} else {
							if (projects == null) {
								projects = new ArrayList();
							}
							projects.add(entryProject);
						}
					}
					break;
				//A container may contain references to projects.
				case IClasspathEntry.CPE_CONTAINER :
					IClasspathContainer container = null;
					try {
						container = JavaCore.getClasspathContainer(entry.getPath(), targetProject);
					} catch (JavaModelException e) {
						JEMPlugin.getPlugin().getLogger().logError(e);
					}
					if (container == null || container.getKind() != IClasspathContainer.K_APPLICATION)
						break;
					//First see if we already resolved
					IClasspathEntry[] containerEntries = null;
					containerEntries = (IClasspathEntry[])resolvedContainers.get(container);
					if (containerEntries == null) {
						containerEntries = container.getClasspathEntries();
						resolvedContainers.put(container, containerEntries);
					}
					for (int j = 0; j < containerEntries.length; j++) {
						if (containerEntries[j].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
							IJavaProject conEntryProject = getVisibleJavaProject(containerEntries[j], isFirstLevel);
							if (conEntryProject != null) {
								if (conEntryProject.equals(testProject)) {
									return true;
								} else {
									if (projects == null) {
										projects = new ArrayList();
									}
									projects.add(conEntryProject);
								}
							}
						}
					}
					break;
			}
		}
		return isInClasspath(testProject, projects, false, visited);
	}
	
	/*
	 * This method is used to return an IJavaProject that is resolved from the entry
	 * if it is currently visible to downstream projects.
	 */
	private IJavaProject getVisibleJavaProject(IClasspathEntry entry, boolean isFirstLevel) {
		if (isFirstLevel || entry.isExported()) {
			IClasspathEntry resEntry = JavaCore.getResolvedClasspathEntry(entry);
			return getJavaProject(resEntry);
		}
		return null;
	}

	/*
	 * See if the testProject is in the classpath of any of the list of projects or in any project that an entry in the list may of visited. Too late
	 * to make private. But it should not be overridden.
	 */
	protected boolean isInClasspath(IJavaProject testProject, List someJavaProjects, boolean isFirstLevel, Set visited) {
		if (someJavaProjects == null)
			return false;
		int size = someJavaProjects.size();
		IJavaProject javaProj = null;
		for (int i = 0; i < size; i++) {
			javaProj = (IJavaProject) someJavaProjects.get(i);
			return isInClasspath(testProject, javaProj, isFirstLevel, visited);
		}
		return false;
	}

	/**
	 * Get the java project that classpath entry is for. This should only be called on classpath entries of type {@link IClasspathEntry#CPE_PROJECT}
	 * 
	 * @param entry
	 *            classpath entry of type {@link IClasspathEntry#CPE_PROJECT}.
	 * @return the java project for this entry. The project might not actually exist. That is not verified.
	 * 
	 * @since 1.2.0
	 */
	protected IJavaProject getJavaProject(IClasspathEntry entry) {
		IProject proj = getWorkspaceRoot().getProject(entry.getPath().segment(0));
		if (proj != null)
			return JavaCore.create(proj);
		return null;
	}

	/**
	 * Get the workspace root. A utility method.
	 * @return the workspace root.
	 * 
	 * @since 1.2.0
	 */
	protected IWorkspaceRoot getWorkspaceRoot() {
		return ResourcesPlugin.getWorkspace().getRoot();
	}
}
