/*******************************************************************************
* Copyright (c) 2005, 2008 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.ltk.internal.core.refactoring.history;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryListener;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistoryEvent;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin;
/**
* Refactoring history listener which continuously persists the global refactoring history in the
* different history locations.
*
* @author Mohsen Vakilian, nchen - Added the support for serializing three new types of events,
* i.e. canceled, performed and unavailable refactorings to the proper directories
*
* @since 3.2
*/
public final class RefactoringHistorySerializer implements IRefactoringHistoryListener {
/**
* {@inheritDoc}
*/
public void historyNotification(final RefactoringHistoryEvent event) {
Assert.isNotNull(event);
serialize(event, getHistoryFolder(event));
}
private IFileStore getHistoryFolder(final RefactoringHistoryEvent event) {
Assert.isNotNull(event);
switch (event.getEventType()) {
//CODINGSPECTATOR: Added the following three cases for handling the events that CodingSpectator is interested in.
case RefactoringHistoryEvent.CODINGSPECTATOR_REFACTORING_CANCELED:
return getCodingSpectatorFileStore(RefactoringHistoryService.getRefactoringHistoryCanceledFolder());
case RefactoringHistoryEvent.CODINGSPECTATOR_REFACTORING_PERFORMED:
return getCodingSpectatorFileStore(RefactoringHistoryService.getRefactoringHistoryPerformedFolder());
case RefactoringHistoryEvent.CODINGSPECTATOR_REFACTORING_UNAVAILABLE:
return getCodingSpectatorFileStore(RefactoringHistoryService.getRefactoringHistoryUnavailableFolder());
case RefactoringHistoryEvent.ADDED:
case RefactoringHistoryEvent.PUSHED:
case RefactoringHistoryEvent.POPPED:
return getEclipseRefactoringHistoryFileStore();
}
return null;
}
private void serialize(final RefactoringHistoryEvent event, IFileStore store) {
final RefactoringDescriptorProxy proxy= event.getDescriptor();
final long stamp= proxy.getTimeStamp();
if (stamp >= 0) {
final String name= proxy.getProject();
if (name != null && !"".equals(name)) { //$NON-NLS-1$
final IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (project.isAccessible()) {
if (RefactoringHistoryService.hasSharedRefactoringHistory(project)) {
final URI uri= project.getLocationURI();
if (uri != null) {
try {
processHistoryNotification(EFS.getStore(uri).getChild(RefactoringHistoryService.NAME_HISTORY_FOLDER), event, name);
} catch (CoreException exception) {
RefactoringCorePlugin.log(exception);
} finally {
try {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException exception) {
RefactoringCorePlugin.log(exception);
}
}
}
} else {
try {
processHistoryNotification(store.getChild(name), event, name);
} catch (CoreException exception) {
RefactoringCorePlugin.log(exception);
}
}
}
} else {
try {
processHistoryNotification(store.getChild(RefactoringHistoryService.NAME_WORKSPACE_PROJECT), event, name);
} catch (CoreException exception) {
RefactoringCorePlugin.log(exception);
}
}
}
}
//CODINGSPECTATOR: Extracted the method getFileStore().
public static IFileStore getEclipseRefactoringHistoryFileStore() {
return EFS.getLocalFileSystem().getStore(getEclipseRefactoringHistoryFolder());
}
//CODINGSPECTATOR: Extracted this method from getFileStore().
public static IPath getEclipseRefactoringHistoryFolder() {
return RefactoringCorePlugin.getDefault().getStateLocation().append(RefactoringHistoryService.NAME_HISTORY_FOLDER);
}
//CODINGSPECTATOR: The path to where CodingSpectator stores the refactoring histories it captures.
public static IPath getCodingSpectatorRefactoringHistoryFolder() {
return RefactoringCorePlugin.getDefault().getStateLocation().append("codingspectator"); //$NON-NLS-1$
}
//CODINGSPECTATOR: Serialize these events to the CodingSpectator data folder
private IFileStore getCodingSpectatorFileStore(String historyFolder) {
return EFS.getLocalFileSystem().getStore(getCodingSpectatorRefactoringHistoryFolder().append(historyFolder));
}
/**
* Processes the history event.
*
* @param store the file store
* @param event the history event
* @param name the project name, or <code>null</code>
* @throws CoreException if an error occurs
*/
private void processHistoryNotification(final IFileStore store, final RefactoringHistoryEvent event, final String name) throws CoreException {
final RefactoringDescriptorProxy proxy= event.getDescriptor();
final int type= event.getEventType();
final RefactoringHistoryManager manager= new RefactoringHistoryManager(store, name);
final NullProgressMonitor monitor= new NullProgressMonitor();
if (isInsertion(type)) {
final RefactoringDescriptor descriptor= proxy.requestDescriptor(monitor);
if (descriptor != null)
manager.addRefactoringDescriptor(descriptor, type == RefactoringHistoryEvent.ADDED, monitor);
} else
manager.removeRefactoringDescriptors(new RefactoringDescriptorProxy[] { proxy}, monitor, RefactoringCoreMessages.RefactoringHistoryService_updating_history);
}
private boolean isInsertion(final int type) {
//CODINGSPECTATOR: Made the two events of CodingSpectator get inserted to the history file.
if (type == RefactoringHistoryEvent.PUSHED || type == RefactoringHistoryEvent.ADDED || type == RefactoringHistoryEvent.CODINGSPECTATOR_REFACTORING_CANCELED
|| type == RefactoringHistoryEvent.CODINGSPECTATOR_REFACTORING_PERFORMED || type == RefactoringHistoryEvent.CODINGSPECTATOR_REFACTORING_UNAVAILABLE)
return true;
else if (type == RefactoringHistoryEvent.POPPED)
return false;
else
throw new IllegalArgumentException();
}
}