| /******************************************************************************* |
| * <copyright> |
| * |
| * Copyright (c) 2005, 2012 SAP AG. |
| * 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: |
| * SAP AG - initial API, implementation and documentation |
| * mwenz - Bug 346932 - Navigation history broken |
| * Bug 336488 - DiagramEditor API |
| * mwenz - Bug 378342 - Cannot store more than a diagram per file |
| * pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface |
| * fvelasco - Bug 415888 - DiagramEditorInput should adapt to IResource |
| * |
| * </copyright> |
| * |
| *******************************************************************************/ |
| package org.eclipse.graphiti.ui.editor; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IAdaptable; |
| 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.resource.ResourceSet; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.graphiti.mm.pictograms.Diagram; |
| import org.eclipse.graphiti.ui.internal.services.GraphitiUiInternal; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IPersistableElement; |
| |
| /** |
| * The editor input object for {@link IDiagramContainerUI}s. Wraps the {@link URI} of |
| * a {@link Diagram} and an ID of a diagram type provider for displaying it with |
| * a Graphiti diagram editor.<br> |
| * |
| * @see {@link IEditorInput} |
| * @see {@link IPersistableElement} |
| * @see {@link DiagramEditorInputFactory} |
| * @see {@link IDiagramContainerUI} |
| */ |
| public class DiagramEditorInput implements IEditorInput, IPersistableElement, IDiagramEditorInput { |
| |
| /** |
| * The memento key for the stored {@link URI} string |
| */ |
| public static final String KEY_URI = "org.eclipse.graphiti.uri"; //$NON-NLS-1$ |
| |
| /** |
| * The memento key for the ID of the diagram type provider. |
| */ |
| public static String KEY_PROVIDER_ID = "org.eclipse.graphiti.providerId"; //$NON-NLS-1$ |
| |
| /** |
| * The stored {@link URI} string |
| */ |
| private URI uri; |
| |
| /** |
| * The ID of the diagram type provider. |
| */ |
| private String providerId; |
| |
| /** |
| * The cached input name (e.g. for displaying the name in the navigation |
| * history without having to instantiate the {@link EObject}) |
| * |
| * @see #getLiveName() |
| */ |
| private String name; |
| |
| /** |
| * The cached input tooltip |
| * |
| * @see #getLiveToolTipText() |
| */ |
| private String tooltip; |
| |
| |
| /** |
| * Creates a new {@link DiagramEditorInput} out of a {@link URI} string and |
| * a Graphiti diagram type provider ID. For resolving the {@link URI} to an |
| * {@link EObject} the {@link ResourceSet} that will be created when a |
| * diagram editor starts is taken. This input object will not resolve the |
| * diagram.<br> |
| * A diagram type provider ID is held in this class. |
| * |
| * @param diagramUri |
| * A {@link URI} that denotes the input's {@link EObject}. This |
| * can either be a URI of a Graphiti diagram or the URI of an EMF |
| * resource storing a Graphiti diagram. In the latter case the |
| * given URI will b e trimmed to point to the first element in |
| * the resource; make sure that this element is a Graphiti |
| * diagram, otherwise an exception will be thrown when the |
| * diagram editor opens. No check on this is done inside the |
| * input object itself! |
| * @param providerId |
| * A {@link String} which holds the diagram type id. When it is |
| * null, it is set later in |
| * {@link DiagramBehavior#setInput(IEditorInput)} |
| * @throws IllegalArgumentException |
| * if <code>uriString</code> parameter is null <br> |
| * |
| * @see URI |
| * @since 0.9 |
| */ |
| public DiagramEditorInput(URI diagramUri, String providerId) { |
| |
| Assert.isNotNull(diagramUri, "diagram must not be null"); //$NON-NLS-1$ |
| // Normalize URI for later compare operations |
| this.uri = normalizeUriString(diagramUri); |
| setProviderId(providerId); |
| } |
| |
| private URI normalizeUriString(URI diagramUri) { |
| URI normalizedURI = new ResourceSetImpl().getURIConverter().normalize(diagramUri); |
| // Do the trimming only in case no explicit fragment (no specific |
| // diagram inside the resource) was provided. In case a fragment was |
| // provided, use it, otherwise simply take the first element in the |
| // resource (#0) |
| if (!normalizedURI.hasFragment() || "/".equals(normalizedURI.fragment())) { |
| URI trimFragment = normalizedURI.trimFragment(); |
| normalizedURI = GraphitiUiInternal.getEmfService().mapDiagramFileUriToDiagramUri(trimFragment); |
| } |
| return normalizedURI; |
| } |
| |
| /** |
| * Creates a new {@link DiagramEditorInput} for the given {@link Diagram} |
| * and the given diagram type provider ID. |
| * |
| * @param diagram |
| * A {@link Diagram} |
| * @param providerId |
| * A {@link String} which holds the diagram type provider id. |
| * @return A {@link DiagramEditorInput} editor input |
| * @since 0.9 |
| */ |
| public static DiagramEditorInput createEditorInput(Diagram diagram, String providerId) { |
| final Resource resource = diagram.eResource(); |
| if (resource == null) { |
| throw new IllegalArgumentException("Diagram must be contained within a resource"); |
| } |
| URI diagramUri = EcoreUtil.getURI(diagram); |
| DiagramEditorInput diagramEditorInput = new DiagramEditorInput(diagramUri, providerId); |
| return diagramEditorInput; |
| } |
| |
| |
| /** |
| * Returns the diagram type provider id. |
| * |
| * @return The providerId. |
| */ |
| public String getProviderId() { |
| return this.providerId; |
| } |
| |
| /** |
| * Sets the diagram type provider id. |
| * |
| * @param providerId |
| * The providerId to set. |
| */ |
| public void setProviderId(String providerId) { |
| this.providerId = providerId; |
| } |
| |
| /** |
| * Returns the factory ID for creating {@link DiagramEditorInput}s from |
| * mementos. |
| * |
| * @return The ID of the associated factory |
| */ |
| public String getFactoryId() { |
| return DiagramEditorInputFactory.class.getName(); |
| } |
| |
| /** |
| * @return Simply returns <code>null</code>. |
| */ |
| public ImageDescriptor getImageDescriptor() { |
| return null; |
| } |
| |
| /** |
| * @return The cached name or the input's {@link URI} string |
| * @see #getLiveName() |
| */ |
| public String getName() { |
| if (this.name != null) { |
| return this.name; |
| } |
| return this.uri.toString(); |
| } |
| |
| /** |
| * Checks if a name is set for this instance |
| * |
| * @return <code>true</code> in case a name is set, <code>false</code> in |
| * name is <code>null</code>. |
| */ |
| protected boolean hasName() { |
| return this.name != null; |
| } |
| |
| /** |
| * Sets the name for this instance. |
| * |
| * @param name |
| * The name to set. |
| */ |
| protected void setName(String name) { |
| this.name = name; |
| } |
| |
| /** |
| * @return The cached tooltip or the input's {@link URI} string |
| * @see #getLiveToolTipText() |
| */ |
| public String getToolTipText() { |
| if (this.tooltip != null) { |
| return this.tooltip; |
| } |
| return getName(); |
| } |
| |
| |
| /** |
| * Adapter method as defined in {@link IAdaptable}, supports adaptation to |
| * {@link IFile}. |
| * |
| * @param adapter |
| * The adapter class to look up |
| * @return A object castable to the given class, or <code>null</code> if |
| * this object does not have an adapter for the given class |
| */ |
| public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { |
| if (IFile.class.isAssignableFrom(adapter) || IResource.class.equals(adapter)) { |
| return GraphitiUiInternal.getEmfService().getFile(getUri()); |
| } |
| return null; |
| } |
| |
| |
| /** |
| * Saves {@link URI} string, object name and provider ID to the given |
| * {@link IMemento}. |
| * |
| * @param memento |
| * The memento to store the information in |
| */ |
| public void saveState(IMemento memento) { |
| // Do not store anything for deleted objects |
| boolean exists = exists(); |
| if (!exists) { |
| return; |
| } |
| // Store object name, URI and diagram type provider ID |
| memento.putString(KEY_URI, this.uri.toString()); |
| memento.putString(KEY_PROVIDER_ID, this.providerId); |
| } |
| |
| |
| /** |
| * @return The {@link URI} string this input and its editors operate on |
| */ |
| public final String getUriString() { |
| return this.uri.toString(); |
| } |
| |
| /** |
| * Checks if the diagram this input represents exist. |
| * <p> |
| * Note: The editor gets only restored, when <code>true</code> is returned. |
| * |
| * @return <code>true</code> if the input's state denotes a living EMF |
| * object <br> |
| */ |
| public boolean exists() { |
| if (uri == null) { |
| return false; |
| } |
| // TODO check if URI points to something |
| return true; |
| } |
| |
| /** |
| * @return this input if it is persistable, otherwise null |
| */ |
| public IPersistableElement getPersistable() { |
| if (uri != null && providerId != null) { |
| return this; |
| } |
| return null; |
| } |
| |
| |
| /** |
| * @return the resolved {@link URI} or <code>null</code> in case of failures |
| * @since 0.9 |
| */ |
| public URI getUri() { |
| return this.uri; |
| } |
| |
| |
| /** |
| * Checks if this instance of the input represent the same object as the |
| * given instance. |
| * |
| * @param obj |
| * The object to compare this instance with. |
| * @return <code>true</code> if the represented objects are the same |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj == null) { |
| return false; |
| } |
| if (getClass() != obj.getClass()) { |
| return false; |
| } |
| DiagramEditorInput other = (DiagramEditorInput) obj; |
| if (uri == null) { |
| if (other.uri != null) { |
| return false; |
| } |
| } else if (!uri.equals(other.uri)) { |
| return false; |
| } |
| if (providerId == null) { |
| if (other.providerId != null) { |
| return false; |
| } |
| } else if (!providerId.equals(other.providerId)) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public int hashCode() { |
| final int prime = 31; |
| int result = 1; |
| result = prime * result + ((uri == null) ? 0 : uri.hashCode()); |
| result = prime * result + ((providerId == null) ? 0 : providerId.hashCode()); |
| return result; |
| } |
| |
| /** |
| * Used for logging only! |
| */ |
| @Override |
| public String toString() { |
| final String s = super.toString() + " uri: " + this.uri; //$NON-NLS-1$ |
| return s; |
| } |
| |
| /** |
| * @since 0.9 |
| */ |
| public void updateUri(URI diagramFileUri) { |
| URI uri = GraphitiUiInternal.getEmfService().mapDiagramFileUriToDiagramUri(diagramFileUri); |
| URI normalizedUri = normalizeUriString(uri); |
| this.uri = normalizedUri; |
| } |
| } |