/******************************************************************************* * Copyright (c) 2010 SAP AG. * 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: * Emil Simeonov - initial API and implementation. * Dimitar Donchev - initial API and implementation. * Dimitar Tenev - initial API and implementation. * Nevena Manova - initial API and implementation. * Georgi Konstantinov - initial API and implementation. *******************************************************************************/ package org.eclipse.wst.sse.sieditor.ui.v2.resources; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IFile; 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.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.wst.sse.sieditor.core.common.Logger; import org.eclipse.wst.sse.sieditor.ui.AbstractEditorWithSourcePage; import org.eclipse.wst.sse.sieditor.ui.Activator; /** * The purpose of this class is to provide refresh functionality for file editor * input editors * * Two types of events are handled: 1. Project close 2. Change * of the edited resource from outside */ public class ResourceChangeHandler implements IResourceChangeListener, IResourceDeltaVisitor { private static ResourceChangeHandler resourceChangeHandler; private Set<AbstractEditorWithSourcePage> registeredEditors = new HashSet<AbstractEditorWithSourcePage>(); public static ResourceChangeHandler getInstance() { if (resourceChangeHandler == null) { resourceChangeHandler = new ResourceChangeHandler(); } return resourceChangeHandler; } private ResourceChangeHandler() { ResourcesPlugin.getWorkspace().addResourceChangeListener(this); } public void registerEditor(AbstractEditorWithSourcePage editor) { if (editor.getEditorInput() instanceof IFileEditorInput) { registeredEditors.add(editor); } } public void deregisterEditor(AbstractEditorWithSourcePage editor) { registeredEditors.remove(editor); } public void resourceChanged(final IResourceChangeEvent event) { if (event.getType() == IResourceChangeEvent.PRE_CLOSE) { Display.getDefault().asyncExec(new Runnable() { public void run() { for (AbstractEditorWithSourcePage editor : registeredEditors) { final IWorkbenchPage[] pages = editor.getSite().getWorkbenchWindow().getPages(); for (int i = 0; i < pages.length; i++) { final IEditorInput input = editor.getEditorInput(); if (((FileEditorInput) input).getFile().getProject().equals(event.getResource())) { final IEditorPart editorPart = pages[i].findEditor(input); if (editorPart != null) { pages[i].closeEditor(editorPart, true); } } } } } }); return; } if (event.getType() == IResourceChangeEvent.POST_CHANGE) { try { event.getDelta().accept(this); } catch (CoreException e) { Logger.log(Activator.PLUGIN_ID, IStatus.ERROR, "Resource changed visitor failed to accept delta.", e); //$NON-NLS-1$ } } } public boolean visit(IResourceDelta delta) throws CoreException { final int flags = delta.getFlags(); // see ResourceFileBuffer.resourceChanged for more resource change types if (delta.getKind() == IResourceDelta.REMOVED) { if ((IResourceDelta.MOVED_TO & flags) != 0) { handleResourceMoved(delta.getResource(), delta.getMovedToPath()); return true; } else { return false; } } // if the resource content nor markers have changed - proceed with it's // children if ((flags & (IResourceDelta.CONTENT | IResourceDelta.MARKERS)) == 0) { return true; } if ((flags & IResourceDelta.MARKERS) != 0) { return true; } final IResource resource = delta.getResource(); // if resource is not an IFile - proceed with children if (!(resource instanceof IFile)) { return true; } Set<AbstractEditorWithSourcePage> foundEditors = findEditors((IFile) resource); if (foundEditors.size() == 0) { return true; } if ((flags & IResourceDelta.CONTENT) != 0) { final List<AbstractEditorWithSourcePage> editorsToRefresh = new ArrayList<AbstractEditorWithSourcePage>(); for (AbstractEditorWithSourcePage editor : foundEditors) { if (editor.isSaving()) { continue; } editorsToRefresh.add(editor); } Display.getDefault().asyncExec(new Runnable() { @Override public void run() { for (AbstractEditorWithSourcePage editor : editorsToRefresh) { if (!editor.isDirty()) { editor.revertContentsToSavedVersion(); } } } }); } return false; } private void handleResourceMoved(IResource resource, IPath newPath) { if (resource instanceof IFile) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IFile newFile = workspace.getRoot().getFile(newPath); final FileEditorInput newInput = new FileEditorInput(newFile); Set<AbstractEditorWithSourcePage> editors = findEditors((IFile) resource); for (final AbstractEditorWithSourcePage editor : editors) { editor.reloadModel(newInput); } } } private Set<AbstractEditorWithSourcePage> findEditors(IFile file) { Set<AbstractEditorWithSourcePage> result = new HashSet<AbstractEditorWithSourcePage>(); for (AbstractEditorWithSourcePage editor : registeredEditors) { if (file.equals(((IFileEditorInput) editor.getEditorInput()).getFile())) { result.add(editor); } } return result; } }