X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.fileimport%2Fsrc%2Forg%2Fsimantics%2Ffileimport%2FFileImportService.java;h=5f9c7257b7da977057d5ac6ef3951aff787724bb;hb=664f37a026967c90a9a8a4ef3c5336ee426f67aa;hp=fcbd3cc30c33a04f87993e8307a1fda32b895fc4;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;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 fcbd3cc30..5f9c7257b 100644 --- a/bundles/org.simantics.fileimport/src/org/simantics/fileimport/FileImportService.java +++ b/bundles/org.simantics.fileimport/src/org/simantics/fileimport/FileImportService.java @@ -13,11 +13,17 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Properties; +import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Collectors; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; +import org.simantics.databoard.util.Base64; +import org.simantics.db.Resource; import org.simantics.fileimport.dropins.FileImportDropins; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility class for Simantics File import functions @@ -27,6 +33,8 @@ import org.simantics.fileimport.dropins.FileImportDropins; */ public class FileImportService { + private static final Logger LOGGER = LoggerFactory.getLogger(FileImportService.class); + private FileImportService() {} public static final String DB_FILE = ".simanticsdb"; @@ -37,7 +45,7 @@ public class FileImportService { serviceReferences = Activator.getContext().getAllServiceReferences(IGenericFileImport.class.getName(), null); } catch (InvalidSyntaxException e) { - e.printStackTrace(); + LOGGER.error("Could not get service references for IGenericFileImport!", e); } if (serviceReferences.length == 0) return Collections.emptyList(); @@ -63,31 +71,73 @@ public class FileImportService { return extensionsWithFilters; } + + private static class ConsumerHolder implements Consumer { + private Throwable throwable; + + @Override + public void accept(Throwable t) { + throwable = t; + } + + public Throwable getThrowable() { + return throwable; + } + + } + + public static String performFileImport(String base64, String name) throws Throwable { + byte[] bytes = Base64.decode(base64); + Path file = Activator.getModelsFolder().resolve(name); + Files.write(file, bytes); + + ConsumerHolder holder = new ConsumerHolder(); + String result = performFileImport(file, Optional.empty(), Optional.of(holder)); + if (holder.getThrowable() != null) + throw holder.getThrowable(); + return result; + } + /** * 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 possibleSelection - the selected resource (if exists) * @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 -> { + public static String performFileImport(Path file, Optional possibleSelection, Optional> callback) { + if (file.getFileName().toString().equals(DB_FILE)) { + return null; + } + String result = "Import failed"; + IGenericFileImport service = findServiceForFileExtension(file); + + if (service != null) { try { - Optional resource = service.perform(file); + Optional resource; + if (possibleSelection.isPresent() && service.defaultParentResource() == null) { + resource = Optional.of(Long.toString(service.perform(possibleSelection.get(), file).get().getResourceId())); + } + else { + resource = service.performWithDefaultParent(file); + } saveResourceForPath(file, resource); + result = resource.get(); } catch (Throwable t) { if (callback.isPresent()) { callback.get().accept(t); } else { - t.printStackTrace(); + LOGGER.error("Could not import file " + file, t); } } - }); + } else { + LOGGER.warn("Could not find service for importing file " + file); + if (callback.isPresent()) + callback.get().accept(new Exception("Could not find IGenericFileImport service for file " + file)); + } + return result; } - /** * 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 @@ -96,22 +146,25 @@ public class FileImportService { * @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(); - } + try { + Optional resource = getResourceForPath(file); + if (!resource.isPresent()) + return; + IGenericFileImport service = findServiceForFileExtension(file); + if (service == null) { + LOGGER.warn("Could not find service for importing file " + file); + if (callback.isPresent()) + callback.get().accept(new Exception("Could not find IGenericFileImport service for file " + file)); } - }); + service.remove(resource.get()); + removeResourceForPath(file); + } catch (Throwable t) { + if (callback.isPresent()) { + callback.get().accept(t); + } else { + LOGGER.error("Could not remove resource for file " + file.toAbsolutePath(), t); + } + } } public static void removeFileForResource(long id, Optional> callback) { @@ -119,33 +172,37 @@ public class FileImportService { try { fileOp = findPathForId(id); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Could not remove file for resource id " + id, e); 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; + IGenericFileImport service = findServiceForFileExtension(file); + if (service == null) { + LOGGER.warn("Could not find service for importing file " + file); + if (callback.isPresent()) + callback.get().accept(new Exception("Could not find IGenericFileImport service for file " + file)); + } + service.remove(resource.get()); + removeResourceForPath(file); 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(); - } + Files.delete(file); + } catch (IOException e) { + Files.delete(file); } - }); + } catch (Throwable t) { + if (callback.isPresent()) { + callback.get().accept(t); + } else { + LOGGER.error("Could not remove file for resource " + id, t); + } + } } private static Optional findPathForId(long id) throws IOException { @@ -172,9 +229,9 @@ public class FileImportService { * 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 + * @return Optional IGenerigFileImport service which is able to handle the import of this type of file */ - public static Optional findServiceForFileExtension(Path file) { + public static IGenericFileImport findServiceForFileExtension(Path file) { String extension = ""; int i = file.getFileName().toString().lastIndexOf('.'); @@ -186,7 +243,30 @@ public class FileImportService { extension = FOLDER; } } + return findServiceForExtension(extension); + } + + public static List filterSupportedExtensions(String filter) { + return getFileImportServices().stream().filter(s -> s.allowedExtensionsWithFilters().keySet().contains(filter)).map(s -> s.allowedExtensionsWithFilters().keySet()).flatMap(Set::stream).collect(Collectors.toList()); + } + public static IGenericFileImport findServiceForExtension(String extension) { + List services = findServicesForExtension(extension); + IGenericFileImport service = null; + if (services.size() == 1) { + service = services.get(0); + } else { + for (IGenericFileImport servicee : services) { + service = servicee; + if (isPerfectMatch(servicee.allowedExtensionsWithFilters().keySet(), extension)) + break; + } + } + return service; + } + + public static List findServicesForExtension(String extension) { + List result = new ArrayList<>(); List services = getFileImportServices(); for (IGenericFileImport service : services) { for (Map.Entry entry : service.allowedExtensionsWithFilters().entrySet()) { @@ -195,14 +275,14 @@ public class FileImportService { possibleExtensions = possibleExtensions.substring(1); if (possibleExtensions.equals(extension) || possibleExtensions.isEmpty()) { if (extension.equals(FOLDER) && possibleExtensions.equals(FOLDER)) { - return Optional.of(service); + result.add(service); } else if (!extension.isEmpty() && !extension.equals(FOLDER)){ - return Optional.of(service); + result.add(service); } } } } - return Optional.empty(); + return result; } /** @@ -227,7 +307,7 @@ public class FileImportService { } return map; } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Could not get current paths and resources!", e); return Collections.emptyMap(); } } @@ -247,7 +327,7 @@ public class FileImportService { props.store(stream, null); } } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Could not save resource for path " + file.toAbsolutePath() + " and resource " + resource.get(), e); } }); } @@ -279,4 +359,41 @@ public class FileImportService { return Optional.empty(); return Optional.of(value); } + + /** + * Calls the proper imported without a selection (null possibleSelection) + * @param path + * @param extension + * @return + * @throws Exception + */ + public static String importGenericFileWithExtension(String path, String extension) throws Exception { + IGenericFileImport service = findServiceForExtension(extension); + Optional result = service.performWithDefaultParent(Paths.get(path)); + return result.get(); + } + + /** + * Calls the proper imported without a selection (null possibleSelection) + * @param parent + * @param path + * @param extension + * @return + * @throws Exception + */ + public static Resource importGenericFileWithExtensionAndParent(Resource parent, String path, String extension) throws Exception { + IGenericFileImport service = findServiceForExtension(extension); + Optional result = service.perform(parent, Paths.get(path)); + return result.get(); + } + + private static boolean isPerfectMatch(Set candidates, String extension) { + for (String ext : candidates) { + if (ext.startsWith("*")) + ext = ext.substring(1); + if (ext.equals(extension)) + return true; + } + return false; + } }