package org.eclipse.ltk.internal.core.refactoring.history;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.ibm.icu.text.DateFormat;
import org.xml.sax.InputSource;
import org.eclipse.core.commands.operations.IOperationHistoryListener;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.commands.operations.TriggeredOperations;
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.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.resources.IFolder;
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.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
import org.eclipse.ltk.core.refactoring.IRefactoringCoreStatusCodes;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
import org.eclipse.ltk.core.refactoring.RefactoringSessionDescriptor;
import org.eclipse.ltk.core.refactoring.history.IRefactoringExecutionListener;
import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryListener;
import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService;
import org.eclipse.ltk.core.refactoring.history.RefactoringExecutionEvent;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistoryEvent;
import org.eclipse.ltk.internal.core.refactoring.IRefactoringSerializationConstants;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin;
import org.eclipse.ltk.internal.core.refactoring.RefactoringPreferenceConstants;
import org.eclipse.ltk.internal.core.refactoring.RefactoringSessionReader;
import org.eclipse.ltk.internal.core.refactoring.UndoableOperation2ChangeAdapter;
public final class RefactoringHistoryService implements IRefactoringHistoryService {
private static final class NullRefactoringHistory extends RefactoringHistory {
private static final RefactoringDescriptorProxy[] NO_PROXIES= {};
@Override
public RefactoringDescriptorProxy[] getDescriptors() {
return NO_PROXIES;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public RefactoringHistory removeAll(final RefactoringHistory history) {
return this;
}
}
private static RefactoringHistoryService fInstance= null;
public static final String NAME_HISTORY_FILE= "refactorings.history";
public static final String NAME_HISTORY_FOLDER= ".refactorings";
public static final String NAME_INDEX_FILE= "refactorings.index";
public static final String NAME_WORKSPACE_PROJECT= ".workspace";
private static final NullRefactoringHistory NO_HISTORY= new NullRefactoringHistory();
private static void filterRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, final Set<RefactoringDescriptorProxy> set, final boolean resolve, final int flags, final IProgressMonitor monitor) {
Assert.isTrue(flags > RefactoringDescriptor.NONE);
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_retrieving_history, proxies.length);
for (RefactoringDescriptorProxy proxy : proxies) {
final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 1));
if (descriptor != null) {
final int filter= descriptor.getFlags();
if ((filter | flags) == filter) {
if (resolve) {
set.add(new RefactoringDescriptorProxyAdapter(descriptor));
} else {
set.add(proxy);
}
}
}
}
} finally {
monitor.done();
}
}
public static RefactoringHistoryService getInstance() {
if (fInstance == null)
fInstance= new RefactoringHistoryService();
return fInstance;
}
public static boolean hasSharedRefactoringHistory(final IProject project) {
Assert.isNotNull(project);
final IScopeContext[] contexts= new IScopeContext[] { new ProjectScope(project)};
final String preference= Platform.getPreferencesService().getString(RefactoringCorePlugin.getPluginId(), RefactoringPreferenceConstants.PREFERENCE_SHARED_REFACTORING_HISTORY, Boolean.FALSE.toString(), contexts);
if (preference != null)
return Boolean.valueOf(preference).booleanValue();
return false;
}
public static void setSharedRefactoringHistory(final IProject project, final boolean enable, IProgressMonitor monitor) throws CoreException {
Assert.isNotNull(project);
Assert.isTrue(project.isAccessible());
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask("", 300);
final String name= project.getName();
final URI uri= project.getLocationURI();
if (uri != null) {
try {
final IFileStore history= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation()).getChild(NAME_HISTORY_FOLDER);
if (enable) {
final IFileStore source= history.getChild(name);
if (source.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists()) {
IFileStore destination= EFS.getStore(uri).getChild(NAME_HISTORY_FOLDER);
if (destination.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists())
destination.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
destination.mkdir(EFS.NONE, new SubProgressMonitor(monitor, 20));
source.copy(destination, EFS.OVERWRITE, new SubProgressMonitor(monitor, 20));
source.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
}
} else {
final IFileStore source= EFS.getStore(uri).getChild(NAME_HISTORY_FOLDER);
if (source.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists()) {
IFileStore destination= history.getChild(name);
if (destination.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists())
destination.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
destination.mkdir(EFS.NONE, new SubProgressMonitor(monitor, 20));
source.copy(destination, EFS.OVERWRITE, new SubProgressMonitor(monitor, 20));
source.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
}
}
} finally {
if (enable)
project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 30));
else {
final IFolder folder= project.getFolder(NAME_HISTORY_FOLDER);
if (folder.exists())
folder.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 30));
}
}
}
} finally {
monitor.done();
}
}
private final ListenerList<IRefactoringExecutionListener> fExecutionListeners= new ListenerList<>(ListenerList.EQUALITY);
private final ListenerList<IRefactoringHistoryListener> fHistoryListeners= new ListenerList<>(ListenerList.EQUALITY);
private IOperationHistoryListener fOperationListener= null;
private long fOverrideTimeStamp= -1;
private int fReferenceCount= 0;
private IResourceChangeListener fResourceListener= null;
private static final int MAX_MANAGERS= 2;
private final Map<IFileStore, RefactoringHistoryManager> fManagerCache= new LinkedHashMap<IFileStore, RefactoringHistoryManager>(MAX_MANAGERS, 0.75f, true) {
private static final long serialVersionUID= 1L;
@Override
protected boolean removeEldestEntry(Map.Entry<IFileStore, RefactoringHistoryManager> entry) {
return size() > MAX_MANAGERS;
}
};
private RefactoringHistoryService() {
}
@Override
public void addExecutionListener(final IRefactoringExecutionListener listener) {
Assert.isNotNull(listener);
fExecutionListeners.add(listener);
}
@Override
public void addHistoryListener(final IRefactoringHistoryListener listener) {
Assert.isNotNull(listener);
fHistoryListeners.add(listener);
}
public void addRefactoringDescriptor(final RefactoringDescriptorProxy proxy, IProgressMonitor monitor) {
Assert.isNotNull(proxy);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.ADDED);
} finally {
monitor.done();
}
}
@Override
public void connect() {
fReferenceCount++;
if (fReferenceCount == 1) {
fOperationListener= new IOperationHistoryListener() {
@Override
public void historyNotification(final OperationHistoryEvent event) {
performHistoryNotification(event);
}
};
OperationHistoryFactory.getOperationHistory().addOperationHistoryListener(fOperationListener);
fResourceListener= new IResourceChangeListener() {
@Override
public void resourceChanged(final IResourceChangeEvent event) {
peformResourceChanged(event);
}
};
ResourcesPlugin.getWorkspace().addResourceChangeListener(fResourceListener, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.POST_CHANGE);
}
}
public void deleteRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, IProgressMonitor monitor) throws CoreException {
Assert.isNotNull(proxies);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, proxies.length + 300);
final Map<String, Collection<RefactoringDescriptorProxy>> projects= new HashMap<>();
for (RefactoringDescriptorProxy proxy : proxies) {
String project= proxy.getProject();
if (project == null || "".equals(project))
project= RefactoringHistoryService.NAME_WORKSPACE_PROJECT;
Collection<RefactoringDescriptorProxy> collection= projects.get(project);
if (collection == null) {
collection= new ArrayList<>();
projects.put(project, collection);
}
collection.add(proxy);
monitor.worked(1);
}
final SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 300);
try {
final Set<Entry<String, Collection<RefactoringDescriptorProxy>>> entries= projects.entrySet();
subMonitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, entries.size());
for (final Iterator<Entry<String, Collection<RefactoringDescriptorProxy>>> iterator= entries.iterator(); iterator.hasNext();) {
final Entry<String, Collection<RefactoringDescriptorProxy>> entry= iterator.next();
final Collection<RefactoringDescriptorProxy> collection= entry.getValue();
String project= entry.getKey();
if (project.equals(RefactoringHistoryService.NAME_WORKSPACE_PROJECT))
project= null;
final RefactoringHistoryManager manager= getManager(project);
if (manager != null)
manager.removeRefactoringDescriptors(collection.toArray(new RefactoringDescriptorProxy[collection.size()]), new SubProgressMonitor(subMonitor, 1), RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings);
else
subMonitor.worked(1);
}
} finally {
subMonitor.done();
}
} finally {
monitor.done();
}
}
public void deleteRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, final IRefactoringDescriptorDeleteQuery query, IProgressMonitor monitor) throws CoreException {
Assert.isNotNull(proxies);
Assert.isNotNull(query);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, proxies.length + 300);
final Set<RefactoringDescriptorProxy> set= new HashSet<>(proxies.length);
for (RefactoringDescriptorProxy proxy : proxies) {
if (query.proceed(proxy).isOK()) {
set.add(proxy);
}
monitor.worked(1);
}
if (!set.isEmpty()) {
final RefactoringDescriptorProxy[] delete= set.toArray(new RefactoringDescriptorProxy[set.size()]);
deleteRefactoringDescriptors(delete, new SubProgressMonitor(monitor, 300));
for (RefactoringDescriptorProxy d : delete) {
fireRefactoringHistoryEvent(d, RefactoringHistoryEvent.DELETED);
}
}
} finally {
monitor.done();
}
}
public void deleteRefactoringHistory(final IProject project, IProgressMonitor monitor) throws CoreException {
Assert.isNotNull(project);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, 100);
final String name= project.getName();
final IFileStore stateStore= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation());
if (name.equals(NAME_WORKSPACE_PROJECT)) {
final IFileStore metaStore= stateStore.getChild(NAME_HISTORY_FOLDER).getChild(name);
metaStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 100));
} else {
final URI uri= project.getLocationURI();
if (uri != null && project.isAccessible()) {
try {
final IFileStore metaStore= stateStore.getChild(NAME_HISTORY_FOLDER).getChild(name);
metaStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
final IFileStore projectStore= EFS.getStore(uri).getChild(NAME_HISTORY_FOLDER);
projectStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
} finally {
project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 60));
}
}
}
} finally {
monitor.done();
}
}
@Override
public void disconnect() {
if (fReferenceCount > 0) {
fManagerCache.clear();
fReferenceCount--;
}
if (fReferenceCount == 0) {
if (fOperationListener != null)
OperationHistoryFactory.getOperationHistory().removeOperationHistoryListener(fOperationListener);
if (fResourceListener != null)
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fResourceListener);
fOperationListener= null;
}
}
private void fireRefactoringExecutionEvent(final RefactoringDescriptorProxy proxy, final int eventType) {
Assert.isNotNull(proxy);
for (final IRefactoringExecutionListener listener : fExecutionListeners) {
SafeRunner.run(new ISafeRunnable() {
@Override
public void handleException(final Throwable throwable) {
RefactoringCorePlugin.log(throwable);
}
@Override
public void run() throws Exception {
listener.executionNotification(new RefactoringExecutionEvent(RefactoringHistoryService.this, eventType, proxy));
}
});
}
}
private void fireRefactoringHistoryEvent(final RefactoringDescriptorProxy proxy, final int eventType) {
Assert.isNotNull(proxy);
for (final IRefactoringHistoryListener listener : fHistoryListeners) {
SafeRunner.run(new ISafeRunnable() {
@Override
public void handleException(final Throwable throwable) {
RefactoringCorePlugin.log(throwable);
}
@Override
public void run() throws Exception {
listener.historyNotification(new RefactoringHistoryEvent(RefactoringHistoryService.this, eventType, proxy));
}
});
}
}
private boolean checkDescriptor(RefactoringDescriptor descriptor, IUndoableOperation operation) {
Assert.isNotNull(descriptor);
try {
final Map<String, String> arguments= RefactoringHistoryManager.getArgumentMap(descriptor);
if (arguments != null)
RefactoringHistoryManager.checkArgumentMap(arguments);
} catch (CoreException exception) {
final IStatus status= exception.getStatus();
if (status.getCode() == IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR) {
final String time= DateFormat.getDateTimeInstance().format(new Date(descriptor.getTimeStamp()));
final String message= "The refactoring executed at " + time + " contributed a refactoring descriptor with invalid format:";
final IStatus comment= new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), descriptor.getComment());
RefactoringCorePlugin.log(new MultiStatus(RefactoringCorePlugin.getPluginId(), 0, new IStatus[] { comment}, message, null));
}
RefactoringCorePlugin.log(exception);
if (operation instanceof TriggeredOperations) {
operation= ((TriggeredOperations) operation).getTriggeringOperation();
}
if (operation instanceof UndoableOperation2ChangeAdapter) {
((UndoableOperation2ChangeAdapter) operation).setChangeDescriptor(null);
}
return false;
}
return true;
}
@Override
public RefactoringHistory getProjectHistory(final IProject project, IProgressMonitor monitor) {
return getProjectHistory(project, 0, Long.MAX_VALUE, RefactoringDescriptor.NONE, monitor);
}
@Override
public RefactoringHistory getProjectHistory(final IProject project, final long start, final long end, final int flags, IProgressMonitor monitor) {
Assert.isNotNull(project);
Assert.isTrue(project.exists());
Assert.isTrue(start >= 0);
Assert.isTrue(end >= 0);
Assert.isTrue(flags >= RefactoringDescriptor.NONE);
if (project.isOpen()) {
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_retrieving_history, 120);
final String name= project.getName();
final RefactoringHistoryManager manager= getManager(name);
if (manager != null) {
RefactoringHistory history= manager.readRefactoringHistory(start, end, new SubProgressMonitor(monitor, 20));
if (flags > RefactoringDescriptor.NONE) {
final Set<RefactoringDescriptorProxy> set= new HashSet<>();
filterRefactoringDescriptors(history.getDescriptors(), set, false, flags, new SubProgressMonitor(monitor, 100));
history= new RefactoringHistoryImplementation(set.toArray(new RefactoringDescriptorProxy[set.size()]));
}
return history;
}
} finally {
monitor.done();
}
}
return NO_HISTORY;
}
@Override
public RefactoringHistory getRefactoringHistory(final IProject[] projects, final IProgressMonitor monitor) {
return getRefactoringHistory(projects, 0, Long.MAX_VALUE, RefactoringDescriptor.NONE, monitor);
}
@Override
public RefactoringHistory getRefactoringHistory(final IProject[] projects, final long start, final long end, final int flags, IProgressMonitor monitor) {
Assert.isNotNull(projects);
Assert.isTrue(start >= 0);
Assert.isTrue(end >= start);
Assert.isTrue(flags >= RefactoringDescriptor.NONE);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_retrieving_history, 3 * projects.length);
final Set<RefactoringDescriptorProxy> set= new HashSet<>();
if (flags > RefactoringDescriptor.NONE) {
for (IProject project : projects) {
if (project.isAccessible()) {
final RefactoringDescriptorProxy[] proxies= getProjectHistory(project, start, end, flags, new SubProgressMonitor(monitor, 1)).getDescriptors();
filterRefactoringDescriptors(proxies, set, false, flags, new SubProgressMonitor(monitor, 2));
}
}
} else {
for (IProject project : projects) {
if (project.isAccessible()) {
final RefactoringDescriptorProxy[] proxies= getProjectHistory(project, start, end, RefactoringDescriptor.NONE, new SubProgressMonitor(monitor, 3)).getDescriptors();
set.addAll(Arrays.asList(proxies));
}
}
}
final RefactoringDescriptorProxy[] proxies= new RefactoringDescriptorProxy[set.size()];
set.toArray(proxies);
return new RefactoringHistoryImplementation(proxies);
} finally {
monitor.done();
}
}
@Override
public RefactoringHistory getWorkspaceHistory(IProgressMonitor monitor) {
return getWorkspaceHistory(0, Long.MAX_VALUE, monitor);
}
@Override
public RefactoringHistory getWorkspaceHistory(final long start, final long end, IProgressMonitor monitor) {
return getRefactoringHistory(ResourcesPlugin.getWorkspace().getRoot().getProjects(), start, end, RefactoringDescriptor.NONE, monitor);
}
public RefactoringDescriptorProxy[] readRefactoringDescriptorProxies(final InputStream stream) throws CoreException {
Assert.isNotNull(stream);
try {
return RefactoringHistoryManager.readRefactoringDescriptorProxies(stream, null, 0, Long.MAX_VALUE);
} catch (IOException exception) {
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), 0, exception.getLocalizedMessage(), null));
}
}
@Override
public RefactoringHistory readRefactoringHistory(final InputStream stream, final int flags) throws CoreException {
Assert.isNotNull(stream);
Assert.isTrue(flags >= RefactoringDescriptor.NONE);
final List<RefactoringDescriptor> list= new ArrayList<>();
final RefactoringSessionDescriptor descriptor= new RefactoringSessionReader(false, null).readSession(new InputSource(stream));
if (descriptor != null) {
final RefactoringDescriptor[] descriptors= descriptor.getRefactorings();
if (flags > RefactoringDescriptor.NONE) {
for (RefactoringDescriptor d : descriptors) {
final int current= d.getFlags();
if ((current | flags) == current) {
list.add(d);
}
}
} else
list.addAll(Arrays.asList(descriptors));
}
final RefactoringDescriptorProxy[] proxies= new RefactoringDescriptorProxy[list.size()];
for (int index= 0; index < list.size(); index++)
proxies[index]= new RefactoringDescriptorProxyAdapter(list.get(index));
return new RefactoringHistoryImplementation(proxies);
}
@Override
public void removeExecutionListener(final IRefactoringExecutionListener listener) {
Assert.isNotNull(listener);
fExecutionListeners.remove(listener);
}
@Override
public void removeHistoryListener(final IRefactoringHistoryListener listener) {
Assert.isNotNull(listener);
fHistoryListeners.remove(listener);
}
public RefactoringDescriptor requestDescriptor(final RefactoringDescriptorProxy proxy, IProgressMonitor monitor) {
Assert.isNotNull(proxy);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
final RefactoringHistoryManager manager= getManager(proxy.getProject());
if (manager != null)
return manager.requestDescriptor(proxy, monitor);
} finally {
monitor.done();
}
return null;
}
public void setOverrideTimeStamp(final long stamp) {
Assert.isTrue(stamp == -1 || stamp >= 0);
fOverrideTimeStamp= stamp;
}
@Override
public void writeRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, final OutputStream stream, final int flags, final boolean time, IProgressMonitor monitor) throws CoreException {
Assert.isNotNull(proxies);
Assert.isNotNull(stream);
Assert.isTrue(flags >= RefactoringDescriptor.NONE);
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask("", 100 * proxies.length);
connect();
final List<RefactoringDescriptor> list= new ArrayList<>(proxies.length);
for (RefactoringDescriptorProxy proxy : proxies) {
final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 100));
if (descriptor != null) {
final int current= descriptor.getFlags();
if ((current | flags) == current)
list.add(descriptor);
}
}
final RefactoringDescriptor[] descriptors= new RefactoringDescriptor[list.size()];
list.toArray(descriptors);
RefactoringHistoryManager.writeRefactoringSession(stream, new RefactoringSessionDescriptor(descriptors, IRefactoringSerializationConstants.CURRENT_VERSION, null), time);
} finally {
disconnect();
}
}
@Override
public void writeRefactoringSession(final RefactoringSessionDescriptor descriptor, final OutputStream stream, final boolean time) throws CoreException {
Assert.isNotNull(descriptor);
Assert.isNotNull(stream);
RefactoringHistoryManager.writeRefactoringSession(stream, descriptor, time);
}
private void moveHistory(final IProject oldProject, final IProject newProject, final IProgressMonitor monitor) {
try {
monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_updating_history, 60);
final IFileStore historyStore= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation()).getChild(NAME_HISTORY_FOLDER);
final String oldName= oldProject.getName();
final String newName= newProject.getName();
final IFileStore oldStore= historyStore.getChild(oldName);
if (oldStore.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).exists()) {
final IFileStore newStore= historyStore.getChild(newName);
if (newStore.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).exists())
newStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
oldStore.move(newStore, EFS.OVERWRITE, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
}
} catch (CoreException exception) {
RefactoringCorePlugin.log(exception);
} finally {
monitor.done();
}
}
private void peformResourceChanged(final IResourceChangeEvent event) {
final int type= event.getType();
if ((type & IResourceChangeEvent.POST_CHANGE) != 0) {
final IResourceDelta delta= event.getDelta();
if (delta != null) {
final IResourceDelta[] deltas= delta.getAffectedChildren();
if (deltas.length == 2) {
final IPath toPath= deltas[0].getMovedToPath();
final IPath fromPath= deltas[1].getMovedFromPath();
if (fromPath != null && toPath != null) {
final IResource oldResource= deltas[0].getResource();
final IResource newResource= deltas[1].getResource();
if (oldResource.getType() == IResource.PROJECT && newResource.getType() == IResource.PROJECT)
moveHistory((IProject) oldResource, (IProject) newResource, new NullProgressMonitor());
} else {
if (deltas[0].getKind() == IResourceDelta.ADDED && deltas[1].getKind() == IResourceDelta.REMOVED) {
final IResource newResource= deltas[0].getResource();
final IResource oldResource= deltas[1].getResource();
if (oldResource.getType() == IResource.PROJECT && newResource.getType() == IResource.PROJECT)
moveHistory((IProject) oldResource, (IProject) newResource, new NullProgressMonitor());
}
}
}
}
}
}
private RefactoringDescriptor getRefactoringDescriptor(IUndoableOperation operation) {
if (operation instanceof TriggeredOperations) {
operation= ((TriggeredOperations) operation).getTriggeringOperation();
}
if (operation instanceof UndoableOperation2ChangeAdapter) {
ChangeDescriptor changeDescriptor= ((UndoableOperation2ChangeAdapter) operation).getChangeDescriptor();
if (changeDescriptor instanceof RefactoringChangeDescriptor) {
return ((RefactoringChangeDescriptor) changeDescriptor).getRefactoringDescriptor();
}
}
return null;
}
private void performHistoryNotification(final OperationHistoryEvent event) {
RefactoringDescriptor descriptor= getRefactoringDescriptor(event.getOperation());
if (descriptor != null) {
RefactoringDescriptorProxyAdapter proxy= new RefactoringDescriptorProxyAdapter(descriptor);
switch (event.getEventType()) {
case OperationHistoryEvent.ABOUT_TO_EXECUTE: {
if (checkDescriptor(descriptor, event.getOperation())) {
fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.ABOUT_TO_PERFORM);
}
break;
}
case OperationHistoryEvent.DONE: {
if (!RefactoringDescriptor.ID_UNKNOWN.equals(descriptor.getID())) {
long timeStamp= fOverrideTimeStamp >= 0 ? fOverrideTimeStamp : System.currentTimeMillis();
descriptor.setTimeStamp(timeStamp);
}
fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.PUSHED);
fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.PERFORMED);
break;
}
case OperationHistoryEvent.ABOUT_TO_UNDO: {
fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.ABOUT_TO_UNDO);
break;
}
case OperationHistoryEvent.UNDONE: {
fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.POPPED);
fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.UNDONE);
break;
}
case OperationHistoryEvent.ABOUT_TO_REDO: {
fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.ABOUT_TO_REDO);
break;
}
case OperationHistoryEvent.REDONE: {
fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.PUSHED);
fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.REDONE);
break;
}
}
}
}
private RefactoringHistoryManager getManager(final String name) {
final IFileStore store= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation()).getChild(NAME_HISTORY_FOLDER);
if (name != null && !"".equals(name)) {
try {
final IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (project.isAccessible()) {
if (hasSharedRefactoringHistory(project)) {
final URI uri= project.getLocationURI();
if (uri != null)
return getManager(EFS.getStore(uri).getChild(RefactoringHistoryService.NAME_HISTORY_FOLDER), name);
} else
return getManager(store.getChild(name), name);
}
} catch (CoreException exception) {
}
} else
return getManager(store.getChild(NAME_WORKSPACE_PROJECT), null);
return null;
}
private RefactoringHistoryManager getManager(final IFileStore store, final String name) {
Assert.isNotNull(store);
RefactoringHistoryManager manager= fManagerCache.get(store);
if (manager == null) {
manager= new RefactoringHistoryManager(store, name);
fManagerCache.put(store, manager);
}
return manager;
}
}