X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2FPlatformUtil.java;fp=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2FPlatformUtil.java;h=5298df922f7ab54ebfc8d48085900bd0abe59ed2;hb=1f8b50d81a1aa1bbd67a77f7cbc1060f2eb805d4;hp=d5c88782a87e42d980773fd8542d8af087327e46;hpb=86bb6157fdcb4a11caee57487cf8fa894eaae2dd;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java b/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java index d5c88782a..5298df922 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/PlatformUtil.java @@ -26,7 +26,9 @@ import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; +import java.util.List; import java.util.Map.Entry; import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; @@ -62,7 +64,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class contains utilities for managing bundles in a active platform. + * This class contains utilities for managing bundles in a active platform. * */ @SuppressWarnings("restriction") @@ -82,13 +84,15 @@ public class PlatformUtil { /** * Get the manifest file of a bundle * - * @param bundle bundle + * @param bundle + * bundle * @return manifest or null if doesn't not exist - * @throws IOException + * @throws IOException */ public static Manifest getManifest(Bundle bundle) throws IOException { URL url = bundle.getEntry("META-INF/MANIFEST.MF"); - if (url==null) return null; + if (url == null) + return null; try (InputStream is = url.openStream()) { return new Manifest(is); } @@ -97,39 +101,41 @@ public class PlatformUtil { /** * Get the manifest file of a bundle * - * @param bundle bundle + * @param bundle + * bundle * @return manifest or null if doesn't not exist - * @throws IOException + * @throws IOException */ public static Manifest getSimanticsManifest(Bundle bundle) throws IOException { URL url = bundle.getEntry("META-INF/SIMANTICS.MF"); - if (url==null) return null; + if (url == null) + return null; try (InputStream is = url.openStream()) { return new Manifest(is); } } - + /** - * Get a list (BundleIds) of all user installable units. These are the - * top-level items that are visible for the end-user. - * The list is acquired from the bundles of the current application. + * Get a list (BundleIds) of all user installable units. These are the top-level + * items that are visible for the end-user. The list is acquired from the + * bundles of the current application. * - * @param list of simantics features URIs - * @throws IOException + * @param list + * of simantics features URIs + * @throws IOException */ - public static void getUserInstallableUnits(Collection list) - throws IOException - { + public static void getUserInstallableUnits(Collection list) throws IOException { for (Bundle bundle : getBundles()) { Manifest manifest = getSimanticsManifest(bundle); - if (manifest==null) continue; + if (manifest == null) + continue; Attributes attributes = manifest.getMainAttributes(); for (Entry entry2 : attributes.entrySet()) { Object key = entry2.getKey(); - if (key.toString().contains("Installable-Unit")) { - String bid = entry2.getValue().toString(); - list.add( bid ); - } + if (key.toString().contains("Installable-Unit")) { + String bid = entry2.getValue().toString(); + list.add(bid); + } } } } @@ -137,69 +143,72 @@ public class PlatformUtil { /** * Get all transferable graphs in the platform * - * @param result collection to be filled with transferable graph info + * @param result + * collection to be filled with transferable graph info */ public static void getPlatformTGInfos(Collection result) { for (Bundle bundle : getBundles()) { Enumeration e = bundle.findEntries("graphs/", "*.tg", false); - if (e==null) continue; + if (e == null) + continue; while (e.hasMoreElements()) { org.osgi.framework.Version osgiVersion = bundle.getVersion(); - Version p2Version = Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), osgiVersion.getQualifier()); + Version p2Version = Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), + osgiVersion.getMicro(), osgiVersion.getQualifier()); String id = bundle.getSymbolicName(); TGInfo info = new TGInfo(); info.location = e.nextElement(); info.bundle = bundle; info.vid = new VersionedId(id, p2Version); - result.add( info ); + result.add(info); + } + } + } + + private static void uncheckedClose(Closeable closeable) { + try { + if (closeable != null) + closeable.close(); + } catch (IOException e) { + // ignore + } + } + + private static File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException { + FileOutputStream os = null; + InputStream is = null; + try { + if (targetFile.exists()) + targetFile.delete(); + + is = url.openStream(); + int read; + byte[] buffer = new byte[16384]; + os = new FileOutputStream(targetFile); + while ((read = is.read(buffer)) != -1) { + os.write(buffer, 0, read); } + os.close(); + is.close(); + + return targetFile; + } finally { + uncheckedClose(os); + uncheckedClose(is); } } - private static void uncheckedClose(Closeable closeable) { - try { - if (closeable != null) - closeable.close(); - } catch (IOException e) { - //ignore - } - } - - private static File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException { - FileOutputStream os = null; - InputStream is = null; - try { - if (targetFile.exists()) - targetFile.delete(); - - is = url.openStream(); - int read; - byte [] buffer = new byte [16384]; - os = new FileOutputStream (targetFile); - while ((read = is.read (buffer)) != -1) { - os.write(buffer, 0, read); - } - os.close (); - is.close (); - - return targetFile; - } finally { - uncheckedClose(os); - uncheckedClose(is); - } - } - - private static File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException { - String tmpDirStr = System.getProperty("java.io.tmpdir"); - if (tmpDirStr == null) - throw new NullPointerException("java.io.tmpdir property is null"); - File tmpDir = new File(tmpDirStr); - File libFile = new File(tmpDir, libName); - return copyResource(libURL, libFile); - } - - private static File url2file(URL url, String fileName) { + private static File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException { + String tmpDirStr = System.getProperty("java.io.tmpdir"); + if (tmpDirStr == null) + throw new NullPointerException("java.io.tmpdir property is null"); + File tmpDir = new File(tmpDirStr); + File libFile = new File(tmpDir, libName); + return copyResource(libURL, libFile); + } + + private static File url2file(URL url, String fileName) { if ("file".equals(url.getProtocol())) { try { File path = new File(URLDecoder.decode(url.getPath(), "UTF-8")); @@ -218,27 +227,41 @@ public class PlatformUtil { } } else { LOGGER.error("Unsupported URL protocol '" + url + "' for FastLZ native library file '" + fileName); - } + } return null; } + public static Collection getTGFiles(Bundle b) { + Enumeration enu = b.findEntries("/", "*.tg", false); + if (enu == null) + return Collections.emptyList(); + if (!enu.hasMoreElements()) + return Collections.emptyList(); + ArrayList result = new ArrayList<>(); + while (enu.hasMoreElements()) { + result.add(enu.nextElement()); + } + return result; + } + public static void compile(Bundle b) throws Exception { Collection sources = new ArrayList<>(); Collection dependencies = new ArrayList<>(); for (Bundle b2 : getBundles()) { - if(b.equals(b2)) continue; - URL url = b2.getEntry("graph.tg"); - if (url==null) continue; - File graphFile = url2file(FileLocator.resolve(b2.getEntry("/graph.tg")), b2.toString()); - dependencies.add(GraphCompiler.read(graphFile)); + if (b.equals(b2)) + continue; + for (URL url : getTGFiles(b2)) { + File graphFile = url2file(url, b2.toString() + url.toString()); + dependencies.add(GraphCompiler.read(graphFile)); + } } File bundleFile = FileLocator.getBundleFile(b); - if(bundleFile.isDirectory()) { + if (bundleFile.isDirectory()) { File folder = new File(bundleFile, "dynamicGraph"); - for(File f : folder.listFiles(new FilenameFilter() { + for (File f : folder.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { @@ -250,22 +273,23 @@ public class PlatformUtil { } } -// System.out.println("source is " + tmpFile.getAbsolutePath()); + // System.out.println("source is " + tmpFile.getAbsolutePath()); final StringBuilder errorStringBuilder = new StringBuilder(); GraphCompilerPreferences prefs = new GraphCompilerPreferences(); prefs.validate = true; prefs.validateRelationRestrictions = ValidationMode.ERROR; prefs.validateResourceHasType = ValidationMode.ERROR; - String currentLayer0Version = OntologyVersions.getInstance().currentOntologyVersion("http://www.simantics.org/Layer0-0.0"); + String currentLayer0Version = OntologyVersions.getInstance() + .currentOntologyVersion("http://www.simantics.org/Layer0-0.0"); CompilationResult result = GraphCompiler.compile(currentLayer0Version, sources, dependencies, null, prefs); - for(Problem problem : result.getErrors()) + for (Problem problem : result.getErrors()) errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n"); - for(Problem problem : result.getWarnings()) + for (Problem problem : result.getWarnings()) errorStringBuilder.append(problem.getLocation() + ": " + problem.getDescription() + "\n"); - if(errorStringBuilder.length() > 0) { + if (errorStringBuilder.length() > 0) { LOGGER.error(errorStringBuilder.toString()); } else { GraphCompiler.write(new File(bundleFile, "graph.tg"), result.getGraph()); @@ -281,15 +305,15 @@ public class PlatformUtil { */ public static void compileAllDynamicOntologies() { for (Bundle bundle : getBundles()) { - if(bundle.getEntry("dynamicGraph") != null) { + if (bundle.getEntry("dynamicGraph") != null) { try { File bundleFile = FileLocator.getBundleFile(bundle); - if(bundleFile.isDirectory()) { + if (bundleFile.isDirectory()) { File tg = new File(bundleFile, "graph.tg"); long tgLastModified = tg.lastModified(); File folder = new File(bundleFile, "dynamicGraph"); - for(File f : folder.listFiles()) { - if(f.isFile() && f.getName().endsWith(".pgraph") && f.lastModified() > tgLastModified) { + for (File f : folder.listFiles()) { + if (f.isFile() && f.getName().endsWith(".pgraph") && f.lastModified() > tgLastModified) { compile(bundle); break; } @@ -311,24 +335,45 @@ public class PlatformUtil { public static Collection getAllGraphs() throws IOException { AtomicReference problem = new AtomicReference<>(); + // Collection gbundles = Arrays.stream(getBundles()) + // // #7806: Due to databoard Binding/Serializer construction process + // thread-unsafety + // // not even the DataContainer.readHeader invocations can run in parallel, + // most likely + // // due to recurring serializer construction for Variant datatypes. + // // Therefore, we must disable parallel loading for now. + // //.parallel() + // .map(b -> { + // try { + // return problem.get() == null ? getGraph(b) : null; + // } catch (IOException e) { + // if (LOGGER.isDebugEnabled()) + // LOGGER.debug("Could not get graph from bundle {}", b, e); + // problem.set(e); + // return null; + // } + // }) + // .filter(Objects::nonNull) + // .collect(Collectors.toList()); + Collection gbundles = Arrays.stream(getBundles()) - // #7806: Due to databoard Binding/Serializer construction process thread-unsafety - // not even the DataContainer.readHeader invocations can run in parallel, most likely + // #7806: Due to databoard Binding/Serializer construction process + // thread-unsafety + // not even the DataContainer.readHeader invocations can run in parallel, most + // likely // due to recurring serializer construction for Variant datatypes. // Therefore, we must disable parallel loading for now. - //.parallel() + // .parallel() .map(b -> { try { - return problem.get() == null ? getGraph(b) : null; + return problem.get() == null ? getGraphs(b) : null; } catch (IOException e) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Could not get graph from bundle {}", b, e); problem.set(e); return null; } - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + }).flatMap(Collection::stream).filter(Objects::nonNull).collect(Collectors.toList()); if (problem.get() != null) throw problem.get(); @@ -336,24 +381,27 @@ public class PlatformUtil { } /** - * Get bundle + * Get bundle * * @param symbolicName - * @return bundle or null if there is no bundle or graph + * @return bundle or null if there is no bundle or graph * @throws IOException */ public static GraphBundle getGraph(String symbolicName) throws IOException { Bundle bundle = Platform.getBundle(symbolicName); - if (bundle == null) return null; - return getGraph( bundle ); + if (bundle == null) + return null; + return getGraph(bundle); } /** - * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the root. + * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the + * root. * * @param bundle - * @return transferable graph, or null if there is no graph in the bundle. - * @throws IOException + * @return transferable graph, or null if there is no graph in the + * bundle. + * @throws IOException */ public static GraphBundleEx getGraph(Bundle bundle) throws IOException { URL url = bundle.getEntry("graph.tg"); @@ -363,13 +411,24 @@ public class PlatformUtil { return result != null ? result : getCompleteGraph(bundle, url); } + public static Collection getGraphs(Bundle bundle) throws IOException { + return getTGFiles(bundle).stream().map(url -> { + try { + GraphBundleEx result = tryGetOnDemandGraph(bundle, url); + return result != null ? result : getCompleteGraph(bundle, url); + } catch (IOException e) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Could not get graph from bundle url {}", url, e); + return null; + } + }).filter(Objects::nonNull).collect(Collectors.toList()); + } + private static GraphBundleEx getCompleteGraph(Bundle bundle, URL url) throws IOException { try { - String id = bundle.getSymbolicName(); - return new GraphBundleEx( - getBundleName(bundle, id), - readTG(url), - new VersionedId(id, toP2Version(bundle)), + String id = tgFileId(bundle, url); + System.err.println("getCompleteGraph " + id); + return new GraphBundleEx(getBundleName(bundle, id), readTG(url), new VersionedId(id, toP2Version(bundle)), isImmutable(bundle)); } catch (Exception e) { throw new IOException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e); @@ -378,13 +437,21 @@ public class PlatformUtil { throw e; } } + + private static String tgFileId(Bundle bundle, URL url) { + String urlString = url.toString(); + String file = urlString.substring(urlString.lastIndexOf("/")+1); + return bundle.getSymbolicName() + "_" + file; + } /** - * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the root. + * Read the graph in a graph bundle. Graph is read from "graph.tg" file in the + * root. * * @param bundle - * @return transferable graph, or null if there is no graph in the bundle. - * @throws IOException + * @return transferable graph, or null if there is no graph in the + * bundle. + * @throws IOException */ private static GraphBundleEx tryGetOnDemandGraph(Bundle bundle, URL url) throws IOException { try { @@ -405,14 +472,12 @@ public class PlatformUtil { } }; - String id = bundle.getSymbolicName(); + String id = tgFileId(bundle, url); + + System.err.println("tryGetOnDemandGraph: " + id); - return new GraphBundleEx( - getBundleName(bundle, id), - graphSource, - cachedHash, - new VersionedId(id, toP2Version(bundle)), - isImmutable(bundle)); + return new GraphBundleEx(getBundleName(bundle, id), graphSource, cachedHash, + new VersionedId(id, toP2Version(bundle)), isImmutable(bundle)); } catch (Exception e) { throw new IOException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e); } @@ -438,7 +503,8 @@ public class PlatformUtil { private static Version toP2Version(Bundle bundle) { org.osgi.framework.Version osgiVersion = bundle.getVersion(); - return Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), osgiVersion.getQualifier()); + return Version.createOSGi(osgiVersion.getMajor(), osgiVersion.getMinor(), osgiVersion.getMicro(), + osgiVersion.getQualifier()); } private static String getBundleName(Bundle bundle, String id) {