X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.ui%2Fsrc%2Forg%2Fsimantics%2Fui%2Fworkbench%2FResourceEditorInput2.java;h=e1ec2f52106cbbcfc4a0ae1d52157e8bf309702b;hp=a03ea7c45dd177d8e7b88f5f6fc8ab66a6a2344c;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java index a03ea7c45..e1ec2f521 100644 --- a/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java +++ b/bundles/org.simantics.ui/src/org/simantics/ui/workbench/ResourceEditorInput2.java @@ -1,555 +1,555 @@ -/******************************************************************************* - * Copyright (c) 2007, 2013 Association for Decentralized Information Management - * in Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - * Semantum Oy - issue #4384 - *******************************************************************************/ -package org.simantics.ui.workbench; - -import java.lang.ref.Reference; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IPersistableElement; -import org.simantics.Simantics; -import org.simantics.db.ReadGraph; -import org.simantics.db.RequestProcessor; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.common.ResourceArray; -import org.simantics.db.common.request.ReadRequest; -import org.simantics.db.exception.AdaptionException; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.ResourceNotFoundException; -import org.simantics.db.layer0.exception.MissingVariableException; -import org.simantics.db.layer0.variable.RVI; -import org.simantics.db.layer0.variable.Variable; -import org.simantics.db.layer0.variable.Variables; -import org.simantics.db.request.Read; -import org.simantics.db.service.LifecycleSupport; -import org.simantics.ui.icons.ImageDescriptorProvider; -import org.simantics.ui.workbench.editor.input.ResourceEditorInputMatchingStrategy; -import org.simantics.utils.ObjectUtils; -import org.simantics.utils.datastructures.cache.ProvisionException; -import org.simantics.utils.ui.ErrorLogger; -import org.simantics.utils.ui.workbench.StringMemento; - -/** - * This is an input class for editors that have as their input the a tuple: - * (Input Resource, Model URI, RVI). - * - * Editor extensions requiring these as input should always use - * {@link ResourceEditorInputMatchingStrategy} as their matchingStrategy. - * - * @author Tuukka Lehtonen - * @see ResourceEditorInput - * @see ResourceEditorInputMatchingStrategy - */ -public class ResourceEditorInput2 extends PlatformObject implements IResourceEditorInput2, IPersistableElement { - - private final static boolean DEBUG_EXISTS = false; - private final static boolean DEBUG_UPDATE = false; - - private static final String NO_NAME = ResourceEditorInput.NO_NAME; - - private final String editorID; - - /** - * A random access ID to {@link #resource}. - */ - protected String modelId; - - protected String rvi; - - /** - * A random access ID to {@link #resource}. - */ - private String resourceId; - - private transient Reference model; - - private transient Reference resource; - - private transient boolean exists; - - private transient String name; - - private transient String tooltip; - - private transient ImageDescriptor imageDesc; - - /** Persistent memento for external data */ - private final StringMemento persistentStore = new StringMemento(); - - ResourceEditorInput2(String editorID, String resourceId, String modelId, String rvi) { - - if (editorID == null) - throw new IllegalArgumentException("null editor id"); - if (resourceId == null) - throw new IllegalArgumentException("null resource id"); - - this.editorID = editorID; - this.resourceId = resourceId; - this.resource = null; - this.modelId = modelId; - this.model = null; - this.rvi = rvi; - - setNonExistant(); - } - - /** - * @param editorID - * @param resourceId - * @param modelURI - * @param rvi - */ - public ResourceEditorInput2(String editorID, String resourceId, String modelId, RVI rvi) { - if (editorID == null) - throw new IllegalArgumentException("null editor id"); - if (resourceId == null) - throw new IllegalArgumentException("null resource id"); - - this.editorID = editorID; - this.resourceId = resourceId; - this.resource = null; - this.modelId = modelId; - this.model = null; - this.rvi = rvi.toString(); - - setNonExistant(); - } - - @Deprecated - public ResourceEditorInput2(String editorID, Resource resource, Resource model, String rvi) { - if (editorID == null) - throw new IllegalArgumentException("null editor id"); - if (resource == null) - throw new IllegalArgumentException("null resource"); - if (model == null) - throw new IllegalArgumentException("null model"); - - this.editorID = editorID; - this.resourceId = ResourceInputs.getRandomAccessId(resource); - this.resource = ResourceInputs.makeReference(resource); - this.modelId = ResourceInputs.getRandomAccessId(model); - this.model = ResourceInputs.makeReference(model); - this.rvi = rvi; - - setNonExistant(); - } - - public ResourceEditorInput2(String editorID, Resource resource, Resource model, RVI rvi) { - if (editorID == null) - throw new IllegalArgumentException("null editor id"); - if (resource == null) - throw new IllegalArgumentException("null resource"); - if (model == null) - throw new IllegalArgumentException("null model"); - - this.editorID = editorID; - this.resourceId = ResourceInputs.getRandomAccessId(resource); - this.resource = ResourceInputs.makeReference(resource); - this.modelId = ResourceInputs.getRandomAccessId(model); - this.model = ResourceInputs.makeReference(model); - this.rvi = rvi != null ? rvi.toString() : null; - - setNonExistant(); - } - - @Override - public void init(IAdaptable adapter) throws DatabaseException { - Resource r = getResource(); - if (r != null) - updateCaches(getSession(), true); - } - - @Override - public void dispose() { - //System.out.println("dispose resource editor input: " + name); - // NOTE: this has to be done since Eclipse will cache these IEditorInput - // instances within EditorHistoryItem's that are stored in an EditorHistory - // instance. They are held by strong reference which means that the session - // cannot be collected if it is not nulled here. - resource = null; - model = null; - } - - /** - * @return a graph instance if it exists and has not yet been disposed, - * null otherwise - */ - public Session getSession() { - Session s = Simantics.getSession(); - if (s.getService(LifecycleSupport.class).isClosed()) - throw new IllegalStateException("database session is closed"); - return s; - } - - @Override - public boolean exists() { - return exists; - } - - @Override - public boolean exists(ReadGraph graph) throws DatabaseException { - try { - assertExists(graph); - return true; - } catch (MissingVariableException e) { - } catch (ResourceNotFoundException e) { - } catch (Nonexistant e) { - } - return false; - } - - public Resource getResource0() throws DatabaseException { - Resource r = tryGetResource(); - if (r != null) - return r; - - Session s = ResourceInputs.peekSession(); - if (s == null) - return null; - - r = ResourceInputs.resolveResource( s, resourceId ); - this.resource = ResourceInputs.makeReference( r ); - return r; - } - - public Resource getModel0() throws DatabaseException { - Resource r = tryGetModel(); - if (r != null) - return r; - - Session s = ResourceInputs.peekSession(); - if (s == null) - return null; - - r = ResourceInputs.resolveResource( s, modelId ); - this.model = ResourceInputs.makeReference( r ); - return r; - } - - @Override - public Resource getResource() { - try { - return getResource0(); - } catch (DatabaseException e) { - ErrorLogger.defaultLogError(e); - return null; - } - } - - @Override - @Deprecated - public ResourceArray getResourceArray() { - Resource r = getResource(); - return r == null ? ResourceArray.EMPTY : new ResourceArray(r); - } - - public Resource getModel(ReadGraph graph) { - try { - return getModel0(); - } catch (DatabaseException e) { - ErrorLogger.defaultLogError(e); - return null; - } - } - - - @Override - public String getRVI() { - return rvi; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IEditorInput#getImageDescriptor() - */ - @Override - public ImageDescriptor getImageDescriptor() { - return imageDesc; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IEditorInput#getName() - */ - @Override - public String getName() { - return name; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IEditorInput#getToolTipText() - */ - @Override - public String getToolTipText() { - return tooltip; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IEditorInput#getPersistable() - */ - @Override - public IPersistableElement getPersistable() { - // Don't allow persistability when it's not possible. - if (!isPersistable()) - return null; - return this; - } - - protected boolean isPersistable() { - Session session = Simantics.peekSession(); - if (session == null) - return false; - LifecycleSupport lc = session.peekService(LifecycleSupport.class); - if (lc == null) - return false; - if (lc.isClosed()) - return false; - return true; - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IPersistableElement#getFactoryId() - */ - @Override - public String getFactoryId() { - return ResourceEditorInputFactory2.getFactoryId(); - } - - /** - * Saves the state of the given resource editor input into the given memento. - * - * @param memento the storage area for element state - * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento) - */ - @Override - public void saveState(IMemento memento) { - IMemento child = memento.createChild(ResourceEditorInputFactory2.TAG_RESOURCE_ID); - child.putTextData(resourceId); - memento.putString(ResourceEditorInputFactory2.TAG_EDITOR_ID, editorID); - memento.putString(ResourceEditorInputFactory2.TAG_MODEL_ID, modelId); - memento.putString(ResourceEditorInputFactory2.TAG_RVI, rvi); - memento.putString(ResourceEditorInputFactory2.TAG_EXTERNAL_MEMENTO_ID, persistentStore.toString()); - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - @SuppressWarnings("rawtypes") - @Override - public Object getAdapter(Class adapter) { - //System.out.println("[ResourceEditorInput] getAdapter: " + adapter.getName()); - return null; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + editorID.hashCode(); - // modelURI and rvi may change => can't use either in hashcode. -// result = prime * result + ObjectUtils.hashCode(modelURI); -// result = prime * result + ObjectUtils.hashCode(rvi); - result = prime * result + ObjectUtils.hashCode(modelId); - result = prime * result + ObjectUtils.hashCode(resourceId); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ResourceEditorInput2 other = (ResourceEditorInput2) obj; - if (!editorID.equals(other.editorID)) - return false; - if (!ObjectUtils.objectEquals(modelId, other.modelId)) - return false; - if (!ObjectUtils.objectEquals(rvi, other.rvi)) - return false; - if (!ObjectUtils.objectEquals(resourceId, other.resourceId)) - return false; - return true; - } - - private void updateCaches(RequestProcessor processor, boolean sync) throws DatabaseException { - ReadRequest req = new ReadRequest() { - @Override - public void run(ReadGraph g) throws DatabaseException { - update(g); - } - }; - if (sync) { - processor.syncRequest(req); - } else { - processor.asyncRequest(req); - } - } - - static class Nonexistant extends DatabaseException { - private static final long serialVersionUID = -7964385375237203651L; - - @Override - public synchronized Throwable fillInStackTrace() { - return this; - } - } - - /* (non-Javadoc) - * @see org.simantics.ui.workbench.IResourceEditorInput#update(org.simantics.db.Graph) - */ - @Override - public void update(ReadGraph g) throws DatabaseException { - Resource r = getResource(); - if (r == null) - return; - - if (DEBUG_UPDATE) - System.out.println("update(" + this + ")"); - - try { - assertExists(g); - - name = g.syncRequest(new TitleRequest(editorID, this)); - if (name == null) - name = NO_NAME; - - tooltip = g.syncRequest(new ToolTipRequest(editorID, this)); - if (tooltip == null) - tooltip = NO_NAME; - - try { - ImageDescriptorProvider idp = g.adapt(r, ImageDescriptorProvider.class); - imageDesc = idp.get(); - } catch (AdaptionException e) { - imageDesc = ImageDescriptor.getMissingImageDescriptor(); - } catch (ProvisionException e) { - imageDesc = ImageDescriptor.getMissingImageDescriptor(); - ErrorLogger.defaultLogError(e); - } - - if (DEBUG_UPDATE) - System.out.println("update(" + this + ") finished"); - } catch (DatabaseException e) { - if (DEBUG_UPDATE) - e.printStackTrace(); - setNonExistant(); - } - } - - private void assertExists(ReadGraph g) throws DatabaseException { - if (DEBUG_EXISTS) - System.out.println("ResourceEditorInput2.assertExists(" + this + ") begins"); - - // 1. Check resource existence - Resource r = getResource(); - if (r == null) - throw new Nonexistant(); - - exists = g.hasStatement(r); - if (!exists) - throw new Nonexistant(); - - // 2. Check model existence - Resource model = getModel(g); - if (model == null) - throw new Nonexistant(); - - exists = g.hasStatement(model); - if (!exists) - throw new Nonexistant(); - - // 3. Validate rvi - if (DEBUG_EXISTS) - System.out.println("validating rvi: '" + rvi + "'"); - - if(rvi != null && !rvi.isEmpty()) { - Variable context = Variables.getPossibleConfigurationContext(g, model); - if (context == null) - throw new Nonexistant(); - RVI rvi_ = RVI.fromResourceFormat(g, rvi); - Variable variable = rvi_.resolvePossible(g, context); - if (variable == null) - throw new Nonexistant(); - } - - // Touch the diagram title calculation within this existence - // checking request. - g.syncRequest(new TitleRequest(editorID, this)); - - if (DEBUG_EXISTS) - System.out.println("ResourceEditorInput2.assertExists(" + this + ") finished"); - } - - private void setNonExistant() { - if (DEBUG_UPDATE) - System.out.println("setNonExistant(" + this + " @ " + System.identityHashCode(this) + ")"); - - exists = false; - tooltip = name = NO_NAME; - imageDesc = ImageDescriptor.getMissingImageDescriptor(); - } - - public IMemento getPersistentStore() { - return persistentStore; - } - - @Override - public String toString() { - return getClass().getSimpleName() + " [name=" + getName() + ", resource=" + resource + ", model=" + model + ", rvi=" + rvi + "]"; - } - - /** - * @see org.simantics.ui.workbench.IResourceEditorInput2#getVariable() - */ - public Variable getVariable() throws DatabaseException { - return getSession().syncRequest(new Read() { - @Override - public Variable perform(ReadGraph graph) throws DatabaseException { - return getVariable(graph); - } - }); - } - - /** - * @see org.simantics.ui.workbench.IResourceEditorInput2#getVariable(org.simantics.db.ReadGraph) - */ - public Variable getVariable(ReadGraph graph) throws DatabaseException { - Resource model = getModel(graph); - String rvi = getRVI(); - // Model + RVI - if (rvi != null) { - Variable configuration = Variables.getConfigurationContext(graph, model); - RVI rrvi = RVI.fromResourceFormat(graph, rvi); - return rrvi.resolve(graph, configuration); - } - // Absolute URI - else { - return Variables.getVariable(graph, model); - } - } - - private Resource tryGetResource() { - Reference ref = resource; - return ref == null ? null : ref.get(); - } - - private Resource tryGetModel() { - Reference ref = model; - return ref == null ? null : ref.get(); - } - +/******************************************************************************* + * Copyright (c) 2007, 2013 Association for Decentralized Information Management + * in Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - issue #4384 + *******************************************************************************/ +package org.simantics.ui.workbench; + +import java.lang.ref.Reference; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.exception.AdaptionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ResourceNotFoundException; +import org.simantics.db.layer0.exception.MissingVariableException; +import org.simantics.db.layer0.variable.RVI; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.request.Read; +import org.simantics.db.service.LifecycleSupport; +import org.simantics.ui.icons.ImageDescriptorProvider; +import org.simantics.ui.workbench.editor.input.ResourceEditorInputMatchingStrategy; +import org.simantics.utils.ObjectUtils; +import org.simantics.utils.datastructures.cache.ProvisionException; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.workbench.StringMemento; + +/** + * This is an input class for editors that have as their input the a tuple: + * (Input Resource, Model URI, RVI). + * + * Editor extensions requiring these as input should always use + * {@link ResourceEditorInputMatchingStrategy} as their matchingStrategy. + * + * @author Tuukka Lehtonen + * @see ResourceEditorInput + * @see ResourceEditorInputMatchingStrategy + */ +public class ResourceEditorInput2 extends PlatformObject implements IResourceEditorInput2, IPersistableElement { + + private final static boolean DEBUG_EXISTS = false; + private final static boolean DEBUG_UPDATE = false; + + private static final String NO_NAME = ResourceEditorInput.NO_NAME; + + private final String editorID; + + /** + * A random access ID to {@link #resource}. + */ + protected String modelId; + + protected String rvi; + + /** + * A random access ID to {@link #resource}. + */ + private String resourceId; + + private transient Reference model; + + private transient Reference resource; + + private transient boolean exists; + + private transient String name; + + private transient String tooltip; + + private transient ImageDescriptor imageDesc; + + /** Persistent memento for external data */ + private final StringMemento persistentStore = new StringMemento(); + + ResourceEditorInput2(String editorID, String resourceId, String modelId, String rvi) { + + if (editorID == null) + throw new IllegalArgumentException("null editor id"); + if (resourceId == null) + throw new IllegalArgumentException("null resource id"); + + this.editorID = editorID; + this.resourceId = resourceId; + this.resource = null; + this.modelId = modelId; + this.model = null; + this.rvi = rvi; + + setNonExistant(); + } + + /** + * @param editorID + * @param resourceId + * @param modelURI + * @param rvi + */ + public ResourceEditorInput2(String editorID, String resourceId, String modelId, RVI rvi) { + if (editorID == null) + throw new IllegalArgumentException("null editor id"); + if (resourceId == null) + throw new IllegalArgumentException("null resource id"); + + this.editorID = editorID; + this.resourceId = resourceId; + this.resource = null; + this.modelId = modelId; + this.model = null; + this.rvi = rvi.toString(); + + setNonExistant(); + } + + @Deprecated + public ResourceEditorInput2(String editorID, Resource resource, Resource model, String rvi) { + if (editorID == null) + throw new IllegalArgumentException("null editor id"); + if (resource == null) + throw new IllegalArgumentException("null resource"); + if (model == null) + throw new IllegalArgumentException("null model"); + + this.editorID = editorID; + this.resourceId = ResourceInputs.getRandomAccessId(resource); + this.resource = ResourceInputs.makeReference(resource); + this.modelId = ResourceInputs.getRandomAccessId(model); + this.model = ResourceInputs.makeReference(model); + this.rvi = rvi; + + setNonExistant(); + } + + public ResourceEditorInput2(String editorID, Resource resource, Resource model, RVI rvi) { + if (editorID == null) + throw new IllegalArgumentException("null editor id"); + if (resource == null) + throw new IllegalArgumentException("null resource"); + if (model == null) + throw new IllegalArgumentException("null model"); + + this.editorID = editorID; + this.resourceId = ResourceInputs.getRandomAccessId(resource); + this.resource = ResourceInputs.makeReference(resource); + this.modelId = ResourceInputs.getRandomAccessId(model); + this.model = ResourceInputs.makeReference(model); + this.rvi = rvi != null ? rvi.toString() : null; + + setNonExistant(); + } + + @Override + public void init(IAdaptable adapter) throws DatabaseException { + Resource r = getResource(); + if (r != null) + updateCaches(getSession(), true); + } + + @Override + public void dispose() { + //System.out.println("dispose resource editor input: " + name); + // NOTE: this has to be done since Eclipse will cache these IEditorInput + // instances within EditorHistoryItem's that are stored in an EditorHistory + // instance. They are held by strong reference which means that the session + // cannot be collected if it is not nulled here. + resource = null; + model = null; + } + + /** + * @return a graph instance if it exists and has not yet been disposed, + * null otherwise + */ + public Session getSession() { + Session s = Simantics.getSession(); + if (s.getService(LifecycleSupport.class).isClosed()) + throw new IllegalStateException("database session is closed"); + return s; + } + + @Override + public boolean exists() { + return exists; + } + + @Override + public boolean exists(ReadGraph graph) throws DatabaseException { + try { + assertExists(graph); + return true; + } catch (MissingVariableException e) { + } catch (ResourceNotFoundException e) { + } catch (Nonexistant e) { + } + return false; + } + + public Resource getResource0() throws DatabaseException { + Resource r = tryGetResource(); + if (r != null) + return r; + + Session s = ResourceInputs.peekSession(); + if (s == null) + return null; + + r = ResourceInputs.resolveResource( s, resourceId ); + this.resource = ResourceInputs.makeReference( r ); + return r; + } + + public Resource getModel0() throws DatabaseException { + Resource r = tryGetModel(); + if (r != null) + return r; + + Session s = ResourceInputs.peekSession(); + if (s == null) + return null; + + r = ResourceInputs.resolveResource( s, modelId ); + this.model = ResourceInputs.makeReference( r ); + return r; + } + + @Override + public Resource getResource() { + try { + return getResource0(); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + return null; + } + } + + @Override + @Deprecated + public ResourceArray getResourceArray() { + Resource r = getResource(); + return r == null ? ResourceArray.EMPTY : new ResourceArray(r); + } + + public Resource getModel(ReadGraph graph) { + try { + return getModel0(); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + return null; + } + } + + + @Override + public String getRVI() { + return rvi; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + @Override + public ImageDescriptor getImageDescriptor() { + return imageDesc; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getName() + */ + @Override + public String getName() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + @Override + public String getToolTipText() { + return tooltip; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + @Override + public IPersistableElement getPersistable() { + // Don't allow persistability when it's not possible. + if (!isPersistable()) + return null; + return this; + } + + protected boolean isPersistable() { + Session session = Simantics.peekSession(); + if (session == null) + return false; + LifecycleSupport lc = session.peekService(LifecycleSupport.class); + if (lc == null) + return false; + if (lc.isClosed()) + return false; + return true; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPersistableElement#getFactoryId() + */ + @Override + public String getFactoryId() { + return ResourceEditorInputFactory2.getFactoryId(); + } + + /** + * Saves the state of the given resource editor input into the given memento. + * + * @param memento the storage area for element state + * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento) + */ + @Override + public void saveState(IMemento memento) { + IMemento child = memento.createChild(ResourceEditorInputFactory2.TAG_RESOURCE_ID); + child.putTextData(resourceId); + memento.putString(ResourceEditorInputFactory2.TAG_EDITOR_ID, editorID); + memento.putString(ResourceEditorInputFactory2.TAG_MODEL_ID, modelId); + memento.putString(ResourceEditorInputFactory2.TAG_RVI, rvi); + memento.putString(ResourceEditorInputFactory2.TAG_EXTERNAL_MEMENTO_ID, persistentStore.toString()); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class adapter) { + //System.out.println("[ResourceEditorInput] getAdapter: " + adapter.getName()); + return null; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + editorID.hashCode(); + // modelURI and rvi may change => can't use either in hashcode. +// result = prime * result + ObjectUtils.hashCode(modelURI); +// result = prime * result + ObjectUtils.hashCode(rvi); + result = prime * result + ObjectUtils.hashCode(modelId); + result = prime * result + ObjectUtils.hashCode(resourceId); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ResourceEditorInput2 other = (ResourceEditorInput2) obj; + if (!editorID.equals(other.editorID)) + return false; + if (!ObjectUtils.objectEquals(modelId, other.modelId)) + return false; + if (!ObjectUtils.objectEquals(rvi, other.rvi)) + return false; + if (!ObjectUtils.objectEquals(resourceId, other.resourceId)) + return false; + return true; + } + + private void updateCaches(RequestProcessor processor, boolean sync) throws DatabaseException { + ReadRequest req = new ReadRequest() { + @Override + public void run(ReadGraph g) throws DatabaseException { + update(g); + } + }; + if (sync) { + processor.syncRequest(req); + } else { + processor.asyncRequest(req); + } + } + + static class Nonexistant extends DatabaseException { + private static final long serialVersionUID = -7964385375237203651L; + + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + } + + /* (non-Javadoc) + * @see org.simantics.ui.workbench.IResourceEditorInput#update(org.simantics.db.Graph) + */ + @Override + public void update(ReadGraph g) throws DatabaseException { + Resource r = getResource(); + if (r == null) + return; + + if (DEBUG_UPDATE) + System.out.println("update(" + this + ")"); + + try { + assertExists(g); + + name = g.syncRequest(new TitleRequest(editorID, this)); + if (name == null) + name = NO_NAME; + + tooltip = g.syncRequest(new ToolTipRequest(editorID, this)); + if (tooltip == null) + tooltip = NO_NAME; + + try { + ImageDescriptorProvider idp = g.adapt(r, ImageDescriptorProvider.class); + imageDesc = idp.get(); + } catch (AdaptionException e) { + imageDesc = ImageDescriptor.getMissingImageDescriptor(); + } catch (ProvisionException e) { + imageDesc = ImageDescriptor.getMissingImageDescriptor(); + ErrorLogger.defaultLogError(e); + } + + if (DEBUG_UPDATE) + System.out.println("update(" + this + ") finished"); + } catch (DatabaseException e) { + if (DEBUG_UPDATE) + e.printStackTrace(); + setNonExistant(); + } + } + + private void assertExists(ReadGraph g) throws DatabaseException { + if (DEBUG_EXISTS) + System.out.println("ResourceEditorInput2.assertExists(" + this + ") begins"); + + // 1. Check resource existence + Resource r = getResource(); + if (r == null) + throw new Nonexistant(); + + exists = g.hasStatement(r); + if (!exists) + throw new Nonexistant(); + + // 2. Check model existence + Resource model = getModel(g); + if (model == null) + throw new Nonexistant(); + + exists = g.hasStatement(model); + if (!exists) + throw new Nonexistant(); + + // 3. Validate rvi + if (DEBUG_EXISTS) + System.out.println("validating rvi: '" + rvi + "'"); + + if(rvi != null && !rvi.isEmpty()) { + Variable context = Variables.getPossibleConfigurationContext(g, model); + if (context == null) + throw new Nonexistant(); + RVI rvi_ = RVI.fromResourceFormat(g, rvi); + Variable variable = rvi_.resolvePossible(g, context); + if (variable == null) + throw new Nonexistant(); + } + + // Touch the diagram title calculation within this existence + // checking request. + g.syncRequest(new TitleRequest(editorID, this)); + + if (DEBUG_EXISTS) + System.out.println("ResourceEditorInput2.assertExists(" + this + ") finished"); + } + + private void setNonExistant() { + if (DEBUG_UPDATE) + System.out.println("setNonExistant(" + this + " @ " + System.identityHashCode(this) + ")"); + + exists = false; + tooltip = name = NO_NAME; + imageDesc = ImageDescriptor.getMissingImageDescriptor(); + } + + public IMemento getPersistentStore() { + return persistentStore; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " [name=" + getName() + ", resource=" + resource + ", model=" + model + ", rvi=" + rvi + "]"; + } + + /** + * @see org.simantics.ui.workbench.IResourceEditorInput2#getVariable() + */ + public Variable getVariable() throws DatabaseException { + return getSession().syncRequest(new Read() { + @Override + public Variable perform(ReadGraph graph) throws DatabaseException { + return getVariable(graph); + } + }); + } + + /** + * @see org.simantics.ui.workbench.IResourceEditorInput2#getVariable(org.simantics.db.ReadGraph) + */ + public Variable getVariable(ReadGraph graph) throws DatabaseException { + Resource model = getModel(graph); + String rvi = getRVI(); + // Model + RVI + if (rvi != null) { + Variable configuration = Variables.getConfigurationContext(graph, model); + RVI rrvi = RVI.fromResourceFormat(graph, rvi); + return rrvi.resolve(graph, configuration); + } + // Absolute URI + else { + return Variables.getVariable(graph, model); + } + } + + private Resource tryGetResource() { + Reference ref = resource; + return ref == null ? null : ref.get(); + } + + private Resource tryGetModel() { + Reference ref = model; + return ref == null ? null : ref.get(); + } + } \ No newline at end of file