X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.fileimport%2Fsrc%2Forg%2Fsimantics%2Ffileimport%2FFileImportService.java;h=fcbd3cc30c33a04f87993e8307a1fda32b895fc4;hb=refs%2Fchanges%2F38%2F238%2F2;hp=e07dfaadd5d5999af4b6ddbfe2256bb623ee062a;hpb=b35573372259ace60d8827766fe41443f4c57629;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 index e07dfaadd..fcbd3cc30 100644 --- a/bundles/org.simantics.fileimport/src/org/simantics/fileimport/FileImportService.java +++ b/bundles/org.simantics.fileimport/src/org/simantics/fileimport/FileImportService.java @@ -1,261 +1,282 @@ -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); - } -} +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.fileimport.dropins.FileImportDropins; + +/** + * Utility class for Simantics File import functions + * + * @author Jani Simomaa + * + */ +public class FileImportService { + + private FileImportService() {} + + public static final String DB_FILE = ".simanticsdb"; + + private 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; + } + + /** + * Lists all supported file extensions which have a registered service for handling the import + * + * @return Map containing the extension and the description of the extension in that order + */ + public static Map supportedExtensionsWithFilters() { + List services = getFileImportServices(); + Map extensionsWithFilters = new HashMap<>(); + for (IGenericFileImport service : services) + extensionsWithFilters.putAll(service.allowedExtensionsWithFilters()); + + return extensionsWithFilters; + } + + /** + * Method that performs the import of the given file. This method is called when e.g. {@link FileImportDropins} watcher detects {@link java.nio.file.StandardWatchEventKinds.ENTRY_CREATE} operation + * + * @param file Path file to be imported + * @param callback Optional callback which can be used to catch Throwables thrown in the import process + */ + 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(); + } + } + }); + } + + + /** + * Remove the entity that matches the file. This method is called when e.g. the {@link FileImportDropins} watcher detects {@link java.nio.file.StandardWatchEventKinds.ENTRY_DELETE} operation + * + * @param file Path file that was deleted + * @param callback Optional callback to catch Throwables thrown during the deletion process + */ + 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); + try { + Files.delete(file); + } catch (IOException e) { + Files.delete(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_"; + + /** + * Method for finding a File Import service for the given file based on the file extension + * + * @param file Path file for which the import service is looked for + * @return Optiona IGenerigFileImport service which is able to handle the import of this type of file + */ + 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(); + } + + /** + * Method for listing all current paths and their corresponding identifiers in Simantics database + * + * @return Map containing + */ + 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 map = new HashMap<>(); + for (Map.Entry entry : props.entrySet()) { + String value = (String) entry.getValue(); + String key = (String) entry.getKey(); + map.put(key, value); + } + return map; + } catch (IOException 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); + } +}