-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.project.management;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.Collection;\r
-import java.util.Comparator;\r
-import java.util.Enumeration;\r
-import java.util.Iterator;\r
-import java.util.Set;\r
-import java.util.TreeSet;\r
-import java.util.jar.JarEntry;\r
-import java.util.jar.JarFile;\r
-import java.util.jar.JarInputStream;\r
-import java.util.jar.Manifest;\r
-\r
-import org.eclipse.core.runtime.Path;\r
-import org.eclipse.equinox.internal.p2.metadata.RequiredCapability;\r
-import org.eclipse.equinox.internal.p2.touchpoint.eclipse.Util;\r
-import org.eclipse.equinox.internal.p2.ui.query.RequiredIUsQuery;\r
-import org.eclipse.equinox.p2.core.IProvisioningAgent;\r
-import org.eclipse.equinox.p2.core.ProvisionException;\r
-import org.eclipse.equinox.p2.metadata.IArtifactKey;\r
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;\r
-import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;\r
-import org.eclipse.equinox.p2.metadata.IRequirement;\r
-import org.eclipse.equinox.p2.metadata.Version;\r
-import org.eclipse.equinox.p2.publisher.AdviceFileAdvice;\r
-import org.eclipse.equinox.p2.publisher.PublisherInfo;\r
-import org.eclipse.equinox.p2.publisher.eclipse.BundleShapeAdvice;\r
-import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction;\r
-import org.eclipse.equinox.p2.publisher.eclipse.IBundleShapeAdvice;\r
-import org.eclipse.equinox.p2.query.IQuery;\r
-import org.eclipse.equinox.p2.query.IQueryResult;\r
-import org.eclipse.equinox.p2.query.IQueryable;\r
-import org.eclipse.equinox.p2.query.QueryUtil;\r
-import org.eclipse.equinox.p2.repository.artifact.ArtifactKeyQuery;\r
-import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;\r
-import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;\r
-import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;\r
-import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;\r
-import org.eclipse.osgi.service.resolver.BundleDescription;\r
-import org.osgi.framework.BundleException;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Files;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.util.StreamUtil;\r
-import org.simantics.graph.db.TransferableGraphException;\r
-import org.simantics.graph.representation.TransferableGraph1;\r
-\r
-/**\r
- * This class contains provisioning utilities.\r
- *\r
- * @see QueryUtil\r
- * @see Util\r
- * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
- */\r
-@SuppressWarnings("restriction")\r
-public class ProvisioningUtil {\r
-\r
- private static IRequirement IS_FEATURE_REQUIREMENT = new RequiredCapability("org.eclipse.equinox.p2.eclipse.type", "feature", null, null, false, false, false);\r
-\r
- public static void getAllRequirements(IInstallableUnit iu, IQueryable<IInstallableUnit> repo, Set<IInstallableUnit> result) \r
- {\r
- if (result.contains(iu)) return;\r
- result.add(iu);\r
- IQuery<IInstallableUnit> reqsQuery = new RequiredIUsQuery(iu);\r
- for (IInstallableUnit _iu : repo.query( reqsQuery, null ).toSet()) {\r
- if (result.contains(_iu)) continue;\r
- getAllRequirements(_iu, repo, result);\r
- } \r
- }\r
- \r
- \r
- /**\r
- * Get IUs that are required to install this bundle. \r
- * Assumed architecture is x86 and os win32. \r
- * Throws an exception if not all requirements can be satisfied.\r
- * \r
- * @param iu\r
- * @param availableIUs\r
- * @return\r
- */\r
- /*\r
- public static Collection<IRequirement> getAllRequirements(IInstallableUnit iu, IQueryable<IInstallableUnit> repo)\r
- { \r
- // Installable Units analysed\r
- Set<IInstallableUnit> ius = new HashSet<IInstallableUnit>();\r
- \r
- // Requirements\r
- Set<IRequirement> reqs = new HashSet<IRequirement>();\r
- \r
- // Satisfied requirements\r
- Set<IRequirement> sats = new HashSet<IRequirement>();\r
- ius.add(iu);\r
- reqs.addAll( iu.getRequirements() );\r
- \r
- // Find satisfactions\r
- return result;\r
- }*/\r
- /*\r
- static void _addIU(IInstallableUnit iu, Set<IInstallableUnit> ius, Set<IRequirement> reqs, Set<IRequirement> sats, Set<IRequirement> unsats, IQueryable<IInstallableUnit> repo) \r
- {\r
- if (ius.contains(iu)) return;\r
- ius.add( iu );\r
- \r
- for (IRequirement req : iu.getRequirements()) {\r
- if (sats.contains(req)) continue;\r
- if (unsats.contains(req)) continue;\r
- \r
- // req is unsatisfied\r
- IQuery\r
- IQueryResult<IInstallableUnit> result = repo.query(req, null);\r
- }\r
- \r
- for (IInstallableUnit _iu : availableIUs) {\r
- if (sats.contains(_iu)) continue;\r
- \r
- boolean satisfies = _iu.satisfies( ) \r
- }\r
- }*/\r
- \r
- /**\r
- * Get all installable units from a metadata repository\r
- * \r
- * @param repo\r
- * @return\r
- */\r
- public static Collection<IInstallableUnit> getInstallableUnits(IMetadataRepository repo) {\r
- \r
-// IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(null, VersionRange.emptyRange);\r
- IQuery<IInstallableUnit> query = QueryUtil.createIUAnyQuery();\r
- IQueryResult<IInstallableUnit> matches = repo.query(query, null);\r
- return matches.toUnmodifiableSet();\r
- }\r
- \r
-\r
- /**\r
- * Test if the {@link IInstallableUnit} is a category. \r
- * @param iu the element being tested.\r
- * @return <tt>true</tt> if the parameter is a category.\r
- */\r
- public static boolean isCategory(IInstallableUnit iu) {\r
- String PROP_TYPE_CATEGORY = "org.eclipse.equinox.p2.type.category"; //$NON-NLS-1$\r
- String value = iu.getProperty(PROP_TYPE_CATEGORY);\r
- if (value != null && (value.equals(Boolean.TRUE.toString())))\r
- return true;\r
- return false;\r
- }\r
-\r
- /**\r
- * Test if the {@link IInstallableUnit} is a fragment. \r
- * @param iu the element being tested.\r
- * @return <tt>true</tt> if the parameter is a fragment.\r
- */\r
- public static boolean isFragment(IInstallableUnit iu) {\r
- return iu instanceof IInstallableUnitFragment;\r
- }\r
-\r
- /**\r
- * Test if the {@link IInstallableUnit} is a group. \r
- * @param iu the element being tested.\r
- * @return <tt>true</tt> if the parameter is a group.\r
- */\r
- public static boolean isGroup(IInstallableUnit iu) {\r
- String PROP_TYPE_GROUP = "org.eclipse.equinox.p2.type.group"; //$NON-NLS-1$\r
- String value = iu.getProperty(PROP_TYPE_GROUP);\r
- if (value != null && (value.equals(Boolean.TRUE.toString())))\r
- return true;\r
- return false;\r
- }\r
-\r
- /**\r
- * Test if the {@link IInstallableUnit} is a patch. \r
- * @param iu the element being tested.\r
- * @return <tt>true</tt> if the parameter is a patch.\r
- */\r
- public static boolean isPatch(IInstallableUnit iu) {\r
- String PROP_TYPE_PATCH = "org.eclipse.equinox.p2.type.patch"; //$NON-NLS-1$\r
- String value = iu.getProperty(PROP_TYPE_PATCH);\r
- if (value != null && (value.equals(Boolean.TRUE.toString())))\r
- return true;\r
- return false;\r
- }\r
- \r
- /**\r
- * Checks whether a installable unit is a feature\r
- * \r
- * @param iu\r
- * @return <code>true</code> if is feature\r
- */\r
- public static boolean isFeature(IInstallableUnit iu) {\r
-// String value = iu.getProperty("org.eclipse.equinox.p2.eclipse.type");\r
-// return value != null && value.equals("feature");\r
- return iu.satisfies(IS_FEATURE_REQUIREMENT);\r
- }\r
-\r
- public static boolean isGraph(IInstallableUnit iu, IMetadataRepository metadata, IArtifactRepository arts) throws IOException {\r
- Collection<IArtifactKey> artifacts = iu.getArtifacts();\r
- for (IArtifactKey key : artifacts) {\r
- if (isGraphArtifact(arts, key)) return true; \r
- }\r
- return false;\r
- }\r
-\r
- /**\r
- * Checks whether artifact is a graph bundle. \r
- * \r
- * @param repo artifact repo\r
- * @param key key to artifact\r
- * @return <code>true</code> if is a graph bundle\r
- * @throws IOException \r
- */\r
- public static boolean isGraphArtifact(IArtifactRepository repo, IArtifactKey key) throws IOException {\r
- return hasFile(repo, key, "graph.tg");\r
- }\r
- \r
- public static boolean hasFile(IArtifactRepository repo, IArtifactKey key, String filename) throws IOException {\r
- boolean isBundle = key.getClassifier().equals("osgi.bundle");\r
- if (!isBundle) return false;\r
- \r
- for (IArtifactDescriptor desc : repo.getArtifactDescriptors(key)) { \r
- if (repo instanceof IFileArtifactRepository) { \r
- IFileArtifactRepository filerepo = (IFileArtifactRepository) repo;\r
- File f = filerepo.getArtifactFile(key);\r
- if (!f.exists()) return false;\r
- \r
- boolean isJar = f.getName().toLowerCase().endsWith(".jar");\r
- if (!isJar) return false;\r
- \r
- JarFile jf = new JarFile(f);\r
- try {\r
- Enumeration<JarEntry> enm = jf.entries();\r
- while (enm.hasMoreElements()) {\r
- JarEntry entry = enm.nextElement();\r
- String entryName = entry.getName();\r
- if ( entryName.equals(filename) ) return true;\r
- }\r
- } finally {\r
- jf.close();\r
- }\r
- \r
- } else {\r
- int size = Integer.valueOf( desc.getProperties().get("download.size") );\r
- ByteArrayOutputStream bos = new ByteArrayOutputStream(size);\r
- repo.getArtifact(desc, bos, null);\r
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());\r
- JarInputStream jis = new JarInputStream( bis );\r
- for (JarEntry entry = jis.getNextJarEntry(); entry!=null; entry = jis.getNextJarEntry()) {\r
- String entryName = entry.getName();\r
- if ( entryName.equals(filename) ) return true;\r
- } \r
- \r
- }\r
- }\r
- return false;\r
- }\r
-\r
- /**\r
- * Get a file from a repository\r
- * \r
- * @param repo artifact repo\r
- * @param key key to artifact\r
- * @return input stream (must be closed) or null\r
- * @throws IOException \r
- */\r
- public static InputStream getFile(IArtifactRepository repo, IArtifactKey key, String filename) throws IOException {\r
- boolean isBundle = key.getClassifier().equals("osgi.bundle");\r
- if (!isBundle) return null;\r
- \r
- for (IArtifactDescriptor desc : repo.getArtifactDescriptors(key)) { \r
- if (repo instanceof IFileArtifactRepository) { \r
- IFileArtifactRepository filerepo = (IFileArtifactRepository) repo;\r
- File f = filerepo.getArtifactFile(key);\r
- if (!f.exists()) return null;\r
- \r
- boolean isJar = f.getName().toLowerCase().endsWith(".jar");\r
- if (!isJar) return null;\r
- \r
- JarFile jf = new JarFile(f);\r
- try {\r
- Enumeration<JarEntry> enm = jf.entries();\r
- while (enm.hasMoreElements()) {\r
- JarEntry entry = enm.nextElement();\r
- String entryName = entry.getName();\r
- if (! entryName.equals(filename) ) continue;\r
- InputStream is = jf.getInputStream(entry);\r
- byte[] data = StreamUtil.readFully(is); \r
- is.close();\r
- return new ByteArrayInputStream(data);\r
- }\r
- } finally {\r
- jf.close();\r
- }\r
- \r
- } else {\r
- int size = Integer.valueOf( desc.getProperties().get("download.size") );\r
- ByteArrayOutputStream bos = new ByteArrayOutputStream(size);\r
- repo.getArtifact(desc, bos, null);\r
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());\r
- JarInputStream jis = new JarInputStream( bis );\r
- for (JarEntry entry = jis.getNextJarEntry(); entry!=null; entry = jis.getNextJarEntry()) {\r
- String entryName = entry.getName();\r
- if (! entryName.equals(filename) ) continue; \r
- return jis;\r
- } \r
- \r
- }\r
- }\r
- return null;\r
- } \r
- /**\r
- * Checks whether artifact is a graph bundle. \r
- * \r
- * @param repo artifact repo\r
- * @param key key to artifact\r
- * @return manifest or null\r
- * @throws IOException \r
- */\r
- public static Manifest getManifest(IArtifactRepository repo, IArtifactKey key) throws IOException {\r
- InputStream is = getFile(repo, key, "META-INF/MANIFEST.MF");\r
- if (is == null) return null;\r
- try {\r
- return new Manifest(is);\r
- } finally {\r
- is.close();\r
- }\r
- }\r
- \r
- /**\r
- * Checks whether artifact is a graph bundle. \r
- * \r
- * @param repo artifact repo\r
- * @param key key to artifact\r
- * @return manifest or null\r
- * @throws IOException \r
- */\r
- public static Manifest getSimanticsManifest(IArtifactRepository repo, IArtifactKey key) throws IOException {\r
- InputStream is = getFile(repo, key, "META-INF/SIMANTICS.MF");\r
- if (is == null) return null;\r
- try {\r
- return new Manifest(is);\r
- } finally {\r
- is.close();\r
- }\r
- }\r
- \r
- public static IArtifactKey[] getAllArtifactKeys(IArtifactRepository repo) {\r
- return repo.query( ArtifactKeyQuery.ALL_KEYS, null ).toArray( IArtifactKey.class );\r
- }\r
- \r
- public static void getUserInstallables(IArtifactRepository repo, Collection<String> result) throws IOException {\r
- IArtifactKey[] keys = repo.query( ArtifactKeyQuery.ALL_KEYS, null ).toArray( IArtifactKey.class );\r
- for (IArtifactKey key : keys) {\r
- Manifest mf = getSimanticsManifest(repo, key);\r
- if (mf==null) continue;\r
- String bundleId = mf.getMainAttributes().getValue("Simantics-Feature-Bundle");\r
- result.add( bundleId );\r
- }\r
- }\r
- \r
- public static GraphBundle getGraphBundle(IArtifactRepository repo, IArtifactKey key, IInstallableUnit iu) \r
- throws TransferableGraphException\r
- {\r
- String name = ProvisioningUtil.getName(iu);\r
- TransferableGraph1 tg = getTransferableGraph(repo, key); \r
- return new GraphBundleEx(name, tg, key.getId(), key.getVersion()); \r
- }\r
- \r
- /**\r
- * Get the .tg file from a Graph bundle\r
- * \r
- * @param repo\r
- * @param key\r
- * @return byte[] transferable fraph\r
- * @throws TGException\r
- */\r
- public static TransferableGraph1 getTransferableGraph(IArtifactRepository repo, IArtifactKey key) \r
- throws TransferableGraphException\r
- {\r
- boolean isBundle = key.getClassifier().equals("osgi.bundle");\r
- if (!isBundle) throw new TransferableGraphException("Artifact Key is not osgi.bundle");\r
- \r
- for (IArtifactDescriptor desc : repo.getArtifactDescriptors(key)) { \r
- if (repo instanceof IFileArtifactRepository) {\r
- IFileArtifactRepository filerepo = (IFileArtifactRepository) repo;\r
- File f = filerepo.getArtifactFile(key);\r
- if (!f.exists()) {\r
- throw new TransferableGraphException(f+" not found");\r
- }\r
- \r
- boolean isJar = f.getName().toLowerCase().endsWith(".jar");\r
- if (!isJar) throw new TransferableGraphException(f+" is not jar as expected");\r
-\r
- JarFile jf = null;\r
- try {\r
- jf = new JarFile(f);\r
- Enumeration<JarEntry> enm = jf.entries();\r
- while (enm.hasMoreElements()) {\r
- JarEntry entry = enm.nextElement();\r
- String entryName = entry.getName().toLowerCase();\r
- boolean isTG = entryName.equalsIgnoreCase("graph.tg");\r
- if (!isTG) continue;\r
- try {\r
- Binding binding = Bindings.getBindingUnchecked( TransferableGraph1.class );\r
- long size = entry.getSize();\r
- InputStream is = jf.getInputStream(entry);\r
- return (TransferableGraph1) Files.readFile(is, size, binding);\r
- } catch (IOException e) {\r
- throw new TransferableGraphException(e);\r
- }\r
- }\r
- } catch (IOException e) {\r
- throw new TransferableGraphException(e);\r
- } finally {\r
- try {\r
- if (jf!=null) jf.close();\r
- } catch (IOException e) {\r
- }\r
- }\r
- throw new TransferableGraphException(".tg file was not found in "+key);\r
- \r
- } else {\r
- try {\r
- int size = Integer.valueOf( desc.getProperties().get("download.size") );\r
- ByteArrayOutputStream bos = new ByteArrayOutputStream(size);\r
- repo.getArtifact(desc, bos, null);\r
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());\r
- JarInputStream jis = new JarInputStream( bis );\r
- for (JarEntry entry = jis.getNextJarEntry(); entry!=null; entry = jis.getNextJarEntry()) {\r
- String entryName = entry.getName().toLowerCase();\r
- boolean isTG = entryName.equalsIgnoreCase("graph.tg");\r
- if (!isTG) continue;\r
- //long fileSize = entry.getSize();\r
- Binding binding = Bindings.getBindingUnchecked(TransferableGraph1.class);\r
- return (TransferableGraph1) Files.readFile(jis, binding);\r
- \r
- }\r
- } catch (IOException e) {\r
- throw new TransferableGraphException(e);\r
- }\r
- throw new TransferableGraphException(".tg file was not found in "+key);\r
- }\r
- }\r
- throw new TransferableGraphException(".tg file was not found in "+key);\r
- }\r
- \r
- public static String getDescription(IInstallableUnit iu) {\r
- return iu.getProperty("org.eclipse.equinox.p2.description");\r
- }\r
- \r
- public static String getName(IInstallableUnit iu) {\r
- return iu.getProperty("org.eclipse.equinox.p2.name");\r
- }\r
-\r
- /**\r
- * Returns an IU corresponding to the given artifact key and bundle, or <code>null</code>\r
- * if an IU could not be created.\r
- */\r
- public static IInstallableUnit createBundleIU(IArtifactKey artifactKey, File bundleFile) {\r
- BundleDescription bundleDescription = null;\r
- try {\r
- bundleDescription = BundlesAction.createBundleDescription(bundleFile);\r
- } catch (IOException | BundleException e) {\r
- e.printStackTrace();\r
- }\r
- if (bundleDescription == null)\r
- return null;\r
- PublisherInfo info = new PublisherInfo();\r
- Version version = Version.create(bundleDescription.getVersion().toString());\r
- AdviceFileAdvice advice = new AdviceFileAdvice(bundleDescription.getSymbolicName(), version, new Path(bundleFile.getAbsolutePath()), AdviceFileAdvice.BUNDLE_ADVICE_FILE);\r
- if (advice.containsAdvice())\r
- info.addAdvice(advice);\r
- String shape = bundleFile.isDirectory() ? IBundleShapeAdvice.DIR : IBundleShapeAdvice.JAR;\r
- info.addAdvice(new BundleShapeAdvice(bundleDescription.getSymbolicName(), version, shape));\r
- return BundlesAction.createBundleIU(bundleDescription, artifactKey, info);\r
- }\r
-\r
- public static IFileArtifactRepository getDownloadCacheRepo(IProvisioningAgent agent) throws ProvisionException {\r
- return org.eclipse.equinox.internal.p2.touchpoint.natives.Util.getDownloadCacheRepo(agent);\r
- }\r
-\r
- public static Comparator<IInstallableUnit> getIUComparator() {\r
- return new Comparator<IInstallableUnit>() {\r
- @Override\r
- public int compare(IInstallableUnit o1, IInstallableUnit o2) {\r
- return o1.getId().compareTo(o2.getId());\r
- }\r
- \r
- };\r
- }\r
-\r
- public static TreeSet<IInstallableUnit> getSorted( Iterator<IInstallableUnit> iter ) {\r
- TreeSet<IInstallableUnit> result = new TreeSet<IInstallableUnit>( getIUComparator() );\r
- while (iter.hasNext()) {\r
- IInstallableUnit iu = iter.next();\r
- result.add( iu );\r
- }\r
- return result;\r
- }\r
-\r
- public static TreeSet<IInstallableUnit> getSorted( IQueryResult<IInstallableUnit> result ) {\r
- return getSorted(result.iterator());\r
- }\r
- \r
-}\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.project.management;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.equinox.internal.p2.metadata.RequiredCapability;
+import org.eclipse.equinox.internal.p2.touchpoint.eclipse.Util;
+import org.eclipse.equinox.internal.p2.ui.query.RequiredIUsQuery;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
+import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.publisher.AdviceFileAdvice;
+import org.eclipse.equinox.p2.publisher.PublisherInfo;
+import org.eclipse.equinox.p2.publisher.eclipse.BundleShapeAdvice;
+import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction;
+import org.eclipse.equinox.p2.publisher.eclipse.IBundleShapeAdvice;
+import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.query.IQueryable;
+import org.eclipse.equinox.p2.query.QueryUtil;
+import org.eclipse.equinox.p2.repository.artifact.ArtifactKeyQuery;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
+import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.osgi.framework.BundleException;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Files;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.util.StreamUtil;
+import org.simantics.graph.db.TransferableGraphException;
+import org.simantics.graph.representation.TransferableGraph1;
+
+/**
+ * This class contains provisioning utilities.
+ *
+ * @see QueryUtil
+ * @see Util
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
+ */
+@SuppressWarnings("restriction")
+public class ProvisioningUtil {
+
+ private static IRequirement IS_FEATURE_REQUIREMENT = new RequiredCapability("org.eclipse.equinox.p2.eclipse.type", "feature", null, null, false, false, false);
+
+ public static void getAllRequirements(IInstallableUnit iu, IQueryable<IInstallableUnit> repo, Set<IInstallableUnit> result)
+ {
+ if (result.contains(iu)) return;
+ result.add(iu);
+ IQuery<IInstallableUnit> reqsQuery = new RequiredIUsQuery(iu);
+ for (IInstallableUnit _iu : repo.query( reqsQuery, null ).toSet()) {
+ if (result.contains(_iu)) continue;
+ getAllRequirements(_iu, repo, result);
+ }
+ }
+
+
+ /**
+ * Get IUs that are required to install this bundle.
+ * Assumed architecture is x86 and os win32.
+ * Throws an exception if not all requirements can be satisfied.
+ *
+ * @param iu
+ * @param availableIUs
+ * @return
+ */
+ /*
+ public static Collection<IRequirement> getAllRequirements(IInstallableUnit iu, IQueryable<IInstallableUnit> repo)
+ {
+ // Installable Units analysed
+ Set<IInstallableUnit> ius = new HashSet<IInstallableUnit>();
+
+ // Requirements
+ Set<IRequirement> reqs = new HashSet<IRequirement>();
+
+ // Satisfied requirements
+ Set<IRequirement> sats = new HashSet<IRequirement>();
+ ius.add(iu);
+ reqs.addAll( iu.getRequirements() );
+
+ // Find satisfactions
+ return result;
+ }*/
+ /*
+ static void _addIU(IInstallableUnit iu, Set<IInstallableUnit> ius, Set<IRequirement> reqs, Set<IRequirement> sats, Set<IRequirement> unsats, IQueryable<IInstallableUnit> repo)
+ {
+ if (ius.contains(iu)) return;
+ ius.add( iu );
+
+ for (IRequirement req : iu.getRequirements()) {
+ if (sats.contains(req)) continue;
+ if (unsats.contains(req)) continue;
+
+ // req is unsatisfied
+ IQuery
+ IQueryResult<IInstallableUnit> result = repo.query(req, null);
+ }
+
+ for (IInstallableUnit _iu : availableIUs) {
+ if (sats.contains(_iu)) continue;
+
+ boolean satisfies = _iu.satisfies( )
+ }
+ }*/
+
+ /**
+ * Get all installable units from a metadata repository
+ *
+ * @param repo
+ * @return
+ */
+ public static Collection<IInstallableUnit> getInstallableUnits(IMetadataRepository repo) {
+
+// IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(null, VersionRange.emptyRange);
+ IQuery<IInstallableUnit> query = QueryUtil.createIUAnyQuery();
+ IQueryResult<IInstallableUnit> matches = repo.query(query, null);
+ return matches.toUnmodifiableSet();
+ }
+
+
+ /**
+ * Test if the {@link IInstallableUnit} is a category.
+ * @param iu the element being tested.
+ * @return <tt>true</tt> if the parameter is a category.
+ */
+ public static boolean isCategory(IInstallableUnit iu) {
+ String PROP_TYPE_CATEGORY = "org.eclipse.equinox.p2.type.category"; //$NON-NLS-1$
+ String value = iu.getProperty(PROP_TYPE_CATEGORY);
+ if (value != null && (value.equals(Boolean.TRUE.toString())))
+ return true;
+ return false;
+ }
+
+ /**
+ * Test if the {@link IInstallableUnit} is a fragment.
+ * @param iu the element being tested.
+ * @return <tt>true</tt> if the parameter is a fragment.
+ */
+ public static boolean isFragment(IInstallableUnit iu) {
+ return iu instanceof IInstallableUnitFragment;
+ }
+
+ /**
+ * Test if the {@link IInstallableUnit} is a group.
+ * @param iu the element being tested.
+ * @return <tt>true</tt> if the parameter is a group.
+ */
+ public static boolean isGroup(IInstallableUnit iu) {
+ String PROP_TYPE_GROUP = "org.eclipse.equinox.p2.type.group"; //$NON-NLS-1$
+ String value = iu.getProperty(PROP_TYPE_GROUP);
+ if (value != null && (value.equals(Boolean.TRUE.toString())))
+ return true;
+ return false;
+ }
+
+ /**
+ * Test if the {@link IInstallableUnit} is a patch.
+ * @param iu the element being tested.
+ * @return <tt>true</tt> if the parameter is a patch.
+ */
+ public static boolean isPatch(IInstallableUnit iu) {
+ String PROP_TYPE_PATCH = "org.eclipse.equinox.p2.type.patch"; //$NON-NLS-1$
+ String value = iu.getProperty(PROP_TYPE_PATCH);
+ if (value != null && (value.equals(Boolean.TRUE.toString())))
+ return true;
+ return false;
+ }
+
+ /**
+ * Checks whether a installable unit is a feature
+ *
+ * @param iu
+ * @return <code>true</code> if is feature
+ */
+ public static boolean isFeature(IInstallableUnit iu) {
+// String value = iu.getProperty("org.eclipse.equinox.p2.eclipse.type");
+// return value != null && value.equals("feature");
+ return iu.satisfies(IS_FEATURE_REQUIREMENT);
+ }
+
+ public static boolean isGraph(IInstallableUnit iu, IMetadataRepository metadata, IArtifactRepository arts) throws IOException {
+ Collection<IArtifactKey> artifacts = iu.getArtifacts();
+ for (IArtifactKey key : artifacts) {
+ if (isGraphArtifact(arts, key)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether artifact is a graph bundle.
+ *
+ * @param repo artifact repo
+ * @param key key to artifact
+ * @return <code>true</code> if is a graph bundle
+ * @throws IOException
+ */
+ public static boolean isGraphArtifact(IArtifactRepository repo, IArtifactKey key) throws IOException {
+ return hasFile(repo, key, "graph.tg");
+ }
+
+ public static boolean hasFile(IArtifactRepository repo, IArtifactKey key, String filename) throws IOException {
+ boolean isBundle = key.getClassifier().equals("osgi.bundle");
+ if (!isBundle) return false;
+
+ for (IArtifactDescriptor desc : repo.getArtifactDescriptors(key)) {
+ if (repo instanceof IFileArtifactRepository) {
+ IFileArtifactRepository filerepo = (IFileArtifactRepository) repo;
+ File f = filerepo.getArtifactFile(key);
+ if (!f.exists()) return false;
+
+ boolean isJar = f.getName().toLowerCase().endsWith(".jar");
+ if (!isJar) return false;
+
+ JarFile jf = new JarFile(f);
+ try {
+ Enumeration<JarEntry> enm = jf.entries();
+ while (enm.hasMoreElements()) {
+ JarEntry entry = enm.nextElement();
+ String entryName = entry.getName();
+ if ( entryName.equals(filename) ) return true;
+ }
+ } finally {
+ jf.close();
+ }
+
+ } else {
+ int size = Integer.valueOf( desc.getProperties().get("download.size") );
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
+ repo.getArtifact(desc, bos, null);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ JarInputStream jis = new JarInputStream( bis );
+ for (JarEntry entry = jis.getNextJarEntry(); entry!=null; entry = jis.getNextJarEntry()) {
+ String entryName = entry.getName();
+ if ( entryName.equals(filename) ) return true;
+ }
+
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get a file from a repository
+ *
+ * @param repo artifact repo
+ * @param key key to artifact
+ * @return input stream (must be closed) or null
+ * @throws IOException
+ */
+ public static InputStream getFile(IArtifactRepository repo, IArtifactKey key, String filename) throws IOException {
+ boolean isBundle = key.getClassifier().equals("osgi.bundle");
+ if (!isBundle) return null;
+
+ for (IArtifactDescriptor desc : repo.getArtifactDescriptors(key)) {
+ if (repo instanceof IFileArtifactRepository) {
+ IFileArtifactRepository filerepo = (IFileArtifactRepository) repo;
+ File f = filerepo.getArtifactFile(key);
+ if (!f.exists()) return null;
+
+ boolean isJar = f.getName().toLowerCase().endsWith(".jar");
+ if (!isJar) return null;
+
+ JarFile jf = new JarFile(f);
+ try {
+ Enumeration<JarEntry> enm = jf.entries();
+ while (enm.hasMoreElements()) {
+ JarEntry entry = enm.nextElement();
+ String entryName = entry.getName();
+ if (! entryName.equals(filename) ) continue;
+ InputStream is = jf.getInputStream(entry);
+ byte[] data = StreamUtil.readFully(is);
+ is.close();
+ return new ByteArrayInputStream(data);
+ }
+ } finally {
+ jf.close();
+ }
+
+ } else {
+ int size = Integer.valueOf( desc.getProperties().get("download.size") );
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
+ repo.getArtifact(desc, bos, null);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ JarInputStream jis = new JarInputStream( bis );
+ for (JarEntry entry = jis.getNextJarEntry(); entry!=null; entry = jis.getNextJarEntry()) {
+ String entryName = entry.getName();
+ if (! entryName.equals(filename) ) continue;
+ return jis;
+ }
+
+ }
+ }
+ return null;
+ }
+ /**
+ * Checks whether artifact is a graph bundle.
+ *
+ * @param repo artifact repo
+ * @param key key to artifact
+ * @return manifest or null
+ * @throws IOException
+ */
+ public static Manifest getManifest(IArtifactRepository repo, IArtifactKey key) throws IOException {
+ InputStream is = getFile(repo, key, "META-INF/MANIFEST.MF");
+ if (is == null) return null;
+ try {
+ return new Manifest(is);
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * Checks whether artifact is a graph bundle.
+ *
+ * @param repo artifact repo
+ * @param key key to artifact
+ * @return manifest or null
+ * @throws IOException
+ */
+ public static Manifest getSimanticsManifest(IArtifactRepository repo, IArtifactKey key) throws IOException {
+ InputStream is = getFile(repo, key, "META-INF/SIMANTICS.MF");
+ if (is == null) return null;
+ try {
+ return new Manifest(is);
+ } finally {
+ is.close();
+ }
+ }
+
+ public static IArtifactKey[] getAllArtifactKeys(IArtifactRepository repo) {
+ return repo.query( ArtifactKeyQuery.ALL_KEYS, null ).toArray( IArtifactKey.class );
+ }
+
+ public static void getUserInstallables(IArtifactRepository repo, Collection<String> result) throws IOException {
+ IArtifactKey[] keys = repo.query( ArtifactKeyQuery.ALL_KEYS, null ).toArray( IArtifactKey.class );
+ for (IArtifactKey key : keys) {
+ Manifest mf = getSimanticsManifest(repo, key);
+ if (mf==null) continue;
+ String bundleId = mf.getMainAttributes().getValue("Simantics-Feature-Bundle");
+ result.add( bundleId );
+ }
+ }
+
+ public static GraphBundle getGraphBundle(IArtifactRepository repo, IArtifactKey key, IInstallableUnit iu)
+ throws TransferableGraphException
+ {
+ String name = ProvisioningUtil.getName(iu);
+ TransferableGraph1 tg = getTransferableGraph(repo, key);
+ return new GraphBundleEx(name, tg, key.getId(), key.getVersion());
+ }
+
+ /**
+ * Get the .tg file from a Graph bundle
+ *
+ * @param repo
+ * @param key
+ * @return byte[] transferable fraph
+ * @throws TGException
+ */
+ public static TransferableGraph1 getTransferableGraph(IArtifactRepository repo, IArtifactKey key)
+ throws TransferableGraphException
+ {
+ boolean isBundle = key.getClassifier().equals("osgi.bundle");
+ if (!isBundle) throw new TransferableGraphException("Artifact Key is not osgi.bundle");
+
+ for (IArtifactDescriptor desc : repo.getArtifactDescriptors(key)) {
+ if (repo instanceof IFileArtifactRepository) {
+ IFileArtifactRepository filerepo = (IFileArtifactRepository) repo;
+ File f = filerepo.getArtifactFile(key);
+ if (!f.exists()) {
+ throw new TransferableGraphException(f+" not found");
+ }
+
+ boolean isJar = f.getName().toLowerCase().endsWith(".jar");
+ if (!isJar) throw new TransferableGraphException(f+" is not jar as expected");
+
+ JarFile jf = null;
+ try {
+ jf = new JarFile(f);
+ Enumeration<JarEntry> enm = jf.entries();
+ while (enm.hasMoreElements()) {
+ JarEntry entry = enm.nextElement();
+ String entryName = entry.getName().toLowerCase();
+ boolean isTG = entryName.equalsIgnoreCase("graph.tg");
+ if (!isTG) continue;
+ try {
+ Binding binding = Bindings.getBindingUnchecked( TransferableGraph1.class );
+ long size = entry.getSize();
+ InputStream is = jf.getInputStream(entry);
+ return (TransferableGraph1) Files.readFile(is, size, binding);
+ } catch (IOException e) {
+ throw new TransferableGraphException(e);
+ }
+ }
+ } catch (IOException e) {
+ throw new TransferableGraphException(e);
+ } finally {
+ try {
+ if (jf!=null) jf.close();
+ } catch (IOException e) {
+ }
+ }
+ throw new TransferableGraphException(".tg file was not found in "+key);
+
+ } else {
+ try {
+ int size = Integer.valueOf( desc.getProperties().get("download.size") );
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
+ repo.getArtifact(desc, bos, null);
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ JarInputStream jis = new JarInputStream( bis );
+ for (JarEntry entry = jis.getNextJarEntry(); entry!=null; entry = jis.getNextJarEntry()) {
+ String entryName = entry.getName().toLowerCase();
+ boolean isTG = entryName.equalsIgnoreCase("graph.tg");
+ if (!isTG) continue;
+ //long fileSize = entry.getSize();
+ Binding binding = Bindings.getBindingUnchecked(TransferableGraph1.class);
+ return (TransferableGraph1) Files.readFile(jis, binding);
+
+ }
+ } catch (IOException e) {
+ throw new TransferableGraphException(e);
+ }
+ throw new TransferableGraphException(".tg file was not found in "+key);
+ }
+ }
+ throw new TransferableGraphException(".tg file was not found in "+key);
+ }
+
+ public static String getDescription(IInstallableUnit iu) {
+ return iu.getProperty("org.eclipse.equinox.p2.description");
+ }
+
+ public static String getName(IInstallableUnit iu) {
+ return iu.getProperty("org.eclipse.equinox.p2.name");
+ }
+
+ /**
+ * Returns an IU corresponding to the given artifact key and bundle, or <code>null</code>
+ * if an IU could not be created.
+ */
+ public static IInstallableUnit createBundleIU(IArtifactKey artifactKey, File bundleFile) {
+ BundleDescription bundleDescription = null;
+ try {
+ bundleDescription = BundlesAction.createBundleDescription(bundleFile);
+ } catch (IOException | BundleException e) {
+ e.printStackTrace();
+ }
+ if (bundleDescription == null)
+ return null;
+ PublisherInfo info = new PublisherInfo();
+ Version version = Version.create(bundleDescription.getVersion().toString());
+ AdviceFileAdvice advice = new AdviceFileAdvice(bundleDescription.getSymbolicName(), version, new Path(bundleFile.getAbsolutePath()), AdviceFileAdvice.BUNDLE_ADVICE_FILE);
+ if (advice.containsAdvice())
+ info.addAdvice(advice);
+ String shape = bundleFile.isDirectory() ? IBundleShapeAdvice.DIR : IBundleShapeAdvice.JAR;
+ info.addAdvice(new BundleShapeAdvice(bundleDescription.getSymbolicName(), version, shape));
+ return BundlesAction.createBundleIU(bundleDescription, artifactKey, info);
+ }
+
+ public static IFileArtifactRepository getDownloadCacheRepo(IProvisioningAgent agent) throws ProvisionException {
+ return org.eclipse.equinox.internal.p2.touchpoint.natives.Util.getDownloadCacheRepo(agent);
+ }
+
+ public static Comparator<IInstallableUnit> getIUComparator() {
+ return new Comparator<IInstallableUnit>() {
+ @Override
+ public int compare(IInstallableUnit o1, IInstallableUnit o2) {
+ return o1.getId().compareTo(o2.getId());
+ }
+
+ };
+ }
+
+ public static TreeSet<IInstallableUnit> getSorted( Iterator<IInstallableUnit> iter ) {
+ TreeSet<IInstallableUnit> result = new TreeSet<IInstallableUnit>( getIUComparator() );
+ while (iter.hasNext()) {
+ IInstallableUnit iu = iter.next();
+ result.add( iu );
+ }
+ return result;
+ }
+
+ public static TreeSet<IInstallableUnit> getSorted( IQueryResult<IInstallableUnit> result ) {
+ return getSorted(result.iterator());
+ }
+
+}
+