-/*******************************************************************************\r
- * Copyright (c) 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
- *******************************************************************************/\r
-package org.simantics.graphfile.hack;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.Reader;\r
-import java.net.URI;\r
-import java.util.Map;\r
-\r
-import org.eclipse.core.resources.IContainer;\r
-import org.eclipse.core.resources.IFile;\r
-import org.eclipse.core.resources.IFileState;\r
-import org.eclipse.core.resources.IMarker;\r
-import org.eclipse.core.resources.IPathVariableManager;\r
-import org.eclipse.core.resources.IProject;\r
-import org.eclipse.core.resources.IProjectDescription;\r
-import org.eclipse.core.resources.IResource;\r
-import org.eclipse.core.resources.IResourceProxy;\r
-import org.eclipse.core.resources.IResourceProxyVisitor;\r
-import org.eclipse.core.resources.IResourceVisitor;\r
-import org.eclipse.core.resources.IWorkspace;\r
-import org.eclipse.core.resources.ResourceAttributes;\r
-import org.eclipse.core.runtime.CoreException;\r
-import org.eclipse.core.runtime.IPath;\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.QualifiedName;\r
-import org.eclipse.core.runtime.Status;\r
-import org.eclipse.core.runtime.content.IContentDescription;\r
-import org.eclipse.core.runtime.jobs.ISchedulingRule;\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.graphfile.Activator;\r
-import org.simantics.graphfile.ontology.GraphFileResource;\r
-import org.simantics.layer0.Layer0;\r
-\r
-/**\r
- * This is an implementation of IFile that can be used to open external editor for any file.\r
- * (Original implementation (org.eclipse.core.filesystem.File) doesn't work without project/file structure) \r
- * \r
- * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>\r
- *\r
- */\r
-public class GraphFile implements IFile {\r
- private Resource fileResource;\r
- private IWorkspace workspace;\r
- \r
- \r
- public GraphFile(Resource fileResource, IWorkspace ws) {\r
- this.fileResource = fileResource;\r
- this.workspace = ws;\r
- }\r
- \r
- public Resource getFileResource() {\r
- return fileResource;\r
- }\r
- \r
- private String getResourceName() {\r
- try {\r
- return Simantics.getSession().syncRequest(new Read<String>() {\r
- @Override\r
- public String perform(ReadGraph graph) throws DatabaseException {\r
- Layer0 l0 = Layer0.getInstance(graph);\r
- return graph.getPossibleRelatedValue(fileResource, l0.HasName);\r
- }\r
- });\r
- } catch (DatabaseException e) {\r
- Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to get resource name: " + fileResource, e));\r
- return e.getMessage();\r
- }\r
- }\r
- \r
- \r
- private byte[] getResourceData() throws DatabaseException {\r
- return Simantics.getSession().syncRequest(new Read<byte[]>() {\r
- @Override\r
- public byte[] perform(ReadGraph graph) throws DatabaseException {\r
- return getResourceData(graph);\r
- }\r
- });\r
- }\r
- \r
- private byte[] getResourceData(ReadGraph graph) throws DatabaseException {\r
- GraphFileResource gf = GraphFileResource.getInstance(graph);\r
- return graph.getRelatedValue(fileResource, gf.HasFiledata);\r
- }\r
- \r
- private long getResourceModificationTime() {\r
- try {\r
- return Simantics.getSession().syncRequest(new Read<Long>() {\r
- @Override\r
- public Long perform(ReadGraph graph) throws DatabaseException {\r
- return getResourceMofificationTime(graph);\r
- }\r
- });\r
- } catch (DatabaseException e) {\r
- return IFile.NULL_STAMP;\r
- }\r
- }\r
- \r
- private long getResourceMofificationTime(ReadGraph graph) throws DatabaseException {\r
- GraphFileResource gf = GraphFileResource.getInstance(graph);\r
- long time = graph.getRelatedValue(fileResource, gf.LastModified);\r
- //System.out.println("Modification time is " + time + " " + fileResource);\r
- return time;\r
- }\r
- \r
- private void setResourceModificationTime(final long time) throws DatabaseException{\r
- \r
- Simantics.getSession().syncRequest(new WriteRequest() {\r
-\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- setResourceModificationTime(graph, time);\r
- }\r
- });\r
- \r
- }\r
- \r
- private void setResourceModificationTime(WriteGraph graph, long time) throws DatabaseException{\r
- GraphFileResource gf = GraphFileResource.getInstance(graph);\r
- graph.claimLiteral(fileResource, gf.LastModified, time);\r
- //System.out.println("Modification time set to " + time + " " + fileResource);\r
- }\r
- \r
- \r
- @Override\r
- public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
- \r
- @Override\r
- public void accept(IResourceVisitor visitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
- \r
- @Override\r
- public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
- \r
- @Override\r
- public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
- \r
- @Override\r
- public void accept(IResourceProxyVisitor visitor, int depth, int memberFlags) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void clearHistory(IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void copy(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public IMarker createMarker(String type) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public IResourceProxy createProxy() {\r
- return null;\r
- }\r
-\r
- @Override\r
- public void delete(boolean force, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public boolean exists() {\r
- return true;\r
- }\r
-\r
- @Override\r
- public IMarker findMarker(long id) throws CoreException {\r
- return null;\r
- }\r
-\r
- @Override\r
- public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {\r
- return null;\r
- }\r
-\r
- @Override\r
- public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth) throws CoreException {\r
- return 0;\r
- }\r
- \r
- \r
-\r
- @Override\r
- public String getFileExtension() {\r
- String name = getResourceName();\r
- if (name == null)\r
- return null;\r
- int i = name.lastIndexOf(".");\r
- if (i > 0)\r
- return name.substring(i);\r
- else\r
- return null;\r
- \r
- }\r
-\r
- @Override\r
- public long getLocalTimeStamp() {\r
- return 0;\r
- }\r
- \r
- @Override\r
- public long setLocalTimeStamp(long value) throws CoreException {\r
- try {\r
- setResourceModificationTime(value);\r
- } catch (DatabaseException e) {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile transaction error",e));\r
- }\r
- return value;\r
- }\r
-\r
- @Override\r
- public IPath getLocation() {\r
- //return new Path(getResourceAbsolutePath());\r
- return new GraphPath(this);\r
- }\r
-\r
- @Override\r
- public URI getLocationURI() {\r
- return null;\r
- }\r
-\r
- @Override\r
- public IMarker getMarker(long id) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public long getModificationStamp() {\r
- return getResourceModificationTime();\r
- }\r
-\r
- @Override\r
- public IContainer getParent() {\r
- return SystemProject.getDefault();\r
- }\r
-\r
- @Override\r
- public String getPersistentProperty(QualifiedName key)throws CoreException {\r
- return null;\r
- }\r
-\r
- @Override\r
- public IProject getProject() {\r
- return SystemProject.getDefault();\r
- }\r
-\r
- @Override\r
- public IPath getProjectRelativePath() {\r
- return null;\r
- }\r
-\r
- @Override\r
- public IPath getRawLocation() {\r
- //return new Path(getResourceAbsolutePath());\r
- return new GraphPath(this);\r
- }\r
-\r
- @Override\r
- public URI getRawLocationURI() {\r
- return null;\r
- }\r
-\r
- @Override\r
- public ResourceAttributes getResourceAttributes() {\r
- return null;\r
- }\r
-\r
- @Override\r
- public Object getSessionProperty(QualifiedName key) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public int getType() {\r
- return IFile.FILE;\r
- }\r
-\r
- @Override\r
- public IWorkspace getWorkspace() {\r
- return workspace;\r
- }\r
-\r
- @Override\r
- public boolean isAccessible() {\r
- return true;\r
- }\r
-\r
- @Override\r
- public boolean isDerived() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isLinked() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isLinked(int options) {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isLocal(int depth) {\r
- return true;\r
- }\r
-\r
- @Override\r
- public boolean isPhantom() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isSynchronized(int depth) {\r
- return true; // FIXME\r
- }\r
-\r
- @Override\r
- public boolean isTeamPrivateMember() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void move(IProjectDescription description, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {\r
- \r
- //throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void revertModificationStamp(long value) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void setDerived(boolean isDerived) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- \r
-\r
- @Override\r
- public void setPersistentProperty(QualifiedName key, String value) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void setReadOnly(boolean readOnly) {\r
-\r
- }\r
-\r
- @Override\r
- public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void setSessionProperty(QualifiedName key, Object value) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported")); \r
- }\r
-\r
- @Override\r
- public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void touch(IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported")); \r
- }\r
-\r
- @SuppressWarnings({ "rawtypes" })\r
- @Override\r
- public Object getAdapter(Class adapter) {\r
- return null;\r
- }\r
-\r
- @Override\r
- public boolean contains(ISchedulingRule rule) {\r
- if (this.equals(rule))\r
- return true;\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isConflicting(ISchedulingRule rule) {\r
- if (this.equals(rule)) // TODO : check cached timestamp\r
- return true;\r
- return false;\r
- }\r
-\r
- @Override\r
- public void appendContents(InputStream source, boolean force,boolean keepHistory, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported")); \r
- }\r
-\r
- @Override\r
- public void create(InputStream source, boolean force, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void create(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public void createLink(URI location, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- \r
- }\r
-\r
- @Override\r
- public String getCharset() throws CoreException {\r
- return getCharset(true);\r
- }\r
-\r
- @Override\r
- public String getCharset(boolean checkImplicit) throws CoreException {\r
- // FIXME\r
- return "UTF-8";\r
- }\r
- \r
- @Override\r
- public int getEncoding() throws CoreException {\r
- // FIXME\r
- return ENCODING_UTF_8;\r
- }\r
-\r
- @Override\r
- public String getCharsetFor(Reader reader) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public IContentDescription getContentDescription() throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public InputStream getContents() throws CoreException {\r
- return getContents(false);\r
- }\r
-\r
- @Override\r
- public InputStream getContents(boolean force) throws CoreException {\r
- try {\r
- return new ByteArrayInputStream(getResourceData());\r
- } catch (DatabaseException e) {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile transaction error",e));\r
- }\r
- }\r
-\r
- \r
-\r
- @Override\r
- public IPath getFullPath() {\r
- //return new Path(getResourceAbsolutePath());\r
- return new GraphPath(this);\r
- }\r
-\r
- @Override\r
- public IFileState[] getHistory(IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public String getName() {\r
- return getResourceName();\r
- }\r
-\r
- @Override\r
- public boolean isReadOnly() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void setCharset(String newCharset) throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));\r
- }\r
-\r
- @Override\r
- public void setContents(IFileState source, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {\r
- setContents(source.getContents(), force, keepHistory, monitor);\r
- setLocalTimeStamp(source.getModificationTime());\r
- }\r
-\r
- @Override\r
- public void setContents(IFileState source, int updateFlags,\r
- IProgressMonitor monitor) throws CoreException {\r
- setContents(source.getContents(), updateFlags, monitor);\r
- setLocalTimeStamp(source.getModificationTime());\r
- }\r
-\r
- @Override\r
- public void setContents(InputStream source, boolean force,\r
- boolean keepHistory, IProgressMonitor monitor)\r
- throws CoreException {\r
- setContents(source, (keepHistory ? KEEP_HISTORY : IResource.NONE) | (force ? FORCE : IResource.NONE), monitor);\r
- }\r
-\r
- @Override\r
- public void setContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {\r
- \r
- \r
- final ByteArrayOutputStream os = new ByteArrayOutputStream();\r
- try {\r
- byte buf[] = new byte[1024];\r
- int count = 0;\r
- while ((count = source.read(buf)) > 0) {\r
- os.write(buf,0,count);\r
- }\r
- os.close();\r
- Simantics.getSession().syncRequest(new WriteRequest() {\r
- \r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- long time = System.currentTimeMillis();\r
- GraphFileResource gf = GraphFileResource.getInstance(graph);\r
- graph.claimLiteral(fileResource, gf.HasFiledata, os.toByteArray());\r
- setResourceModificationTime(graph, time);\r
- }\r
- });\r
- } catch (DatabaseException e ) {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile transaction error",e));\r
- } catch (IOException e) {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile IO error",e));\r
- }\r
- }\r
-\r
- @SuppressWarnings({ "rawtypes" })\r
- @Override\r
- public Map getPersistentProperties() throws CoreException {\r
- return null;\r
- }\r
-\r
- @SuppressWarnings({ "rawtypes" })\r
- @Override\r
- public Map getSessionProperties() throws CoreException {\r
- return null;\r
- }\r
-\r
- @Override\r
- public boolean isDerived(int options) {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isHidden() {\r
- return false;\r
- }\r
-\r
- @Override\r
- public void setHidden(boolean isHidden) throws CoreException {\r
-\r
- }\r
-\r
- @Override\r
- public boolean isHidden(int options) {\r
- return false;\r
- }\r
-\r
- @Override\r
- public boolean isTeamPrivateMember(int options) {\r
- return false;\r
- }\r
- \r
- @Override\r
- public IPathVariableManager getPathVariableManager() {\r
- return null;\r
- }\r
- \r
- @Override\r
- public boolean isVirtual() {\r
- return false;\r
- }\r
- \r
- @Override\r
- public void setDerived(boolean isDerived, IProgressMonitor monitor)\r
- throws CoreException {\r
- throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported")); \r
- }\r
-\r
- \r
- @Override\r
- public boolean equals(Object obj) {\r
- if (obj == null)\r
- return false;\r
- if (obj.getClass() != getClass())\r
- return false;\r
- GraphFile other = (GraphFile)obj;\r
- return fileResource.equals(other.fileResource);\r
- }\r
- \r
- @Override\r
- public int hashCode() {\r
- return fileResource.hashCode();\r
- }\r
-\r
-}\r
-\r
+/*******************************************************************************
+ * Copyright (c) 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
+ *******************************************************************************/
+package org.simantics.graphfile.hack;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFileState;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IPathVariableManager;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
+import org.simantics.graphfile.Activator;
+import org.simantics.graphfile.ontology.GraphFileResource;
+import org.simantics.layer0.Layer0;
+
+/**
+ * This is an implementation of IFile that can be used to open external editor for any file.
+ * (Original implementation (org.eclipse.core.filesystem.File) doesn't work without project/file structure)
+ *
+ * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>
+ *
+ */
+public class GraphFile implements IFile {
+ private Resource fileResource;
+ private IWorkspace workspace;
+
+
+ public GraphFile(Resource fileResource, IWorkspace ws) {
+ this.fileResource = fileResource;
+ this.workspace = ws;
+ }
+
+ public Resource getFileResource() {
+ return fileResource;
+ }
+
+ private String getResourceName() {
+ try {
+ return Simantics.getSession().syncRequest(new Read<String>() {
+ @Override
+ public String perform(ReadGraph graph) throws DatabaseException {
+ Layer0 l0 = Layer0.getInstance(graph);
+ return graph.getPossibleRelatedValue(fileResource, l0.HasName);
+ }
+ });
+ } catch (DatabaseException e) {
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to get resource name: " + fileResource, e));
+ return e.getMessage();
+ }
+ }
+
+
+ private byte[] getResourceData() throws DatabaseException {
+ return Simantics.getSession().syncRequest(new Read<byte[]>() {
+ @Override
+ public byte[] perform(ReadGraph graph) throws DatabaseException {
+ return getResourceData(graph);
+ }
+ });
+ }
+
+ private byte[] getResourceData(ReadGraph graph) throws DatabaseException {
+ GraphFileResource gf = GraphFileResource.getInstance(graph);
+ return graph.getRelatedValue(fileResource, gf.HasFiledata);
+ }
+
+ private long getResourceModificationTime() {
+ try {
+ return Simantics.getSession().syncRequest(new Read<Long>() {
+ @Override
+ public Long perform(ReadGraph graph) throws DatabaseException {
+ return getResourceMofificationTime(graph);
+ }
+ });
+ } catch (DatabaseException e) {
+ return IFile.NULL_STAMP;
+ }
+ }
+
+ private long getResourceMofificationTime(ReadGraph graph) throws DatabaseException {
+ GraphFileResource gf = GraphFileResource.getInstance(graph);
+ long time = graph.getRelatedValue(fileResource, gf.LastModified);
+ //System.out.println("Modification time is " + time + " " + fileResource);
+ return time;
+ }
+
+ private void setResourceModificationTime(final long time) throws DatabaseException{
+
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ setResourceModificationTime(graph, time);
+ }
+ });
+
+ }
+
+ private void setResourceModificationTime(WriteGraph graph, long time) throws DatabaseException{
+ GraphFileResource gf = GraphFileResource.getInstance(graph);
+ graph.claimLiteral(fileResource, gf.LastModified, time);
+ //System.out.println("Modification time set to " + time + " " + fileResource);
+ }
+
+
+ @Override
+ public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void accept(IResourceVisitor visitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void accept(IResourceProxyVisitor visitor, int depth, int memberFlags) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void clearHistory(IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void copy(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public IMarker createMarker(String type) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public IResourceProxy createProxy() {
+ return null;
+ }
+
+ @Override
+ public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public IMarker findMarker(long id) throws CoreException {
+ return null;
+ }
+
+ @Override
+ public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {
+ return null;
+ }
+
+ @Override
+ public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth) throws CoreException {
+ return 0;
+ }
+
+
+
+ @Override
+ public String getFileExtension() {
+ String name = getResourceName();
+ if (name == null)
+ return null;
+ int i = name.lastIndexOf(".");
+ if (i > 0)
+ return name.substring(i);
+ else
+ return null;
+
+ }
+
+ @Override
+ public long getLocalTimeStamp() {
+ return 0;
+ }
+
+ @Override
+ public long setLocalTimeStamp(long value) throws CoreException {
+ try {
+ setResourceModificationTime(value);
+ } catch (DatabaseException e) {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile transaction error",e));
+ }
+ return value;
+ }
+
+ @Override
+ public IPath getLocation() {
+ //return new Path(getResourceAbsolutePath());
+ return new GraphPath(this);
+ }
+
+ @Override
+ public URI getLocationURI() {
+ return null;
+ }
+
+ @Override
+ public IMarker getMarker(long id) {
+ return null;
+ }
+
+ @Override
+ public long getModificationStamp() {
+ return getResourceModificationTime();
+ }
+
+ @Override
+ public IContainer getParent() {
+ return SystemProject.getDefault();
+ }
+
+ @Override
+ public String getPersistentProperty(QualifiedName key)throws CoreException {
+ return null;
+ }
+
+ @Override
+ public IProject getProject() {
+ return SystemProject.getDefault();
+ }
+
+ @Override
+ public IPath getProjectRelativePath() {
+ return null;
+ }
+
+ @Override
+ public IPath getRawLocation() {
+ //return new Path(getResourceAbsolutePath());
+ return new GraphPath(this);
+ }
+
+ @Override
+ public URI getRawLocationURI() {
+ return null;
+ }
+
+ @Override
+ public ResourceAttributes getResourceAttributes() {
+ return null;
+ }
+
+ @Override
+ public Object getSessionProperty(QualifiedName key) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public int getType() {
+ return IFile.FILE;
+ }
+
+ @Override
+ public IWorkspace getWorkspace() {
+ return workspace;
+ }
+
+ @Override
+ public boolean isAccessible() {
+ return true;
+ }
+
+ @Override
+ public boolean isDerived() {
+ return false;
+ }
+
+ @Override
+ public boolean isLinked() {
+ return false;
+ }
+
+ @Override
+ public boolean isLinked(int options) {
+ return false;
+ }
+
+ @Override
+ public boolean isLocal(int depth) {
+ return true;
+ }
+
+ @Override
+ public boolean isPhantom() {
+ return false;
+ }
+
+ @Override
+ public boolean isSynchronized(int depth) {
+ return true; // FIXME
+ }
+
+ @Override
+ public boolean isTeamPrivateMember() {
+ return false;
+ }
+
+ @Override
+ public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void move(IProjectDescription description, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
+
+ //throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void revertModificationStamp(long value) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setDerived(boolean isDerived) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+
+
+ @Override
+ public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+
+ }
+
+ @Override
+ public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void touch(IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ @Override
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ @Override
+ public boolean contains(ISchedulingRule rule) {
+ if (this.equals(rule))
+ return true;
+ return false;
+ }
+
+ @Override
+ public boolean isConflicting(ISchedulingRule rule) {
+ if (this.equals(rule)) // TODO : check cached timestamp
+ return true;
+ return false;
+ }
+
+ @Override
+ public void appendContents(InputStream source, boolean force,boolean keepHistory, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void create(InputStream source, boolean force, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void create(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public void createLink(URI location, int updateFlags, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+
+ }
+
+ @Override
+ public String getCharset() throws CoreException {
+ return getCharset(true);
+ }
+
+ @Override
+ public String getCharset(boolean checkImplicit) throws CoreException {
+ // FIXME
+ return "UTF-8";
+ }
+
+ @Override
+ public int getEncoding() throws CoreException {
+ // FIXME
+ return ENCODING_UTF_8;
+ }
+
+ @Override
+ public String getCharsetFor(Reader reader) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public IContentDescription getContentDescription() throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public InputStream getContents() throws CoreException {
+ return getContents(false);
+ }
+
+ @Override
+ public InputStream getContents(boolean force) throws CoreException {
+ try {
+ return new ByteArrayInputStream(getResourceData());
+ } catch (DatabaseException e) {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile transaction error",e));
+ }
+ }
+
+
+
+ @Override
+ public IPath getFullPath() {
+ //return new Path(getResourceAbsolutePath());
+ return new GraphPath(this);
+ }
+
+ @Override
+ public IFileState[] getHistory(IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public String getName() {
+ return getResourceName();
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ @Override
+ public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setCharset(String newCharset) throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+ @Override
+ public void setContents(IFileState source, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
+ setContents(source.getContents(), force, keepHistory, monitor);
+ setLocalTimeStamp(source.getModificationTime());
+ }
+
+ @Override
+ public void setContents(IFileState source, int updateFlags,
+ IProgressMonitor monitor) throws CoreException {
+ setContents(source.getContents(), updateFlags, monitor);
+ setLocalTimeStamp(source.getModificationTime());
+ }
+
+ @Override
+ public void setContents(InputStream source, boolean force,
+ boolean keepHistory, IProgressMonitor monitor)
+ throws CoreException {
+ setContents(source, (keepHistory ? KEEP_HISTORY : IResource.NONE) | (force ? FORCE : IResource.NONE), monitor);
+ }
+
+ @Override
+ public void setContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {
+
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try {
+ byte buf[] = new byte[1024];
+ int count = 0;
+ while ((count = source.read(buf)) > 0) {
+ os.write(buf,0,count);
+ }
+ os.close();
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ long time = System.currentTimeMillis();
+ GraphFileResource gf = GraphFileResource.getInstance(graph);
+ graph.claimLiteral(fileResource, gf.HasFiledata, os.toByteArray());
+ setResourceModificationTime(graph, time);
+ }
+ });
+ } catch (DatabaseException e ) {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile transaction error",e));
+ } catch (IOException e) {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"GraphFile IO error",e));
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ @Override
+ public Map getPersistentProperties() throws CoreException {
+ return null;
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ @Override
+ public Map getSessionProperties() throws CoreException {
+ return null;
+ }
+
+ @Override
+ public boolean isDerived(int options) {
+ return false;
+ }
+
+ @Override
+ public boolean isHidden() {
+ return false;
+ }
+
+ @Override
+ public void setHidden(boolean isHidden) throws CoreException {
+
+ }
+
+ @Override
+ public boolean isHidden(int options) {
+ return false;
+ }
+
+ @Override
+ public boolean isTeamPrivateMember(int options) {
+ return false;
+ }
+
+ @Override
+ public IPathVariableManager getPathVariableManager() {
+ return null;
+ }
+
+ @Override
+ public boolean isVirtual() {
+ return false;
+ }
+
+ @Override
+ public void setDerived(boolean isDerived, IProgressMonitor monitor)
+ throws CoreException {
+ throw new CoreException(new Status(Status.ERROR,Activator.PLUGIN_ID,"not supported"));
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (obj.getClass() != getClass())
+ return false;
+ GraphFile other = (GraphFile)obj;
+ return fileResource.equals(other.fileResource);
+ }
+
+ @Override
+ public int hashCode() {
+ return fileResource.hashCode();
+ }
+
+}
+