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