/*******************************************************************************
* Copyright (c) 2009 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
* Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.core.project;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.eclipse.core.resources.*;
import org.eclipse.php.internal.core.PHPCoreConstants;
import org.eclipse.php.internal.core.PHPCorePlugin;
import org.eclipse.php.internal.core.preferences.*;
public class PHPVersionChangedHandler implements IResourceChangeListener {
private static final String PHP_VERSION = PHPCoreConstants.PHP_OPTIONS_PHP_VERSION;
private HashMap<IProject, HashSet<IPreferencesPropagatorListener>> projectListeners = new HashMap<IProject, HashSet<IPreferencesPropagatorListener>>();
private HashMap<IProject, PreferencesPropagatorListener> preferencesPropagatorListeners = new HashMap<IProject, PreferencesPropagatorListener>();
private PreferencesPropagator preferencesPropagator;
private static final String NODES_QUALIFIER = PHPCorePlugin.ID;
private static final PHPVersionChangedHandler instance = new PHPVersionChangedHandler();
private PHPVersionChangedHandler() {
preferencesPropagator = PreferencePropagatorFactory.getPreferencePropagator(NODES_QUALIFIER);
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
public static PHPVersionChangedHandler getInstance() {
return instance;
}
private void projectVersionChanged(IProject project, PreferencesPropagatorEvent event) {
HashSet<IPreferencesPropagatorListener> listeners = projectListeners.get(project);
if (listeners != null) {
for (Iterator<IPreferencesPropagatorListener> iter = listeners.iterator(); iter.hasNext();) {
IPreferencesPropagatorListener listener = iter.next();
listener.preferencesEventOccured(event);
}
}
}
private class PreferencesPropagatorListener implements IPreferencesPropagatorListener {
private IProject project;
public PreferencesPropagatorListener(IProject project) {
this.project = project;
}
public void preferencesEventOccured(PreferencesPropagatorEvent event) {
if (event.getNewValue() == null) {
// We take the workspace settings since there was a move from
// project-specific to workspace settings.
String newValue = PreferencesSupport.getWorkspacePreferencesValue(PHPCorePlugin.ID,
(String) event.getKey());
if (newValue == null || newValue.equals(event.getOldValue())) {
return; // No need to send a notification
}
event = new PreferencesPropagatorEvent(event.getSource(), event.getOldValue(), newValue,
event.getKey());
} else if (event.getOldValue() == null) {
// In this case there was a move from the workspace setting to a
// project-specific setting.
// At this stage the new value of the project-specific will
// always be as the workspace, so there is
// no need to send a notification.
String preferencesValue = PreferencesSupport.getWorkspacePreferencesValue(PHPCorePlugin.ID,
(String) event.getKey());
if (preferencesValue != null && preferencesValue.equals(event.getNewValue())) {
return; // No need to send a notification
}
}
projectVersionChanged(project, event);
}
public IProject getProject() {
return project;
}
}
public void addPHPVersionChangedListener(IPreferencesPropagatorListener listener) {
IProject project = listener.getProject();
HashSet<IPreferencesPropagatorListener> listeners = projectListeners.get(project);
if (listeners == null) {
projectAdded(project);
listeners = projectListeners.get(project);
}
listeners.add(listener);
}
public void removePHPVersionChangedListener(IPreferencesPropagatorListener listener) {
if (listener == null) {// this was added since when working with RSE
// project model, listener was NULL
return;
}
IProject project = listener.getProject();
HashSet<IPreferencesPropagatorListener> listeners = projectListeners.get(project);
if (listeners != null) {
listeners.remove(listener);
}
}
public void projectAdded(IProject project) {
if (project == null || projectListeners.get(project) != null) {
return;
}
projectListeners.put(project, new HashSet<IPreferencesPropagatorListener>());
// register as a listener to the PP on this project
PreferencesPropagatorListener listener = new PreferencesPropagatorListener(project);
preferencesPropagatorListeners.put(project, listener);
preferencesPropagator.addPropagatorListener(listener, PHP_VERSION);
}
public void projectRemoved(IProject project) {
PreferencesPropagatorListener listener = preferencesPropagatorListeners.get(project);
if (listener == null) {
return;
}
preferencesPropagator.removePropagatorListener(listener, PHP_VERSION);
preferencesPropagatorListeners.remove(project);
projectListeners.remove(project);
}
private void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) {
if (delta == null) {
return;
}
IResource resource = delta.getResource();
IResourceDelta[] children = null;
switch (resource.getType()) {
case IResource.ROOT:
children = delta.getAffectedChildren();
break;
case IResource.PROJECT:
IProject project = (IProject) resource;
switch (delta.getKind()) {
case IResourceDelta.ADDED:
projectAdded(project);
break;
case IResourceDelta.CHANGED:
if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
// project opened or closed
if (project.isOpen()) {
projectAdded(project);
} else {
projectRemoved(project);
}
}
break;
case IResourceDelta.REMOVED:
projectRemoved(project);
break;
}
break;
}
if (children != null) {
for (int i = 0; i < children.length; i++) {
this.checkProjectsBeingAddedOrRemoved(children[i]);
}
}
}
public void resourceChanged(IResourceChangeEvent event) {
checkProjectsBeingAddedOrRemoved(event.getDelta());
}
}