--- /dev/null
+package org.simantics.fileimport;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.nio.file.Files;\r
+import java.nio.file.Path;\r
+import java.nio.file.Paths;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Optional;\r
+import java.util.Properties;\r
+import java.util.function.Consumer;\r
+\r
+import org.osgi.framework.InvalidSyntaxException;\r
+import org.osgi.framework.ServiceReference;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.service.SerialisationSupport;\r
+import org.simantics.layer0.Layer0;\r
+\r
+public class FileImportService {\r
+\r
+ public static final String DB_FILE = ".simanticsdb";\r
+\r
+ public static List<IGenericFileImport> getFileImportServices() {\r
+ ServiceReference<?>[] serviceReferences = new ServiceReference<?>[0];\r
+ try {\r
+ serviceReferences = Activator.getContext().getAllServiceReferences(IGenericFileImport.class.getName(),\r
+ null);\r
+ } catch (InvalidSyntaxException e) {\r
+ e.printStackTrace();\r
+ }\r
+ if (serviceReferences.length == 0)\r
+ return Collections.emptyList();\r
+\r
+ List<IGenericFileImport> services = new ArrayList<>(serviceReferences.length);\r
+ for (ServiceReference<?> reference : serviceReferences) {\r
+ IGenericFileImport service = (IGenericFileImport) Activator.getContext().getService(reference);\r
+ services.add(service);\r
+ }\r
+ return services;\r
+ }\r
+\r
+ public static Map<String, String> supportedExtensionsWithFilters() {\r
+ List<IGenericFileImport> services = getFileImportServices();\r
+ Map<String, String> extensionsWithFilters = new HashMap<>();\r
+ for (IGenericFileImport service : services)\r
+ extensionsWithFilters.putAll(service.allowedExtensionsWithFilters());\r
+\r
+ return extensionsWithFilters;\r
+ }\r
+\r
+ public static void performFileImport(Path file, Optional<Consumer<Throwable>> callback) {\r
+ if (file.getFileName().toString().equals(DB_FILE))\r
+ return;\r
+ Optional<IGenericFileImport> serviceOp = findServiceForFileExtension(file);\r
+ serviceOp.ifPresent(service -> {\r
+ try {\r
+ Optional<String> resource = service.perform(file);\r
+ saveResourceForPath(file, resource);\r
+ } catch (Throwable t) {\r
+ if (callback.isPresent()) {\r
+ callback.get().accept(t);\r
+ } else {\r
+ t.printStackTrace();\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ public static void removeResourceForFile(Path file, Optional<Consumer<Throwable>> callback) {\r
+ Optional<IGenericFileImport> serviceOp = findServiceForFileExtension(file);\r
+ serviceOp.ifPresent(service -> {\r
+ try {\r
+ Optional<String> resource = getResourceForPath(file);\r
+ if (!resource.isPresent())\r
+ return;\r
+ service.remove(resource.get());\r
+ removeResourceForPath(file);\r
+ } catch (Throwable t) {\r
+ if (callback.isPresent()) {\r
+ callback.get().accept(t);\r
+ } else {\r
+ t.printStackTrace();\r
+ }\r
+ }\r
+ });\r
+ }\r
+ \r
+ public static void removeFileForResource(long id, Optional<Consumer<Throwable>> callback) {\r
+ Optional<Path> fileOp;\r
+ try {\r
+ fileOp = findPathForId(id);\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ return;\r
+ }\r
+ if (!fileOp.isPresent())\r
+ return;\r
+ Path file = fileOp.get();\r
+ Optional<IGenericFileImport> serviceOp = findServiceForFileExtension(file);\r
+ serviceOp.ifPresent(service -> {\r
+ try {\r
+ Optional<String> resource = getResourceForPath(file);\r
+ if (!resource.isPresent())\r
+ return;\r
+ service.remove(resource.get());\r
+ removeResourceForPath(file);\r
+ } catch (Throwable t) {\r
+ if (callback.isPresent()) {\r
+ callback.get().accept(t);\r
+ } else {\r
+ t.printStackTrace();\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ private static Optional<Path> findPathForId(long id) throws IOException {\r
+ Path db = Activator.getDropinsFolder().resolve(DB_FILE);\r
+ if (!Files.exists(db))\r
+ Files.createFile(db);\r
+ Properties props = new Properties();\r
+ try (InputStream stream = Files.newInputStream(db)) {\r
+ props.load(stream);\r
+ }\r
+ for (Map.Entry<Object, Object> entry : props.entrySet()) {\r
+ Long value = Long.valueOf(entry.getValue().toString());\r
+ if (value.longValue() == id) {\r
+ String key = (String) entry.getKey();\r
+ return Optional.of(Paths.get(key));\r
+ }\r
+ }\r
+ return Optional.empty();\r
+ }\r
+\r
+ static final String FOLDER = "_folder_";\r
+ \r
+ public static Optional<IGenericFileImport> findServiceForFileExtension(Path file) {\r
+ String extension = "";\r
+\r
+ int i = file.getFileName().toString().lastIndexOf('.');\r
+ if (i > 0) {\r
+ extension = file.getFileName().toString().substring(i);\r
+ } else {\r
+ // Handle case that file is actually a directory\r
+ if (Files.isDirectory(file) || !Files.isRegularFile(file)) {\r
+ extension = FOLDER;\r
+ }\r
+ }\r
+\r
+ List<IGenericFileImport> services = getFileImportServices();\r
+ for (IGenericFileImport service : services) {\r
+ for (Map.Entry<String, String> entry : service.allowedExtensionsWithFilters().entrySet()) {\r
+ String possibleExtensions = entry.getKey();\r
+ if (possibleExtensions.startsWith("*"))\r
+ possibleExtensions = possibleExtensions.substring(1);\r
+ if (possibleExtensions.equals(extension) || possibleExtensions.isEmpty()) {\r
+ if (extension.equals(FOLDER) && possibleExtensions.equals(FOLDER)) {\r
+ return Optional.of(service);\r
+ } else if (!extension.isEmpty() && !extension.equals(FOLDER)){\r
+ return Optional.of(service);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return Optional.empty();\r
+ }\r
+ \r
+ public static Map<String, Long> getPathsAndResources() {\r
+ try {\r
+ Path db = Activator.getDropinsFolder().resolve(DB_FILE);\r
+ if (!Files.exists(db))\r
+ Files.createFile(db);\r
+ Properties props = new Properties();\r
+ try (InputStream stream = Files.newInputStream(db)) {\r
+ props.load(stream);\r
+ }\r
+ Map<String, Long> result = Simantics.getSession().syncRequest(new UniqueRead<Map<String, Long>>() {\r
+\r
+ @Override\r
+ public Map<String, Long> perform(ReadGraph graph) throws DatabaseException {\r
+ Map<String, Long> map = new HashMap<>();\r
+ for (Map.Entry<Object, Object> entry : props.entrySet()) {\r
+ String value = (String) entry.getValue();\r
+ Long id = Long.valueOf(value);\r
+ SerialisationSupport ss = graph.getService(SerialisationSupport.class);\r
+ try {\r
+ Resource r = ss.getResource(id);\r
+ String name = graph.getRelatedValue(r, Layer0.getInstance(graph).HasName);\r
+ map.put(name, id);\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return map;\r
+ }\r
+ });\r
+\r
+ return result;\r
+ } catch (IOException | DatabaseException e) {\r
+ e.printStackTrace();\r
+ return Collections.emptyMap();\r
+ }\r
+ }\r
+\r
+ private static void saveResourceForPath(Path file, Optional<String> resource) {\r
+ resource.ifPresent(res -> {\r
+ try {\r
+ Path db = Activator.getDropinsFolder().resolve(DB_FILE);\r
+ if (!Files.exists(db))\r
+ Files.createFile(db);\r
+ Properties props = new Properties();\r
+ try (InputStream stream = Files.newInputStream(db)) {\r
+ props.load(stream);\r
+ }\r
+ props.put(file.getFileName().toString(), resource.get());\r
+ try (OutputStream stream = Files.newOutputStream(db)) {\r
+ props.store(stream, null);\r
+ }\r
+ } catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+ });\r
+ }\r
+\r
+ private static void removeResourceForPath(Path file) throws IOException {\r
+ Path db = Activator.getDropinsFolder().resolve(DB_FILE);\r
+ if (!Files.exists(db))\r
+ Files.createFile(db);\r
+ Properties props = new Properties();\r
+ try (InputStream stream = Files.newInputStream(db)) {\r
+ props.load(stream);\r
+ }\r
+ props.remove(file.getFileName().toString());\r
+ try (OutputStream stream = Files.newOutputStream(db)) {\r
+ props.store(stream, null);\r
+ }\r
+ }\r
+ \r
+ private static Optional<String> getResourceForPath(Path file) throws IOException {\r
+ Path db = Activator.getDropinsFolder().resolve(DB_FILE);\r
+ if (!Files.exists(db))\r
+ Files.createFile(db);\r
+ Properties props = new Properties();\r
+ try (InputStream stream = Files.newInputStream(db)) {\r
+ props.load(stream);\r
+ }\r
+ String value = props.getProperty(file.getFileName().toString());\r
+ if (value == null)\r
+ return Optional.empty();\r
+ return Optional.of(value);\r
+ }\r
+}\r