/*******************************************************************************
* Copyright (c) 2006, 2007 Red Hat Inc. 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:
* Kyu Lee <klee@redhat.com> - initial API and implementation
* Jeff Johnston <jjohnstn@redhat.com> - add removed files support
*******************************************************************************/
package org.eclipse.linuxtools.internal.changelog.core.actions;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.linuxtools.internal.changelog.core.ChangeLogExtensionManager;
import org.eclipse.linuxtools.internal.changelog.core.ChangelogPlugin;
import org.eclipse.linuxtools.internal.changelog.core.Messages;
import org.eclipse.team.ui.synchronize.SyncInfoCompareInput;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
public abstract class ChangeLogAction extends Action {
protected ChangeLogExtensionManager extensionManager = null;
// Preference variables
protected String pref_AuthorName;
protected String pref_AuthorEmail;
protected String pref_ChangeLogName = "ChangeLog"; // $NON-NLS-1$
protected String pref_Formatter;
// set selection here
// selection can be either IEditorPart / IProject / IStructuredSelection
// IEditorPart and IProject will be adapted to IStructuredSelection.
public ChangeLogAction() {
extensionManager = ChangeLogExtensionManager.getExtensionManager();
}
protected void reportErr(String msg, Exception e) {
ChangelogPlugin.getDefault().getLog().log(
new Status(IStatus.ERROR, ChangelogPlugin.PLUGIN_ID, IStatus.ERROR, msg, e));
}
private IWorkspaceRoot getWorkspaceRoot() {
return ResourcesPlugin.getWorkspace().getRoot();
}
protected IEditorPart openEditor(IFile diskresource) {
IWorkbench ws = PlatformUI.getWorkbench();
try {
return org.eclipse.ui.ide.IDE.openEditor(ws
.getActiveWorkbenchWindow().getActivePage(), diskresource,
true);
} catch (PartInitException e) {
e.printStackTrace();
return null;
}
}
protected IFile createChangeLog(IPath changelog) {
IWorkspaceRoot myWorkspaceRoot = getWorkspaceRoot();
IWorkbench ws = PlatformUI.getWorkbench();
final IFile changelog_File = myWorkspaceRoot.getFile(changelog);
final InputStream initialContents = new ByteArrayInputStream(
new byte[0]);
WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
@Override
public void execute(IProgressMonitor monitor) throws CoreException {
try {
monitor.beginTask(Messages.getString("ChangeLog.AddingChangeLog"), 2000); //$NON-NLS-1$
changelog_File.create(initialContents, false, monitor);
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
} finally {
monitor.done();
}
}
};
try {
new ProgressMonitorDialog(ws.getActiveWorkbenchWindow().getShell())
.run(true, true, operation);
} catch (InterruptedException e) {
reportErr(Messages.getString("ChangeLog.ErrInterrupted"), e); // $NON-NLS-1$
return null;
} catch (InvocationTargetException e) {
reportErr(Messages.getString("ChangeLog.ErrInvocation"), e); // $NON-NLS-1$
return null;
}
// FIXME: we should put this refreshLocal call into a thread (filed as bug #256180)
try {
IContainer changelogContainer = myWorkspaceRoot.getContainerForLocation(changelog);
if (changelogContainer != null)
changelogContainer.refreshLocal(2, null);
} catch (CoreException e) {
reportErr(Messages.getString("ChangeLog.ErrRefresh"), e); // $NON-NLS-1$
return null;
}
return changelog_File;
}
protected IEditorPart askChangeLogLocation(String editorLoc) {
IWorkbench ws = PlatformUI.getWorkbench();
IWorkspaceRoot myWorkspaceRoot = getWorkspaceRoot();
IResource given_resource = myWorkspaceRoot.findMember(editorLoc);
if (given_resource == null)
return null;
ChangeLogContainerSelectionDialog dialog = new ChangeLogContainerSelectionDialog(ws
.getActiveWorkbenchWindow().getShell(), given_resource
.getParent(), false, Messages
.getString("AddAction.str_ChangeLog_Location")); //$NON-NLS-1$
dialog.showClosedProjects(false);
dialog.open();
Object[] result = dialog.getResult();
if (result == null)
return null;
final IPath result_path = new Path(result[0]
+ System.getProperty("file.separator") + pref_ChangeLogName); //$NON-NLS-1$ //$NON-NLS-2$
IFile newChangeLog = createChangeLog(result_path);
return openEditor(newChangeLog);
}
protected IEditorPart getChangelog(String currentEditorloc) {
IFile changelog = getChangelogFile(currentEditorloc);
return changelog != null ? openEditor(changelog) : null;
}
protected IFile getChangelogFile(String currentEditorloc) {
// Scenario 1: The Changelog is in in the current project file
IWorkspaceRoot myWorkspaceRoot = getWorkspaceRoot();
IResource given_resource = myWorkspaceRoot.findMember(currentEditorloc);
if (given_resource != null) {
IResource parent_dec = given_resource;
while (parent_dec != null) {
String parent_node = parent_dec.getFullPath()
.removeLastSegments(1).toOSString();
parent_node = parent_node
+ System.getProperty("file.separator") + pref_ChangeLogName; //$NON-NLS-1$
IResource change_log_res = myWorkspaceRoot
.findMember(parent_node);
if (change_log_res != null) {
IProject proj_loc = given_resource.getProject();
IPath modified_changelog_path = change_log_res
.getFullPath().removeFirstSegments(1);
IFile change_log_file = proj_loc
.getFile(modified_changelog_path);
return change_log_file;
}
parent_dec = parent_dec.getParent();
if (parent_dec == null) {
break;
}
}
}
return null;
}
/**
* Find the ChangeLog for a file that is being removed. It can't be found and
* it is possible that the directory it is in has also been removed.
*
* @param path Path of removed file
* @return ChangeLog editor part that must be used to report removed file
*/
protected IEditorPart getChangelogForRemovePath(IPath path) {
IResource parent_resource = null;
IPath loc_path = path;
// Look from current loc up to find first folder that is still existing
IWorkspaceRoot myWorkspaceRoot = getWorkspaceRoot();
while (loc_path.segmentCount() > 0) {
parent_resource = myWorkspaceRoot.findMember(loc_path);
if (parent_resource != null)
break;
loc_path = loc_path.removeLastSegments(1);
}
if (parent_resource != null) {
IResource parent_dec = parent_resource;
while (parent_dec != null) {
String parent_node = parent_dec.getFullPath().toOSString();
parent_node = parent_node
+ System.getProperty("file.separator") + pref_ChangeLogName; //$NON-NLS-1$
IResource change_log_res = myWorkspaceRoot
.findMember(parent_node);
if (change_log_res != null) {
IProject proj_loc = parent_resource.getProject();
IPath modified_changelog_path = change_log_res
.getFullPath().removeFirstSegments(1);
IFile change_log_file = proj_loc
.getFile(modified_changelog_path);
return openEditor(change_log_file);
}
parent_dec = parent_dec.getParent();
if (parent_dec == null) {
break;
}
}
}
return null;
}
private IFile getDocumentIFile(IEditorPart currentEditor) {
IEditorInput cc = currentEditor.getEditorInput();
if (cc instanceof IFileEditorInput) {
return ((IFileEditorInput) cc).getFile();
}
return null;
}
protected String getDocumentLocation(IEditorPart currentEditor,
boolean appendRoot) {
IFile loc = getDocumentIFile(currentEditor);
IEditorInput cc = null;
String WorkspaceRoot;
IWorkspaceRoot myWorkspaceRoot = getWorkspaceRoot();
WorkspaceRoot = myWorkspaceRoot.getLocation().toOSString();
if (currentEditor instanceof MultiPageEditorPart) {
Object ed = ((MultiPageEditorPart) currentEditor).getSelectedPage();
if (ed instanceof IEditorPart)
cc = ((IEditorPart) ed).getEditorInput();
if (cc instanceof FileEditorInput)
return (appendRoot) ? WorkspaceRoot + ((FileEditorInput) cc).getFile().getFullPath().toOSString() :
((FileEditorInput) cc).getFile().getFullPath().toOSString();
}
cc = currentEditor.getEditorInput();
if (cc == null)
return "";
if ((cc instanceof SyncInfoCompareInput)
|| (cc instanceof CompareEditorInput)) {
CompareEditorInput test = (CompareEditorInput) cc;
if (test.getCompareResult() == null) {
return "";
} else if (test.getCompareResult() instanceof ICompareInput) {
ITypedElement leftCompare = ((ICompareInput) test.getCompareResult())
.getLeft();
if (leftCompare instanceof IResourceProvider){
String localPath = ((IResourceProvider)leftCompare).getResource().getFullPath().toString();
if (appendRoot) {
return WorkspaceRoot + localPath;
}
return localPath;
}
} else {
if (appendRoot)
return WorkspaceRoot + test.getCompareResult().toString();
return test.getCompareResult().toString();
}
} else if (cc instanceof FileStoreEditorInput) {
return ((FileStoreEditorInput)cc).getName();
}
if (appendRoot) {
return WorkspaceRoot + loc.getFullPath().toOSString();
} else if (loc != null) {
return loc.getFullPath().toOSString();
} else {
return "";
}
}
protected void loadPreferences() {
IPreferenceStore store = ChangelogPlugin.getDefault()
.getPreferenceStore();
pref_AuthorName = store.getString("IChangeLogConstants.AUTHOR_NAME"); //$NON-NLS-1$
pref_AuthorEmail = store.getString("IChangeLogConstants.AUTHOR_EMAIL"); //$NON-NLS-1$
pref_Formatter = store
.getString("IChangeLogConstants.DEFAULT_FORMATTER"); // $NON-NLS-1$
}
}