/**
* Copyright (c) 2008 Borland Software Corp.
*
* 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:
* Alexander Shatalin (Borland) - initial API and implementation
*/
package org.eclipse.gmf.internal.xpand.migration.ui;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.gmf.internal.xpand.RootManager;
import org.eclipse.gmf.internal.xpand.expression.AnalysationIssue;
import org.eclipse.gmf.internal.xpand.migration.MigrationException;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
public class MigrateXpandRoot implements IObjectActionDelegate {
private static final String CHARSET = "ISO-8859-1";
private static final String MIGRATED_ROOT_EXTENSION = "migrated";
private IContainer selectedContainer;
private RootManager rootManager;
private IWorkbenchPart workbenchPart;
private static IFolder getOutputFolder(IContainer selectedContainer) {
IContainer parent = selectedContainer.getParent();
IPath relativePathBasis = selectedContainer.getProjectRelativePath().removeFirstSegments(parent.getProjectRelativePath().segmentCount());
IPath relativePath = relativePathBasis.addFileExtension(MIGRATED_ROOT_EXTENSION);
for (int i = 0; parent.getFolder(relativePath).exists(); i++) {
relativePath = relativePathBasis.addFileExtension(MIGRATED_ROOT_EXTENSION + i);
}
return parent.getFolder(relativePath);
}
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
workbenchPart = targetPart;
}
public void run(IAction action) {
WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
@Override
protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
monitor.setTaskName("Migrating Xpand Resources");
monitor.beginTask("Migrating Xpand Resources", 102);
int totalNumberOfFiles = calculateFiles(selectedContainer, new SubProgressMonitor(monitor, 1));
IFolder newFolder = getOutputFolder(selectedContainer);
monitor.worked(1);
IProgressMonitor subProgressMonitor = createSubProgressMonitor(monitor, null, 100);
subProgressMonitor.beginTask("Migrating Xpand Resources", totalNumberOfFiles);
try {
selectedContainer.accept(new MigrationVisitor(selectedContainer, newFolder, rootManager, subProgressMonitor));
} catch (CoreException e) {
Throwable cause = e.getCause();
if (cause instanceof InterruptedException) {
throw (InterruptedException) cause;
} else if (cause instanceof XpandResourceMigrationException) {
throw new InvocationTargetException(cause);
} else if (cause instanceof UnsupportedEncodingException) {
throw new InvocationTargetException(cause);
} else {
throw e;
}
}
monitor.done();
}
};
try {
new ProgressMonitorDialog(getShell()).run(true, true, op);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof XpandResourceMigrationException) {
reportMigrationException((XpandResourceMigrationException) cause);
} else if (cause instanceof UnsupportedEncodingException) {
showError("Unsupported encoding", "Specified encoding \"" + CHARSET + "\" is not supported by the platform: " + cause.getMessage());
} else {
showError("Invocation target exception", e.getMessage());
}
} catch (InterruptedException e) {
}
}
protected IProgressMonitor createSubProgressMonitor(IProgressMonitor monitor, String taskName, int numberOfTicks) throws InterruptedException {
if (monitor.isCanceled()) {
throw new InterruptedException("Process was canceled");
}
SubProgressMonitor spm = new SubProgressMonitor(monitor, numberOfTicks);
if (taskName != null) {
spm.setTaskName(taskName);
}
return spm;
}
private int calculateFiles(IContainer container, SubProgressMonitor monitor) throws CoreException {
ResourceCountingVisitor visitor = new ResourceCountingVisitor(monitor);
container.accept(visitor);
monitor.done();
return visitor.getNumberOfSteps();
}
private void reportMigrationException(XpandResourceMigrationException ex) {
MigrationException migrationException = ex.getMigrationException();
StringBuilder sb = new StringBuilder(ex.getTemplateFile().getProjectRelativePath().toString());
sb.append(" migration error\n");
switch (migrationException.getType()) {
case ANALYZATION_PROBLEMS:
sb.append("Following analyzation problems present:\n\n");
for (AnalysationIssue issue : migrationException.getIssues()) {
sb.append(issue.toString());
sb.append("\n");
}
showError("Unable to load xtend resource", sb.toString());
return;
default:
showError("Migration exception", sb.append(migrationException.getMessage()).toString());
}
}
private void showError(String title, String contents) {
MessageDialog.openError(getShell(), title, contents);
}
public void selectionChanged(IAction action, ISelection selection) {
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
if (structuredSelection.size() == 1 && structuredSelection.getFirstElement() instanceof IContainer) {
selectedContainer = (IContainer) structuredSelection.getFirstElement();
rootManager = new RootManager(selectedContainer.getProject());
action.setEnabled(rootManager.isTemplateRoot(selectedContainer));
return;
}
}
action.setEnabled(false);
}
private Shell getShell() {
return workbenchPart.getSite().getShell();
}
}