/******************************************************************************* * Copyright (c) 2005, 2010 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 *******************************************************************************/ /* * $$RCSfile: ResourceSetWorkbenchSynchronizer.java,v $$ * $$Revision: 1.4 $$ $$Date: 2006/05/17 20:13:45 $$ */ package net.enilink.komma.workbench; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import net.enilink.komma.model.IModelSet; import net.enilink.komma.workbench.internal.KommaWorkbenchContextFactory; import net.enilink.komma.workbench.internal.KommaWorkbenchPlugin; /** * Synchronizer on the workspace. It listens for the project to see if it is * closed or deleted. If it does it notifies this out. * * @since 1.0.0 */ public class ModelSetWorkbenchSynchronizer implements IResourceChangeListener { protected IProject project; protected WeakReference<IModelSet> modelSetReference; /** Extenders that will be notified after a pre build resource change */ protected List<ISynchronizerExtender> extenders; /** The delta for this project that will be broadcast to the extenders */ protected IResourceDelta currentProjectDelta; private int currentEventType = -1; /** * Constructor taking a model set and project. * * @param modelSet * @param project * * @since 1.0.0 */ public ModelSetWorkbenchSynchronizer(IModelSet modelSet, IProject project) { this.modelSetReference = new WeakReference<IModelSet>(modelSet); this.project = project; if (modelSet != null && modelSet instanceof IProjectModelSet) { ((IProjectModelSet) modelSet).setSynchronizer(this); } initialize(); } /** * Get the project for this synchronizer * * @return project * * @since 1.0.0 */ public IProject getProject() { return project; } /* * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) */ public void resourceChanged(IResourceChangeEvent event) { currentEventType = event.getType(); currentProjectDelta = null; if ((currentEventType == IResourceChangeEvent.PRE_CLOSE || currentEventType == IResourceChangeEvent.PRE_DELETE) && event.getResource().equals(getProject())) { notifyExtendersOfClose(); release(); } } protected void notifyExtendersIfNecessary() { if (currentEventType != IResourceChangeEvent.POST_CHANGE || extenders == null || currentProjectDelta == null) { return; } for (int i = 0; i < extenders.size(); i++) { ISynchronizerExtender extender = (ISynchronizerExtender) extenders .get(i); extender.projectChanged(currentProjectDelta); } } protected void notifyExtendersOfClose() { if (extenders != null && !extenders.isEmpty()) { for (int i = 0; i < extenders.size(); i++) { ISynchronizerExtender extender = (ISynchronizerExtender) extenders .get(i); extender.projectClosed(); } } } protected IWorkspace getWorkspace() { if (getProject() == null) { return ResourcesPlugin.getWorkspace(); } return getProject().getWorkspace(); } protected void initialize() { getWorkspace().addResourceChangeListener( this, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_BUILD); } /** * Dispose of the synchronizer. Called when no longer needed. * * @since 1.0.0 */ public void dispose() { getWorkspace().removeResourceChangeListener(this); } /** * The project is going away so we need to cleanup ourself and the * model set. */ protected void release() { if (KommaWorkbenchPlugin.isActivated()) { try { IModelSet modelSet = modelSetReference.get(); if (modelSet instanceof IProjectModelSet) { ((IProjectModelSet) modelSet).release(); } } finally { KommaWorkbenchContextFactory.INSTANCE .removeCachedProject(getProject()); dispose(); } } } /** * Add an extender to be notified of events. * * @param extender * * @since 1.0.0 */ public void addExtender(ISynchronizerExtender extender) { if (extenders == null) extenders = new ArrayList<ISynchronizerExtender>(3); extenders.add(extender); } /** * Remove extender from notification of events. * * @param extender * * @since 1.0.0 */ public void removeExtender(ISynchronizerExtender extender) { if (extenders == null) return; extenders.remove(extender); } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ public String toString() { return getClass().getName() + '(' + ((getProject() != null) ? getProject().getName() : "null") + ')'; //$NON-NLS-1$ } /** * Tell Synchronizer that a file is about to be saved. This method should be * called prior to writing to an IFile from a KOMMA model. * <p> * Default does nothing, but subclasses can do something. * </p> * * @param aFile * file about to be saved. * * @since 1.0.0 */ public void preSave(IFile aFile) { // Default is do nothing } }