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