Java tutorial
/****************************************************************************** * Copyright (c) 2009-2013, Linagora * * 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: * Linagora - initial API and implementation *******************************************************************************/ package com.ebmwebsourcing.petals.services.explorer; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IFile; 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.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchListener; import org.eclipse.ui.PlatformUI; import com.ebmwebsourcing.petals.services.PetalsServicesPlugin; import com.ebmwebsourcing.petals.services.explorer.sources.CurrentWorkspaceSource; import com.ebmwebsourcing.petals.services.explorer.sources.EndpointSource; import com.ebmwebsourcing.petals.services.explorer.sources.ExternalWorkspaceSource; import com.ebmwebsourcing.petals.services.explorer.sources.SaDirectorySource; import com.ebmwebsourcing.petals.services.utils.ServiceProjectRelationUtils; /** * The class in charge of managing all the end-point sources. * <p> * When a source must be added, removed, or is changed, it must be signaled * in this class. The changes will be propagated to listeners. * </p> * * @author Vincent Zurczak - EBM WebSourcing */ public class SourceManager implements IResourceChangeListener { private static final String EXT_WK_SRC_PREF = "petals.service-explorer.external-workspaces"; private static final String SA_FLDR_SRC_PREF = "petals.service-explorer.sa-folders"; private static SourceManager instance = new SourceManager(); private final Set<EndpointSource> sources = new HashSet<EndpointSource>(); private final List<ISourceChangeListener> listeners = new ArrayList<ISourceChangeListener>(); private final CurrentWorkspaceSource currentWorkspaceSource = new CurrentWorkspaceSource(); private boolean restoredSources = false; /** * Constructor. */ private SourceManager() { // Listen to the workbench ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD); // Listen to the workbench // Release resources when the workbench is closed PlatformUI.getWorkbench().addWorkbenchListener(new IWorkbenchListener() { @Override public boolean preShutdown(IWorkbench workbench, boolean forced) { // Do not be notified by workspace changes anymore ResourcesPlugin.getWorkspace().removeResourceChangeListener(SourceManager.this); // Dispose remaining sources for (EndpointSource source : SourceManager.this.sources) source.dispose(); return true; } @Override public void postShutdown(IWorkbench workbench) { // nothing } }); } /** * @return */ public static SourceManager getInstance() { return instance; } /** * Returns the list of end-point sources. * <p> * If sources were stored and not yet restored, they are restored. * </p> * * @return the sources */ public Collection<EndpointSource> getSources() { if (!this.restoredSources) { restoreSavedSources(); this.restoredSources = true; } return Collections.unmodifiableSet(this.sources); } /** * @param source * @return * @see java.util.List#add(java.lang.Object) */ public boolean addSource(EndpointSource source) { boolean result = this.sources.add(source); for (ISourceChangeListener listener : this.listeners) listener.sourceAdded(source); storeSources(); return result; } /** * @param source * @return * @see java.util.List#remove(java.lang.Object) */ public boolean removeSource(EndpointSource source) { boolean result = this.sources.remove(source); for (ISourceChangeListener listener : this.listeners) listener.sourceRemoved(source); source.dispose(); storeSources(); return result; } /** * @param source */ public void updateSource(EndpointSource source) { source.refreshServiceUnitList(); for (ISourceChangeListener listener : this.listeners) listener.sourceChanged(source); } /** * @param listener * @return * @see java.util.List#add(java.lang.Object) */ public boolean registerListener(ISourceChangeListener listener) { return this.listeners.add(listener); } /** * @param listener * @return * @see java.util.List#remove(java.lang.Object) */ public boolean unregisterListener(ISourceChangeListener listener) { return this.listeners.remove(listener); } /** * Restores the saved sources. * <p> * If no source was saved, the workspace source is added. * </p> */ private void restoreSavedSources() { // Workspace this.sources.add(this.currentWorkspaceSource); // External workspaces IPreferenceStore store = PetalsServicesPlugin.getDefault().getPreferenceStore(); String prefs = store.getString(EXT_WK_SRC_PREF); for (String pref : prefs.split(";;")) { if (pref.trim().length() == 0) continue; File f = new File(pref); if (f.exists()) this.sources.add(new ExternalWorkspaceSource(f)); } // SA Folders prefs = store.getString(SA_FLDR_SRC_PREF); for (String pref : prefs.split(";;")) { if (pref.trim().length() == 0) continue; File f = new File(pref); if (f.exists()) this.sources.add(new SaDirectorySource(f, false, false)); } } /** * Saves the sources in the preferences, so that they can be restored at next startup. */ private void storeSources() { StringBuffer extWk = new StringBuffer(); StringBuffer saFldr = new StringBuffer(); for (EndpointSource source : this.sources) { if (source instanceof ExternalWorkspaceSource) { extWk.append(((ExternalWorkspaceSource) source).getDirectory().getAbsolutePath()); extWk.append(";;"); } else if (source instanceof SaDirectorySource) { saFldr.append(((SaDirectorySource) source).getDirectoryOrSaFile().getAbsolutePath()); saFldr.append(";;"); } } IPreferenceStore store = PetalsServicesPlugin.getDefault().getPreferenceStore(); store.setValue(EXT_WK_SRC_PREF, extWk.toString()); store.setValue(SA_FLDR_SRC_PREF, saFldr.toString()); } /** * Handles workspace changes to notify listeners when workspace end-points were modified. */ @Override public void resourceChanged(IResourceChangeEvent event) { try { event.getDelta().accept(new IResourceDeltaVisitor() { boolean stopSearching = false; @Override public boolean visit(IResourceDelta delta) throws CoreException { if (this.stopSearching) return false; IResource resource = delta.getResource(); // Processing projects if (resource instanceof IProject) { IProject project = (IProject) resource; // Project was deleted: update the workspace source and do not go further if (delta.getKind() == IResourceDelta.REMOVED) { updateSource(SourceManager.this.currentWorkspaceSource); this.stopSearching = true; return false; } // Filter the project return project.isAccessible() && ServiceProjectRelationUtils.isSuProject(project); } // Processing files else if (resource instanceof IFile) { if (resource.getName().equals("jbi.xml") || resource.getName().equals(".jbi-metadata")) { updateSource(SourceManager.this.currentWorkspaceSource); this.stopSearching = true; } return false; } return true; } }); } catch (CoreException e) { PetalsServicesPlugin.log(e, IStatus.ERROR); } } }