1 package org.simantics.document.ui.graphfile;
\r
3 import java.io.BufferedReader;
\r
5 import java.io.FileInputStream;
\r
6 import java.io.IOException;
\r
7 import java.io.InputStreamReader;
\r
8 import java.io.PrintStream;
\r
9 import java.util.Collection;
\r
10 import java.util.HashSet;
\r
11 import java.util.Set;
\r
13 import org.eclipse.core.runtime.IProgressMonitor;
\r
14 import org.simantics.Simantics;
\r
15 import org.simantics.db.ReadGraph;
\r
16 import org.simantics.db.Resource;
\r
17 import org.simantics.db.WriteGraph;
\r
18 import org.simantics.db.common.request.ReadRequest;
\r
19 import org.simantics.db.common.request.WriteRequest;
\r
20 import org.simantics.db.common.request.WriteResultRequest;
\r
21 import org.simantics.db.exception.DatabaseException;
\r
22 import org.simantics.document.DocumentResource;
\r
23 import org.simantics.graphfile.ontology.GraphFileResource;
\r
24 import org.simantics.graphfile.util.GraphFileUtil;
\r
25 import org.simantics.layer0.Layer0;
\r
26 import org.simantics.utils.ui.ExceptionUtils;
\r
30 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
33 public class FileDocumentUtil {
\r
36 * Imports file, sets its L0.hasName, and and adds it to a library
\r
38 * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.
\r
43 * @throws DatabaseException
\r
45 public static Resource importFile(final String fileName, final Resource lib, final Resource rel) throws DatabaseException {
\r
46 return Simantics.getSession().syncRequest(new WriteResultRequest<Resource>() {
\r
48 public Resource perform(WriteGraph graph) throws DatabaseException {
\r
49 return importFile(graph, fileName,lib,rel);
\r
56 public static void importFileAsync(final String fileName, final Resource lib, final Resource rel) {
\r
57 Simantics.getSession().asyncRequest(new WriteRequest() {
\r
60 public void perform(WriteGraph graph) throws DatabaseException {
\r
61 importFile(graph, fileName,lib,rel);
\r
64 },new org.simantics.utils.datastructures.Callback<DatabaseException>() {
\r
67 public void run(DatabaseException parameter) {
\r
68 if (parameter != null)
\r
69 ExceptionUtils.logAndShowError("Cannot import file " + fileName, parameter);
\r
78 * Imports file, sets its L0.HasName, and and adds it to a library
\r
80 * Note: if library relation is L0.ConsistsOf, L0.HasName is set to next available unique name.
\r
86 * @throws DatabaseException
\r
88 public static Resource importFile(WriteGraph graph, String fileName, Resource lib, Resource rel) throws DatabaseException{
\r
89 Layer0 l0 = Layer0.getInstance(graph);
\r
90 Resource fileResource = importFile(graph, fileName);
\r
91 graph.claim(lib, rel, fileResource);
\r
92 File file = new File(fileName);
\r
93 String name = file.getName();
\r
94 graph.claimLiteral(fileResource, l0.HasName, name);
\r
95 setUniqueName(graph, fileResource, lib, rel);
\r
96 return fileResource;
\r
99 public static Resource importFileWithName(WriteGraph graph, String fileName) throws DatabaseException{
\r
100 Layer0 l0 = Layer0.getInstance(graph);
\r
101 Resource fileResource = importFile(graph, fileName);
\r
102 File file = new File(fileName);
\r
103 String name = file.getName();
\r
104 graph.claimLiteral(fileResource, l0.HasName, name);
\r
105 return fileResource;
\r
109 * Imports folder of documents recursively (including all sub folders).
\r
111 * @param folderName Name of imported folder
\r
112 * @param lib Library, where imported folder is attached.
\r
113 * @param folderType Type of folders
\r
114 * @param relation Relation used to create file/folder hierarchy
\r
115 * @return the imported folder
\r
116 * @throws DatabaseException
\r
118 public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource lib, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{
\r
119 Resource folderRes = importFolderWithName(graph, folderName, folderType, relation,monitor);
\r
120 graph.claim(lib, relation, folderRes);
\r
121 FileDocumentUtil.createUniqueName(graph, folderRes);
\r
126 * Imports folder of documents recursively (including all sub folders).
\r
128 * @param folderName Name of imported folder
\r
129 * @param folderType Type of folders
\r
130 * @param relation Relation used to create file/folder hierarchy
\r
131 * @param monitor ProgessMonitor or null
\r
132 * @return the imported folder
\r
133 * @throws DatabaseException
\r
135 public static Resource importFolderWithName(WriteGraph graph, String folderName, Resource folderType, Resource relation, IProgressMonitor monitor) throws Exception{
\r
136 Layer0 l0 = Layer0.getInstance(graph);
\r
137 File folder = new File(folderName);
\r
138 Resource rootFolderRes = graph.newResource();
\r
139 graph.claim(rootFolderRes, l0.InstanceOf, folderType);
\r
140 graph.claimLiteral(rootFolderRes, l0.HasName, folder.getName());
\r
141 importFolder(graph, folder, rootFolderRes, relation, monitor);
\r
142 return rootFolderRes;
\r
146 * Imports folder of documents recursively (including all sub folders).
\r
148 * @param folder Imported folder
\r
149 * @param folderResource Resource folder matching file system folder
\r
150 * @param relation Relation used to create file/folder hierarchy
\r
151 * @throws DatabaseException
\r
153 public static void importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{
\r
154 if (monitor != null) {
\r
155 int count = _countFiles(folder);
\r
156 monitor.beginTask("Import files", count);
\r
158 _importFolder(graph, folder, folderResource, relation, monitor);
\r
159 if (monitor != null)
\r
163 private static void _importFolder(WriteGraph graph, File folder, Resource folderResource, Resource relation, IProgressMonitor monitor) throws Exception{
\r
164 Layer0 l0 = Layer0.getInstance(graph);
\r
165 File files[] = folder.listFiles();
\r
166 for (File f : files) {
\r
167 if (f.isDirectory()) {
\r
168 Resource newFolderRes = graph.newResource();
\r
169 graph.claim(newFolderRes, l0.InstanceOf, graph.getSingleType(folderResource));
\r
170 graph.claim(folderResource, relation, newFolderRes);
\r
171 graph.claimLiteral(newFolderRes, l0.HasName, f.getName());
\r
172 _importFolder(graph, f, newFolderRes, relation,monitor);
\r
174 Resource fileRes = null;
\r
177 fileRes = importURL(graph, f);
\r
178 fileRes = importFileWithName(graph, f.getAbsolutePath());
\r
180 graph.claim(folderResource, relation, fileRes);
\r
181 if (monitor != null)
\r
187 private static int _countFiles(File folder) {
\r
190 File files[] = folder.listFiles();
\r
191 for (File f : files) {
\r
192 if (f.isDirectory()) {
\r
193 count += _countFiles(f);
\r
202 public static void createUniqueName(WriteGraph graph, Resource document) throws DatabaseException {
\r
203 Layer0 l0 = Layer0.getInstance(graph);
\r
204 Resource lib = graph.getPossibleObject(document, l0.PartOf);
\r
207 setUniqueName(graph, document, lib, l0.ConsistsOf);
\r
210 public static void setUniqueName(WriteGraph graph, Resource res, Resource lib, Resource rel) throws DatabaseException{
\r
211 Layer0 l0 = Layer0.getInstance(graph);
\r
212 Set<String> names = new HashSet<String>();
\r
213 for (Resource r : graph.getObjects(lib, rel)) {
\r
216 names.add((String)graph.getRelatedValue(r, l0.HasName));
\r
218 String name = graph.getRelatedValue(res, l0.HasName);
\r
219 if (!names.contains(name))
\r
223 String proposal = name +" (" + i +")";
\r
224 if (!names.contains(proposal)) {
\r
225 graph.claimLiteral(res, l0.HasName, proposal);
\r
239 * @throws DatabaseException
\r
241 public static Resource importFile(WriteGraph graph, String fileName) throws DatabaseException{
\r
242 Layer0 l0 = Layer0.getInstance(graph);
\r
243 DocumentResource doc = DocumentResource.getInstance(graph);
\r
245 Resource fileResource = graph.newResource();
\r
246 graph.claim(fileResource, l0.InstanceOf, doc.FileDocument);
\r
248 GraphFileUtil.toGraph(graph,fileName, fileResource);
\r
250 } catch (IOException e) {
\r
251 throw new DatabaseException(e);
\r
253 return fileResource;
\r
258 * Exports graph folder recursively to file system.
\r
260 * @param folderResource
\r
263 * @throws DatabaseException
\r
265 public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, final IProgressMonitor monitor) throws Exception{
\r
266 Simantics.getSession().syncRequest(new ReadRequest() {
\r
269 public void run(ReadGraph graph) throws DatabaseException {
\r
271 exportDocumentFolder(graph, folderResource, folder, relation, monitor);
\r
272 } catch (Exception e) {
\r
273 throw new DatabaseException(e);
\r
282 * Exports graph folder recursively to file system.
\r
284 * @param folderResource
\r
287 * @throws DatabaseException
\r
289 public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, IProgressMonitor monitor) throws Exception{
\r
290 Layer0 l0 = Layer0.getInstance(graph);
\r
291 DocumentResource doc = DocumentResource.getInstance(graph);
\r
292 GraphFileResource gf = GraphFileResource.getInstance(graph);
\r
293 Set<String> names = new HashSet<String>();
\r
294 Collection<Resource> folderType = graph.getPrincipalTypes(folderResource);
\r
295 for (Resource r : graph.getObjects(folderResource, relation)) {
\r
296 if (graph.isInstanceOf(r, doc.Document)) {
\r
297 String name = null;
\r
298 boolean canExport = false;
\r
299 if (graph.isInstanceOf(r, doc.FileDocument)) {
\r
300 name = graph.getRelatedValue(r, gf.HasResourceName);
\r
302 } else if (graph.isInstanceOf(r, doc.UrlDocument)) {
\r
303 name = graph.getRelatedValue(r, l0.HasName) +".url";
\r
307 name = resolveName(folder, name, names, true);
\r
308 File file = new File(folder.getAbsolutePath()+"/"+name);
\r
309 if (graph.isInstanceOf(r, doc.FileDocument)) {
\r
310 GraphFileUtil.writeDataToFile(graph,r, file);
\r
311 } else if (graph.isInstanceOf(r, doc.UrlDocument)) {
\r
312 String url = graph.getRelatedValue(r, doc.HasUrl);
\r
313 String n = graph.getRelatedValue(r, l0.HasName);
\r
314 exportUrl(file, n, url);
\r
316 if (monitor != null)
\r
321 Collection<Resource> type = graph.getPrincipalTypes(r);
\r
322 if (type.size() == folderType.size() && folderType.containsAll(type)) {
\r
323 String name = graph.getRelatedValue(r, l0.HasName);
\r
324 name = resolveName(folder, name, names, false);
\r
325 File subFolder = new File(folder.getAbsolutePath()+"/"+name);
\r
326 if (!subFolder.exists()) {
\r
327 if (!subFolder.mkdir()) {
\r
332 exportDocumentFolder(graph, r, subFolder, relation,monitor);
\r
339 * Print URL to a file (Windows specific format?)
\r
342 * @throws DatabaseException
\r
344 private static void exportUrl(File toFile, String name, String url) throws Exception{
\r
345 PrintStream os = new PrintStream(toFile,"UTF-8");
\r
346 os.println("[InternetShortcut]");
\r
347 os.println("URL="+url);
\r
348 os.println("name="+name);
\r
353 public static Resource importURL(WriteGraph graph, File file) throws Exception{
\r
356 String name = null;
\r
357 BufferedReader is = null;
\r
359 is = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
\r
360 while ((s = is.readLine()) != null) {
\r
361 if (s.startsWith("URL=")) {
\r
362 url = s.substring(4);
\r
363 } else if (s.startsWith("name=")) {
\r
364 name = s.substring(5);
\r
375 Layer0 l0 = Layer0.getInstance(graph);
\r
376 DocumentResource doc = DocumentResource.getInstance(graph);
\r
378 Resource fileResource = graph.newResource();
\r
379 graph.claim(fileResource, l0.InstanceOf, doc.UrlDocument);
\r
380 if (name == null) {
\r
381 name = file.getName();
\r
382 name = unescape(name);
\r
383 name = name.substring(0,name.length()-4);
\r
385 graph.claimLiteral(fileResource, l0.HasName, name);
\r
386 graph.claimLiteral(fileResource, doc.HasUrl, url);
\r
387 return fileResource;
\r
390 private static boolean isUrl(File file) throws Exception{
\r
391 return (file.getAbsolutePath().endsWith(".url"));
\r
394 private static final char ESCAPE = '%';
\r
396 private static String escape(String s) {
\r
398 int len = s.length();
\r
399 StringBuilder sb = new StringBuilder(len);
\r
400 for (int i = 0; i < len; i++) {
\r
401 char ch = s.charAt(i);
\r
402 if (ch < ' ' || ch >= 0x7F || ch == '/' || ch == '\\' || ch == ':' || ch == ESCAPE) {
\r
407 sb.append(Integer.toHexString(ch));
\r
412 return sb.toString();
\r
415 private static String unescape(String s) {
\r
416 int len = s.length();
\r
417 StringBuilder sb = new StringBuilder(len);
\r
418 for (int i = 0; i < len; i++) {
\r
419 char ch = s.charAt(i);
\r
420 if (ch == ESCAPE) {
\r
422 num += s.charAt(++i);
\r
423 num += s.charAt(++i);
\r
424 ch = (char)Integer.decode(num).intValue();
\r
428 return sb.toString();
\r
432 private static String resolveName(File parentFolder, String proposal, Set<String> used, boolean file) {
\r
433 String current = escape(proposal);
\r
438 if (used.contains(current)) {
\r
439 current = createFileName(proposal, i);
\r
441 File subFile = new File(parentFolder.getAbsolutePath()+"/"+current);
\r
442 if (!subFile.exists())
\r
444 if (subFile.exists() && subFile.isFile() && subFile.canWrite()) {
\r
452 if (used.contains(current)) {
\r
453 current = proposal+i;
\r
455 File subFolder = new File(parentFolder.getAbsolutePath()+"/"+current);
\r
456 if (!subFolder.exists())
\r
458 if (subFolder.exists() && subFolder.isDirectory()) {
\r
468 private static String createFileName(String original, int i) {
\r
469 int extIndex = original.lastIndexOf(".");
\r
470 if (extIndex == -1)
\r
472 return original.substring(0,extIndex) + i + original.substring(extIndex);
\r