/**
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* 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.
*
*/
package gov.redhawk.sca.dcd.diagram.part;
import gov.redhawk.diagram.editor.URIEditorInputProxy;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import mil.jpeojtrs.sca.dcd.diagram.part.DcdDiagramEditorPlugin;
import mil.jpeojtrs.sca.dcd.diagram.part.DcdDiagramEditorUtil;
import mil.jpeojtrs.sca.dcd.diagram.part.Messages;
import mil.jpeojtrs.sca.dcd.util.DcdResourceImpl;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.DiagramDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.EditorInputProxy;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.document.FileEditorInputProxy;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.EditorStatusCodes;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.util.DiagramIOUtil;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResource;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.part.FileEditorInput;
/**
*
*/
public class DcdDocumentProvider extends mil.jpeojtrs.sca.dcd.diagram.part.DcdDocumentProvider {
private static enum SINGLETON {
INSTANCE;
private final DcdDocumentProvider value = new DcdDocumentProvider();
}
public static DcdDocumentProvider getInstance() {
return SINGLETON.INSTANCE.value;
}
private DcdDocumentProvider() {
};
@Override
protected IDocument createDocument(final Object element) throws CoreException {
if (!(element instanceof FileEditorInput) && !(element instanceof URIEditorInput) && !(element instanceof EditorInputProxy)) {
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, 0, NLS.bind(Messages.DcdDocumentProvider_IncorrectInputError,
new Object[] { element, "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$
null));
}
final IDocument document = createEmptyDocument(element);
setDocumentContent(document, (IEditorInput) element);
setupDocument(element, document);
return document;
}
/**
* @since 2.0
*/
@Override
protected ElementInfo createElementInfo(final Object element) throws CoreException {
if (!(element instanceof FileEditorInput) && !(element instanceof URIEditorInput) && !(element instanceof EditorInputProxy)) {
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, 0, NLS.bind(Messages.DcdDocumentProvider_IncorrectInputError,
new Object[] { element, "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$
null));
}
final IEditorInput editorInput = (IEditorInput) element;
final IDiagramDocument document = (IDiagramDocument) createDocument(editorInput);
final ResourceSetInfo info = new ResourceSetInfo(document, editorInput);
info.setModificationStamp(computeModificationStamp(info));
info.fStatus = null;
return info;
}
private long computeModificationStamp(final ResourceSetInfo info) {
int result = 0;
for (final Iterator<Resource> it = info.getLoadedResourcesIterator(); it.hasNext();) {
final Resource nextResource = it.next();
final IFile file = WorkspaceSynchronizer.getFile(nextResource);
if (file != null) {
if (file.getLocation() != null) {
result += file.getLocation().toFile().lastModified();
} else {
result += file.getModificationStamp();
}
}
}
return result;
}
@Override
protected IDocument createEmptyDocument() {
// END GENERATED CODE
return createEmptyDocument(null);
// BEGIN GENERATED CODE
}
/**
* @param object
*/
protected IDocument createEmptyDocument(final Object input) {
IDocument document;
if (input instanceof EditorInputProxy) {
final EditorInputProxy proxy = (EditorInputProxy) input;
document = new DiagramDocument();
((DiagramDocument) document).setEditingDomain(proxy.getEditingDomain());
} else {
document = super.createEmptyDocument();
}
return document;
}
@Override
protected void doSaveDocument(final IProgressMonitor monitor, final Object element, final IDocument document, final boolean overwrite) throws CoreException {
final ResourceSetInfo info = getResourceSetInfo(element);
if (info != null) {
if (!overwrite && !info.isSynchronized()) {
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, IResourceStatus.OUT_OF_SYNC_LOCAL,
Messages.DcdDocumentProvider_UnsynchronizedFileSaveError, null));
}
info.stopResourceListening();
fireElementStateChanging(element);
try {
monitor.beginTask(Messages.DcdDocumentProvider_SaveDiagramTask, info.getResourceSet().getResources().size() + 1); //"Saving diagram"
for (final Iterator<org.eclipse.emf.ecore.resource.Resource> it = info.getLoadedResourcesIterator(); it.hasNext();) {
final Resource nextResource = it.next();
monitor.setTaskName(NLS.bind(Messages.DcdDocumentProvider_SaveNextResourceTask, nextResource.getURI()));
if (nextResource.isLoaded() && !info.getEditingDomain().isReadOnly(nextResource)
&& (nextResource instanceof DcdResourceImpl || nextResource instanceof GMFResource)) {
try {
nextResource.save(DcdDiagramEditorUtil.getSaveOptions());
} catch (final IOException e) {
fireElementStateChangeFailed(element);
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, EditorStatusCodes.RESOURCE_FAILURE,
e.getLocalizedMessage(), null));
}
}
monitor.worked(1);
}
monitor.done();
info.setModificationStamp(computeModificationStamp(info));
} catch (final RuntimeException x) {
fireElementStateChangeFailed(element);
throw x;
} finally {
info.startResourceListening();
}
} else {
URI newResoruceURI;
List< ? > affectedFiles = null;
if (element instanceof FileEditorInput || element instanceof FileEditorInputProxy) {
IFile newFile;
if (element instanceof FileEditorInputProxy) {
newFile = ((FileEditorInputProxy) element).getFile();
} else {
newFile = ((FileEditorInput) element).getFile();
}
affectedFiles = Collections.singletonList(newFile);
newResoruceURI = URI.createPlatformResourceURI(newFile.getFullPath().toString(), true);
} else if (element instanceof URIEditorInputProxy) {
newResoruceURI = ((URIEditorInputProxy) element).getURI();
} else if (element instanceof URIEditorInput) {
newResoruceURI = ((URIEditorInput) element).getURI();
} else {
fireElementStateChangeFailed(element);
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, 0, NLS.bind(Messages.DcdDocumentProvider_IncorrectInputError,
new Object[] { element, "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$
null));
}
if (!(document instanceof IDiagramDocument)) {
fireElementStateChangeFailed(element);
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, 0, "Incorrect document used: " + document
+ " instead of org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument", null)); //$NON-NLS-1$
}
final IDiagramDocument diagramDocument = (IDiagramDocument) document;
final Resource newResource = diagramDocument.getEditingDomain().getResourceSet().createResource(newResoruceURI);
final Diagram diagramCopy = EcoreUtil.copy(diagramDocument.getDiagram());
try {
final AbstractTransactionalCommand command = new AbstractTransactionalCommand(diagramDocument.getEditingDomain(), NLS.bind(
Messages.DcdDocumentProvider_SaveAsOperation, diagramCopy.getName()), affectedFiles) {
@Override
protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
newResource.getContents().add(diagramCopy);
return CommandResult.newOKCommandResult();
}
};
command.execute(monitor, null);
newResource.save(DcdDiagramEditorUtil.getSaveOptions());
} catch (final ExecutionException e) {
fireElementStateChangeFailed(element);
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, 0, e.getLocalizedMessage(), null));
} catch (final IOException e) {
fireElementStateChangeFailed(element);
throw new CoreException(new Status(IStatus.ERROR, DcdDiagramEditorPlugin.ID, 0, e.getLocalizedMessage(), null));
}
newResource.unload();
}
}
@Override
protected void handleElementMoved(final IEditorInput input, final URI uri) {
if (input instanceof FileEditorInput || input instanceof FileEditorInputProxy) {
final IFile newFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(URI.decode(uri.path())).removeFirstSegments(1));
Object elementMoved;
if (newFile == null) {
elementMoved = null;
} else {
elementMoved = new FileEditorInput(newFile);
}
fireElementMoved(input, elementMoved);
return;
}
// TODO: append suffix to the URI! (use diagram as a parameter)
fireElementMoved(input, new URIEditorInput(uri));
}
@Override
public boolean isModifiable(final Object element) {
if (!isStateValidated(element) && (element instanceof EditorInputProxy)) {
final EditorInputProxy proxy = (EditorInputProxy) element;
if (element instanceof EObject) {
return proxy.getEditingDomain().isReadOnly(((EObject) element).eResource());
} else if (element instanceof Resource) {
return proxy.getEditingDomain().isReadOnly((Resource) element);
}
return true;
} else {
return super.isModifiable(element);
}
}
@Override
protected void setDocumentContent(final IDocument document, final IEditorInput element) throws CoreException {
final IDiagramDocument diagramDocument = (IDiagramDocument) document;
final TransactionalEditingDomain domain = diagramDocument.getEditingDomain();
if (element instanceof FileEditorInputProxy) {
final IStorage storage = ((FileEditorInputProxy) element).getStorage();
final Diagram diagram = DiagramIOUtil.load(domain, storage, true, getProgressMonitor());
document.setContent(diagram);
} else if (element instanceof URIEditorInputProxy) {
super.setDocumentContent(diagramDocument, ((URIEditorInputProxy) element).getProxied());
} else {
super.setDocumentContent(diagramDocument, element);
}
}
}