X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2FBundlePool.java;fp=bundles%2Forg.simantics.project%2Fsrc%2Forg%2Fsimantics%2Fproject%2Fmanagement%2FBundlePool.java;h=aa8beb7e2bf1e85fdfad0eda3d8f54e172fa2906;hp=2679f6ad24448b89a45dde2b94ce5e496e904c73;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/BundlePool.java b/bundles/org.simantics.project/src/org/simantics/project/management/BundlePool.java index 2679f6ad2..aa8beb7e2 100644 --- a/bundles/org.simantics.project/src/org/simantics/project/management/BundlePool.java +++ b/bundles/org.simantics.project/src/org/simantics/project/management/BundlePool.java @@ -1,616 +1,616 @@ -/******************************************************************************* - * Copyright (c) 2007 VTT Technical Research Centre of Finland and others. - * 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.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.Manifest; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository; -import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository; -import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepositoryFactory; -import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository; -import org.eclipse.equinox.internal.p2.metadata.repository.LocalMetadataRepository; -import org.eclipse.equinox.internal.p2.metadata.repository.SimpleMetadataRepositoryFactory; -import org.eclipse.equinox.p2.core.IProvisioningAgent; -import org.eclipse.equinox.p2.core.ProvisionException; -import org.eclipse.equinox.p2.internal.repository.mirroring.Mirroring; -import org.eclipse.equinox.p2.metadata.IArtifactKey; -import org.eclipse.equinox.p2.metadata.IInstallableUnit; -import org.eclipse.equinox.p2.metadata.IVersionedId; -import org.eclipse.equinox.p2.metadata.VersionedId; -import org.eclipse.equinox.p2.query.IQuery; -import org.eclipse.equinox.p2.query.IQueryResult; -import org.eclipse.equinox.p2.query.QueryUtil; -import org.eclipse.equinox.p2.repository.artifact.ArtifactKeyQuery; -import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; -import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; -import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; -import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; -import org.simantics.graph.db.TransferableGraphException; -import org.simantics.graph.query.Graphs; -import org.simantics.graph.query.IGraph; -import org.simantics.graph.query.Paths; -import org.simantics.graph.query.Res; -import org.simantics.graph.query.UriUtils; -import org.simantics.graph.representation.TransferableGraph1; -import org.simantics.scl.reflection.OntologyVersions; -import org.simantics.utils.FileUtils; - -/** - * Bundlepool is a repository of artifacts and installable units. - * - * @author Toni Kalajainen - */ -@SuppressWarnings("restriction") -public class BundlePool { - - /** Application default pool. It is located at "workspace/bundlepool" */ - static BundlePool DEFAULT; - - IMetadataRepository metadataRepository; - IArtifactRepository artifactRepository; - IProvisioningAgent metadataAgent; - IProvisioningAgent artifactAgent; - URI metadataAgentLocation; - URI artifactAgentLocation; - - List userInstallables; - - /** All features that were discovered in the repository */ - Set projectFeatures = new HashSet(); - - /** - * Get SPM Bundle Pool - * - * @return SPM Bundle Pool - */ - public synchronized static BundlePool getDefault() { - if (DEFAULT == null) { - try { - IPath path = Platform.getLocation().append("bundlepool"); - URI metadataRepositoryLocation = path.toFile().toURI(); - URI artifactRepositoryLocation = path.toFile().toURI(); - IProvisioningAgent agent = P2Util.createAgent( path ); - DEFAULT = new BundlePool(metadataRepositoryLocation, artifactRepositoryLocation, agent); - } catch (ProvisionException e) { - // Not expected - throw new RuntimeException(e); - } - } - return DEFAULT; - } - - /** - * Create bundle pool in a directory on a local hard drive. - * This location will contain metadata repository, artifact repository and - * P2 workarea (Agent). - * - * @param location - * @return bundle pool - */ - public static BundlePool createAt(File location) { - try { - File canonicalLocation = location.getCanonicalFile(); - URI metadataRepositoryLocation = canonicalLocation.toURI(); - URI artifactRepositoryLocation = canonicalLocation.toURI(); - IPath agentLocation = new Path( canonicalLocation.toString() ); - IProvisioningAgent agent = P2Util.createAgent( agentLocation ); - return new BundlePool(metadataRepositoryLocation, artifactRepositoryLocation, agent); - } catch (IOException e) { - throw new RuntimeException(e); - } catch (org.eclipse.equinox.p2.core.ProvisionException e) { - throw new RuntimeException(e); - } - - } - - public BundlePool(URI metadataRepositoryLocation, URI artifactRepositoryLocation, IProvisioningAgent agent) throws ProvisionException { - - this.metadataAgent = agent; - this.artifactAgent = agent; - - SimpleMetadataRepositoryFactory metRepFactory = new SimpleMetadataRepositoryFactory(); - metRepFactory.setAgent( metadataAgent ); - try { - metadataRepository = metRepFactory.load(metadataRepositoryLocation, 0, null); - } catch (org.eclipse.equinox.p2.core.ProvisionException pe) { - new File(metadataRepositoryLocation).mkdirs(); - Map repoProperties = new HashMap(); - metadataRepository = metRepFactory.create(metadataRepositoryLocation, "SPM Bundle Pool", "file", repoProperties); - } - - // IMetadataRepository metadataRepository = new LocalMetadataRepository( agent, repositoryLocation, "My Metadata Repository", Collections.EMPTY_MAP ); - // IMetadataRepository metadataRepository = getMetadataRepository(agent, repositoryLocation); - -// IArtifactRepository artifactRepository = new SimpleArtifactRepositoryFactory().create(repositoryLocation, "Sample Artifact Repository", ArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, Collections.EMPTY_MAP); -// SimpleArtifactRepository artifactRepository = new SimpleArtifactRepository( agent, "My Simple Artifact Repository", repositoryLocation, Collections.EMPTY_MAP); - SimpleArtifactRepositoryFactory artRepFactory = new SimpleArtifactRepositoryFactory(); - artRepFactory.setAgent( artifactAgent ); - - try { - artifactRepository = artRepFactory.load(artifactRepositoryLocation, 0, null); - } catch (org.eclipse.equinox.p2.core.ProvisionException pe) { - new File(artifactRepositoryLocation).mkdirs(); - Map repoProperties = new HashMap(); - artifactRepository = artRepFactory.create(artifactRepositoryLocation, "SPM Bundle Pool", "file", repoProperties); - } - - init(); - } - - public BundlePool(IMetadataRepository metadataRepository, IArtifactRepository artifactRepository) throws ProvisionException { - this.metadataRepository = metadataRepository; - this.artifactRepository = artifactRepository; - this.metadataAgent = metadataRepository.getProvisioningAgent(); - this.artifactAgent = artifactRepository.getProvisioningAgent(); - init(); - } - - /** - * Init prepares with the following actions: - * o loads transferable graphs - * o discovers Features and collects Feature URIs, Artifacts and Installable Units - * - * @throws ProvisionException - */ - protected void init() throws ProvisionException { - try { - projectFeatures.clear(); - - ArrayList platformTGs = new ArrayList(); - - for (IArtifactKey key : getAllArtifactKeys()) { - boolean hasGraph = ProvisioningUtil.hasFile(artifactRepository, key, "graph.tg"); - if (!hasGraph) continue; - - // Read Graph - TransferableGraph1 graph = ProvisioningUtil.getTransferableGraph(artifactRepository, key); - platformTGs.add(graph); - } - - // Create new project, use all features available in Platform - final List poolFeatures = new ArrayList(); - - // Convert graph instances - GraphBundleEx l0 = getLayer0(); - String l0v = l0.getMajor() + "." + l0.getMinor(); - IGraph graph = Graphs.createGraph(new Paths(l0v), platformTGs); - - for(Res feature : graph.getInstances(UriUtils.uriToPath(OntologyVersions.getInstance().currentVersion("http://www.simantics.org/Project-0.0/Feature" )))) { - poolFeatures.add( feature.toString() ); - } - - } catch (TransferableGraphException e) { - throw new ProvisionException("Problem", e); - } catch (IOException e) { - throw new ProvisionException("Failed to read graph.tg", e); - } - } - - public IMetadataRepository getMetadataRepository() { - return metadataRepository; - } - - public IArtifactRepository getArtifactRepository() { - return artifactRepository; - } - - public IArtifactKey[] getAllArtifactKeys() { - return artifactRepository.query( ArtifactKeyQuery.ALL_KEYS, null ).toArray( IArtifactKey.class ); - } - - public GraphBundleEx getLayer0() throws ProvisionException, TransferableGraphException { - IVersionedId vid = VersionedId.parse("org.simantics.layer0"); - Set result = metadataRepository.query( QueryUtil.createLatestQuery( QueryUtil.createIUQuery(vid) ), null).toSet(); - if (result.isEmpty()) throw new RuntimeException("Unexpectedly got no IU for "+vid); - if (result.size()>1) throw new RuntimeException("Unexpectedly got more than one latest IU for "+vid); - IInstallableUnit iu = result.iterator().next(); - IArtifactKey key = toSingleArtifact(iu); - TransferableGraph1 graph = getTransferableGraph( key ); - return new GraphBundleEx( "Layer0", graph, key); - } - - public TransferableGraph1 getTransferableGraph(IArtifactKey artifactKey) throws ProvisionException, TransferableGraphException { - return ProvisioningUtil.getTransferableGraph( artifactRepository, artifactKey); - } - - - - /** - * Get all features. - * - * @param a list of features - * @throws ProvisionException - */ - public void getFeatures(List features) throws ProvisionException { - IMetadataRepository metadataRepository = getMetadataRepository(); - - Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); - for (IInstallableUnit iu : ius) { - if (ProvisioningUtil.isGroup(iu)) { -// if (P2Util.isFeature(iu)) { - BundleInfo b = BundleInfo.read(iu); - features.add( b ); - } - } - } - - /** - * Get bundle info - * - * @param id bundle id - * @return bundle info - */ - public BundleInfo getBundleInfo(String id) { - IQuery query = QueryUtil.createLatestQuery( QueryUtil.createIUQuery(id) ); - IQueryResult queryResult = metadataRepository.query(query, null); - IInstallableUnit[] array = queryResult.toArray( IInstallableUnit.class ); - for (IInstallableUnit iu : array) { - BundleInfo bi = BundleInfo.read(iu); - return bi; - } - return null; - } - - /** - * Get the features that visible for the end-user. - * User installable features are configured in Simantics manifest files - * (META-INF/SIMANTICS.MF as Simantics-Features-Bundle -property) - * - * @param result - * @throws IOException - */ -// public void getUserInstallableFeatures(Collection result) throws IOException { -// ArrayList ids = new ArrayList(); -// ProvisioningUtil.getUserInstallables(artifactRepository, ids); -// for (String id : ids) { -// BundleInfo bi = getBundleInfo(id); -// if (bi != null) result.add( bi ); -// } -// // Add workspace bundle -// BundleInfo bi = getBundleInfo( "org.simantics.workbench.product" ); -// if (bi != null) result.add( bi ); -// } - - /** - * Get all groups. - * - * @param a list of features - * @throws ProvisionException - */ -// public void getInstallableFeatures(List features) throws ProvisionException { -// IMetadataRepository metadataRepository = getMetadataRepository(); -// -// Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); -// for (IInstallableUnit iu : ius) { -// if (ProvisioningUtil.isGroup(iu)) { -//// if (P2Util.isFeature(iu)) { -// BundleInfo b = BundleInfo.read(iu); -// features.add( b ); -// } -// } -// } - - /** - * Mirror source locations to the bundle pool. - * - * @param monitor - * @param sourceLocations - * @return - * @throws ProvisionException - */ - public IStatus download(IProgressMonitor monitor, URI[] sourceLocations) throws ProvisionException { - try { - monitor.beginTask("Synchronizing Local repository with web repositories", 10); - - @SuppressWarnings("unused") - IMetadataRepositoryManager metaRepoMgr = (IMetadataRepositoryManager) metadataAgent.getService(IMetadataRepositoryManager.SERVICE_NAME); - @SuppressWarnings("unused") - IArtifactRepositoryManager artsRepoMgr = (IArtifactRepositoryManager) artifactAgent.getService(IArtifactRepositoryManager.SERVICE_NAME); - - - // Create dest repos - monitor.setTaskName("Setting up local metadata repository"); - LocalMetadataRepository dstMetaRepo = (LocalMetadataRepository) metadataRepository; - monitor.worked(1); - - monitor.setTaskName("Setting up local artifact repository"); - SimpleArtifactRepository dstArtsRepo = (SimpleArtifactRepository) artifactRepository; - monitor.worked(1); - - // Create a source repos - monitor.setTaskName("Setting up remote artifact repository"); - CompositeArtifactRepository srcArtsRepo = CompositeArtifactRepository.createMemoryComposite( metadataAgent /* ? */ ); - for (URI uri : sourceLocations) srcArtsRepo.addChild(uri); - monitor.worked(1); - - monitor.setTaskName("Setting up remote metadata repository"); - CompositeMetadataRepository srcMetaRepo = CompositeMetadataRepository.createMemoryComposite( artifactAgent /* ? */ ); - for (URI uri : sourceLocations) srcMetaRepo.addChild(uri); - monitor.worked(1); - - monitor.setTaskName("Retrieving Installable Units"); - @SuppressWarnings("unused") - Collection ius = ProvisioningUtil.getInstallableUnits(srcMetaRepo); - monitor.worked(1); - - monitor.setTaskName("Mirroring Metadata"); - // Get all IUs from source - IQueryResult allIUs = srcMetaRepo.query(QueryUtil.createIUAnyQuery(), monitor); - // Put the IUs to dst - dstMetaRepo.addInstallableUnits(allIUs.toUnmodifiableSet()); - dstMetaRepo.addReferences(srcMetaRepo.getReferences()); - monitor.worked(1); - - monitor.setTaskName("Mirroring Artifacts"); - - boolean compare = false; - boolean failOnError = true; - //boolean raw = true; - boolean verbose = false; - boolean validate = false; - //boolean mirrorReferences = false; - String comparatorID = ""; - - Mirroring mirror = new Mirroring(srcArtsRepo, dstArtsRepo, false); - mirror.setCompare(compare); - mirror.setComparatorId(comparatorID); - // mirror.setBaseline(null); - mirror.setValidate(validate); - // mirror.setCompareExclusions(); - - IStatus result = mirror.run(failOnError, verbose); - if (result.getException()!=null) - throw new ProvisionException(result); - - init(); - - return result; - } catch (IllegalArgumentException iae) { - return new Status(IStatus.ERROR, "org.simantics.project", iae.getMessage(), iae); - } - } - - public IInstallableUnit toSingleInstallableUnit(IVersionedId id) throws ProvisionException { - Set result = metadataRepository.query( QueryUtil.createIUQuery(id), null).toSet(); - if (result.size() != 1) throw new RuntimeException("Unexpectedly got more than one latest IU for "+id); - return result.iterator().next(); - } - - public IArtifactKey toSingleArtifact(IVersionedId id) throws ProvisionException { - IInstallableUnit iu = toSingleInstallableUnit(id); - if (iu.getArtifacts().size() != 1) throw new RuntimeException("Unexpectedly got more than one artifact for "); - return iu.getArtifacts().iterator().next(); - } - - /** - * Get file from an artifact. - * - * @param key - * @param filename - * @return inputstream or null. Inputstream must be closed. - * @throws IOException - */ - public InputStream getFile(IArtifactKey key, String filename) throws IOException { - return ProvisioningUtil.getFile(artifactRepository, key, filename); - } - - /** - * Checks whether there exists a file in an artifact - * - * @param key - * @param filename - * @return true file exists in the artifact - * @throws IOException - */ - public boolean hasFile(IArtifactKey key, String filename) throws IOException { - return ProvisioningUtil.hasFile(artifactRepository, key, filename); - } - - /** - * Get META-INF/MANIFEST.MF - * - * @param repo artifact repo - * @param key key to artifact - * @return manifest or null - * @throws IOException - */ - public Manifest getManifest(IArtifactKey key) throws IOException { - return ProvisioningUtil.getManifest(artifactRepository, key); - } - - /** - * Get META-INF/SIMANTICS.MF - * - * @param repo artifact repo - * @param key key to artifact - * @return manifest or null - * @throws IOException - */ - public Manifest getSimanticsManifest(IArtifactKey key) throws IOException { - return ProvisioningUtil.getManifest(artifactRepository, key); - } - - /** - * Get list of user installable bundles - * - * @param result - * @throws IOException - */ - public void getUserInstallables(List result) throws IOException { - if (userInstallables==null) { - userInstallables = new ArrayList(); - - List topLevelBundles = new ArrayList(); - ProvisioningUtil.getUserInstallables(artifactRepository, topLevelBundles); - - for (String bundleId : topLevelBundles) { - IInstallableUnit ius[] = metadataRepository.query( QueryUtil.createIUQuery(bundleId) , null).toArray( IInstallableUnit.class ); - for (IInstallableUnit iu : ius) { - userInstallables.add( BundleInfo.read(iu) ); - } - } - - } - result.addAll(userInstallables); - } - - - - /////////// - /////////// GRAPHS - /////////// - - - -// /** -// * Get graph bundles -// * -// * @param list to be populated with graph bundle ids -// * @throws ProvisionException -// * @throws IOException -// */ -// public void getGraphs(List graphs) throws ProvisionException, IOException { -// Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); -// for (IInstallableUnit iu : ius) { -// if (isGraph(iu)) { -// BundleInfo b = BundleInfo.read(iu); -// graphs.add( b ); -// } -// } -// } - - /** - * Get graph bundles - * - * @param list to be populated with graph bundle ids - * @throws ProvisionException - * @throws IOException - * @throws TransferableGraphException - */ - public void getGraphBundles(List graphs) throws ProvisionException, IOException, TransferableGraphException { - Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); - for (IInstallableUnit iu : ius) { - for (IArtifactKey key : iu.getArtifacts()) { - if (!ProvisioningUtil.isGraphArtifact(artifactRepository, key)) continue; - TransferableGraph1 tg = ProvisioningUtil.getTransferableGraph( artifactRepository, key ); - GraphBundleEx b = new GraphBundleEx(iu.getId(), tg, key); - graphs.add( b ); - } - } - } - - /** - * Get a list of all features. Features are uris, they are versionless. - * @return fetures - * @throws TransferableGraphException - * @throws IOException - */ - public Set getFeatures() throws IOException, TransferableGraphException { - /* - HashSet result = new HashSet(); - Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); - for (IInstallableUnit iu : ius) { - for (IArtifactKey key : iu.getArtifacts()) { - if (!ProvisioningUtil.isGraphArtifact(artifactRepository, key)) continue; - TransferableGraph1 tg = ProvisioningUtil.getTransferableGraph( artifactRepository, key ); - IGraph g = Graphs.createGraph(tg); - - Res PublishedProjectFeatures = UriUtils.uriToPath( ProjectResource.URIs.PublishedProjectFeatures ); - Path HasFeature = UriUtils.uriToPath( ProjectResource.URIs.HasFeature ); - for(Res feature : g.getObjects(PublishedProjectFeatures, HasFeature)) { - String uri = feature.toString(); - String name = feature instanceof PathChild ? ((PathChild)feature).name : uri; - - FeatureInfo fi = new FeatureInfo(name, uri, null, null); - result.add( fi ); - } - } - } - - return result; - */ - return Collections.emptySet(); - } - - /** - * For a set of extact feature ids (id_version), find the set of graph bundles - * required in the database. - * - * @param featureIds feature - * @return graph bundles - */ - public Set getRequiredGraphBundles(Collection featureIds) { - - return null; - } - - /** - * Checks whether artifact is a graph bundle. - * - * @param key key to artifact - * @return true if is a graph bundle - * @throws IOException - */ - public boolean isGraphArtifact(IArtifactKey key) throws IOException { - return ProvisioningUtil.isGraphArtifact(artifactRepository, key); - } - - /** - * Checks wheter iu is graph - * - * @param iu - * @return - * @throws IOException - */ - public boolean isGraph(IInstallableUnit iu) throws IOException { - return ProvisioningUtil.isGraph(iu, metadataRepository, artifactRepository); - } - - /** - * Delete default repositories located in /P2 folder - * @throws IOException - */ - public void delete() throws IOException { - File location1 = new File(metadataAgentLocation); - File location2 = new File(artifactAgentLocation); - File location3 = new File(metadataRepository.getLocation()); - File location4 = new File(artifactRepository.getLocation()); - FileUtils.deleteDir(location1); - FileUtils.deleteDir(location2); - FileUtils.deleteDir(location3); - FileUtils.deleteDir(location4); - location1.mkdirs(); - location2.mkdirs(); - location3.mkdirs(); - location4.mkdirs(); - } - - -} - +/******************************************************************************* + * Copyright (c) 2007 VTT Technical Research Centre of Finland and others. + * 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.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.Manifest; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository; +import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository; +import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepositoryFactory; +import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository; +import org.eclipse.equinox.internal.p2.metadata.repository.LocalMetadataRepository; +import org.eclipse.equinox.internal.p2.metadata.repository.SimpleMetadataRepositoryFactory; +import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.core.ProvisionException; +import org.eclipse.equinox.p2.internal.repository.mirroring.Mirroring; +import org.eclipse.equinox.p2.metadata.IArtifactKey; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.metadata.IVersionedId; +import org.eclipse.equinox.p2.metadata.VersionedId; +import org.eclipse.equinox.p2.query.IQuery; +import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.QueryUtil; +import org.eclipse.equinox.p2.repository.artifact.ArtifactKeyQuery; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; +import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; +import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; +import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; +import org.simantics.graph.db.TransferableGraphException; +import org.simantics.graph.query.Graphs; +import org.simantics.graph.query.IGraph; +import org.simantics.graph.query.Paths; +import org.simantics.graph.query.Res; +import org.simantics.graph.query.UriUtils; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.scl.reflection.OntologyVersions; +import org.simantics.utils.FileUtils; + +/** + * Bundlepool is a repository of artifacts and installable units. + * + * @author Toni Kalajainen + */ +@SuppressWarnings("restriction") +public class BundlePool { + + /** Application default pool. It is located at "workspace/bundlepool" */ + static BundlePool DEFAULT; + + IMetadataRepository metadataRepository; + IArtifactRepository artifactRepository; + IProvisioningAgent metadataAgent; + IProvisioningAgent artifactAgent; + URI metadataAgentLocation; + URI artifactAgentLocation; + + List userInstallables; + + /** All features that were discovered in the repository */ + Set projectFeatures = new HashSet(); + + /** + * Get SPM Bundle Pool + * + * @return SPM Bundle Pool + */ + public synchronized static BundlePool getDefault() { + if (DEFAULT == null) { + try { + IPath path = Platform.getLocation().append("bundlepool"); + URI metadataRepositoryLocation = path.toFile().toURI(); + URI artifactRepositoryLocation = path.toFile().toURI(); + IProvisioningAgent agent = P2Util.createAgent( path ); + DEFAULT = new BundlePool(metadataRepositoryLocation, artifactRepositoryLocation, agent); + } catch (ProvisionException e) { + // Not expected + throw new RuntimeException(e); + } + } + return DEFAULT; + } + + /** + * Create bundle pool in a directory on a local hard drive. + * This location will contain metadata repository, artifact repository and + * P2 workarea (Agent). + * + * @param location + * @return bundle pool + */ + public static BundlePool createAt(File location) { + try { + File canonicalLocation = location.getCanonicalFile(); + URI metadataRepositoryLocation = canonicalLocation.toURI(); + URI artifactRepositoryLocation = canonicalLocation.toURI(); + IPath agentLocation = new Path( canonicalLocation.toString() ); + IProvisioningAgent agent = P2Util.createAgent( agentLocation ); + return new BundlePool(metadataRepositoryLocation, artifactRepositoryLocation, agent); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (org.eclipse.equinox.p2.core.ProvisionException e) { + throw new RuntimeException(e); + } + + } + + public BundlePool(URI metadataRepositoryLocation, URI artifactRepositoryLocation, IProvisioningAgent agent) throws ProvisionException { + + this.metadataAgent = agent; + this.artifactAgent = agent; + + SimpleMetadataRepositoryFactory metRepFactory = new SimpleMetadataRepositoryFactory(); + metRepFactory.setAgent( metadataAgent ); + try { + metadataRepository = metRepFactory.load(metadataRepositoryLocation, 0, null); + } catch (org.eclipse.equinox.p2.core.ProvisionException pe) { + new File(metadataRepositoryLocation).mkdirs(); + Map repoProperties = new HashMap(); + metadataRepository = metRepFactory.create(metadataRepositoryLocation, "SPM Bundle Pool", "file", repoProperties); + } + + // IMetadataRepository metadataRepository = new LocalMetadataRepository( agent, repositoryLocation, "My Metadata Repository", Collections.EMPTY_MAP ); + // IMetadataRepository metadataRepository = getMetadataRepository(agent, repositoryLocation); + +// IArtifactRepository artifactRepository = new SimpleArtifactRepositoryFactory().create(repositoryLocation, "Sample Artifact Repository", ArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, Collections.EMPTY_MAP); +// SimpleArtifactRepository artifactRepository = new SimpleArtifactRepository( agent, "My Simple Artifact Repository", repositoryLocation, Collections.EMPTY_MAP); + SimpleArtifactRepositoryFactory artRepFactory = new SimpleArtifactRepositoryFactory(); + artRepFactory.setAgent( artifactAgent ); + + try { + artifactRepository = artRepFactory.load(artifactRepositoryLocation, 0, null); + } catch (org.eclipse.equinox.p2.core.ProvisionException pe) { + new File(artifactRepositoryLocation).mkdirs(); + Map repoProperties = new HashMap(); + artifactRepository = artRepFactory.create(artifactRepositoryLocation, "SPM Bundle Pool", "file", repoProperties); + } + + init(); + } + + public BundlePool(IMetadataRepository metadataRepository, IArtifactRepository artifactRepository) throws ProvisionException { + this.metadataRepository = metadataRepository; + this.artifactRepository = artifactRepository; + this.metadataAgent = metadataRepository.getProvisioningAgent(); + this.artifactAgent = artifactRepository.getProvisioningAgent(); + init(); + } + + /** + * Init prepares with the following actions: + * o loads transferable graphs + * o discovers Features and collects Feature URIs, Artifacts and Installable Units + * + * @throws ProvisionException + */ + protected void init() throws ProvisionException { + try { + projectFeatures.clear(); + + ArrayList platformTGs = new ArrayList(); + + for (IArtifactKey key : getAllArtifactKeys()) { + boolean hasGraph = ProvisioningUtil.hasFile(artifactRepository, key, "graph.tg"); + if (!hasGraph) continue; + + // Read Graph + TransferableGraph1 graph = ProvisioningUtil.getTransferableGraph(artifactRepository, key); + platformTGs.add(graph); + } + + // Create new project, use all features available in Platform + final List poolFeatures = new ArrayList(); + + // Convert graph instances + GraphBundleEx l0 = getLayer0(); + String l0v = l0.getMajor() + "." + l0.getMinor(); + IGraph graph = Graphs.createGraph(new Paths(l0v), platformTGs); + + for(Res feature : graph.getInstances(UriUtils.uriToPath(OntologyVersions.getInstance().currentVersion("http://www.simantics.org/Project-0.0/Feature" )))) { + poolFeatures.add( feature.toString() ); + } + + } catch (TransferableGraphException e) { + throw new ProvisionException("Problem", e); + } catch (IOException e) { + throw new ProvisionException("Failed to read graph.tg", e); + } + } + + public IMetadataRepository getMetadataRepository() { + return metadataRepository; + } + + public IArtifactRepository getArtifactRepository() { + return artifactRepository; + } + + public IArtifactKey[] getAllArtifactKeys() { + return artifactRepository.query( ArtifactKeyQuery.ALL_KEYS, null ).toArray( IArtifactKey.class ); + } + + public GraphBundleEx getLayer0() throws ProvisionException, TransferableGraphException { + IVersionedId vid = VersionedId.parse("org.simantics.layer0"); + Set result = metadataRepository.query( QueryUtil.createLatestQuery( QueryUtil.createIUQuery(vid) ), null).toSet(); + if (result.isEmpty()) throw new RuntimeException("Unexpectedly got no IU for "+vid); + if (result.size()>1) throw new RuntimeException("Unexpectedly got more than one latest IU for "+vid); + IInstallableUnit iu = result.iterator().next(); + IArtifactKey key = toSingleArtifact(iu); + TransferableGraph1 graph = getTransferableGraph( key ); + return new GraphBundleEx( "Layer0", graph, key); + } + + public TransferableGraph1 getTransferableGraph(IArtifactKey artifactKey) throws ProvisionException, TransferableGraphException { + return ProvisioningUtil.getTransferableGraph( artifactRepository, artifactKey); + } + + + + /** + * Get all features. + * + * @param a list of features + * @throws ProvisionException + */ + public void getFeatures(List features) throws ProvisionException { + IMetadataRepository metadataRepository = getMetadataRepository(); + + Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); + for (IInstallableUnit iu : ius) { + if (ProvisioningUtil.isGroup(iu)) { +// if (P2Util.isFeature(iu)) { + BundleInfo b = BundleInfo.read(iu); + features.add( b ); + } + } + } + + /** + * Get bundle info + * + * @param id bundle id + * @return bundle info + */ + public BundleInfo getBundleInfo(String id) { + IQuery query = QueryUtil.createLatestQuery( QueryUtil.createIUQuery(id) ); + IQueryResult queryResult = metadataRepository.query(query, null); + IInstallableUnit[] array = queryResult.toArray( IInstallableUnit.class ); + for (IInstallableUnit iu : array) { + BundleInfo bi = BundleInfo.read(iu); + return bi; + } + return null; + } + + /** + * Get the features that visible for the end-user. + * User installable features are configured in Simantics manifest files + * (META-INF/SIMANTICS.MF as Simantics-Features-Bundle -property) + * + * @param result + * @throws IOException + */ +// public void getUserInstallableFeatures(Collection result) throws IOException { +// ArrayList ids = new ArrayList(); +// ProvisioningUtil.getUserInstallables(artifactRepository, ids); +// for (String id : ids) { +// BundleInfo bi = getBundleInfo(id); +// if (bi != null) result.add( bi ); +// } +// // Add workspace bundle +// BundleInfo bi = getBundleInfo( "org.simantics.workbench.product" ); +// if (bi != null) result.add( bi ); +// } + + /** + * Get all groups. + * + * @param a list of features + * @throws ProvisionException + */ +// public void getInstallableFeatures(List features) throws ProvisionException { +// IMetadataRepository metadataRepository = getMetadataRepository(); +// +// Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); +// for (IInstallableUnit iu : ius) { +// if (ProvisioningUtil.isGroup(iu)) { +//// if (P2Util.isFeature(iu)) { +// BundleInfo b = BundleInfo.read(iu); +// features.add( b ); +// } +// } +// } + + /** + * Mirror source locations to the bundle pool. + * + * @param monitor + * @param sourceLocations + * @return + * @throws ProvisionException + */ + public IStatus download(IProgressMonitor monitor, URI[] sourceLocations) throws ProvisionException { + try { + monitor.beginTask("Synchronizing Local repository with web repositories", 10); + + @SuppressWarnings("unused") + IMetadataRepositoryManager metaRepoMgr = (IMetadataRepositoryManager) metadataAgent.getService(IMetadataRepositoryManager.SERVICE_NAME); + @SuppressWarnings("unused") + IArtifactRepositoryManager artsRepoMgr = (IArtifactRepositoryManager) artifactAgent.getService(IArtifactRepositoryManager.SERVICE_NAME); + + + // Create dest repos + monitor.setTaskName("Setting up local metadata repository"); + LocalMetadataRepository dstMetaRepo = (LocalMetadataRepository) metadataRepository; + monitor.worked(1); + + monitor.setTaskName("Setting up local artifact repository"); + SimpleArtifactRepository dstArtsRepo = (SimpleArtifactRepository) artifactRepository; + monitor.worked(1); + + // Create a source repos + monitor.setTaskName("Setting up remote artifact repository"); + CompositeArtifactRepository srcArtsRepo = CompositeArtifactRepository.createMemoryComposite( metadataAgent /* ? */ ); + for (URI uri : sourceLocations) srcArtsRepo.addChild(uri); + monitor.worked(1); + + monitor.setTaskName("Setting up remote metadata repository"); + CompositeMetadataRepository srcMetaRepo = CompositeMetadataRepository.createMemoryComposite( artifactAgent /* ? */ ); + for (URI uri : sourceLocations) srcMetaRepo.addChild(uri); + monitor.worked(1); + + monitor.setTaskName("Retrieving Installable Units"); + @SuppressWarnings("unused") + Collection ius = ProvisioningUtil.getInstallableUnits(srcMetaRepo); + monitor.worked(1); + + monitor.setTaskName("Mirroring Metadata"); + // Get all IUs from source + IQueryResult allIUs = srcMetaRepo.query(QueryUtil.createIUAnyQuery(), monitor); + // Put the IUs to dst + dstMetaRepo.addInstallableUnits(allIUs.toUnmodifiableSet()); + dstMetaRepo.addReferences(srcMetaRepo.getReferences()); + monitor.worked(1); + + monitor.setTaskName("Mirroring Artifacts"); + + boolean compare = false; + boolean failOnError = true; + //boolean raw = true; + boolean verbose = false; + boolean validate = false; + //boolean mirrorReferences = false; + String comparatorID = ""; + + Mirroring mirror = new Mirroring(srcArtsRepo, dstArtsRepo, false); + mirror.setCompare(compare); + mirror.setComparatorId(comparatorID); + // mirror.setBaseline(null); + mirror.setValidate(validate); + // mirror.setCompareExclusions(); + + IStatus result = mirror.run(failOnError, verbose); + if (result.getException()!=null) + throw new ProvisionException(result); + + init(); + + return result; + } catch (IllegalArgumentException iae) { + return new Status(IStatus.ERROR, "org.simantics.project", iae.getMessage(), iae); + } + } + + public IInstallableUnit toSingleInstallableUnit(IVersionedId id) throws ProvisionException { + Set result = metadataRepository.query( QueryUtil.createIUQuery(id), null).toSet(); + if (result.size() != 1) throw new RuntimeException("Unexpectedly got more than one latest IU for "+id); + return result.iterator().next(); + } + + public IArtifactKey toSingleArtifact(IVersionedId id) throws ProvisionException { + IInstallableUnit iu = toSingleInstallableUnit(id); + if (iu.getArtifacts().size() != 1) throw new RuntimeException("Unexpectedly got more than one artifact for "); + return iu.getArtifacts().iterator().next(); + } + + /** + * Get file from an artifact. + * + * @param key + * @param filename + * @return inputstream or null. Inputstream must be closed. + * @throws IOException + */ + public InputStream getFile(IArtifactKey key, String filename) throws IOException { + return ProvisioningUtil.getFile(artifactRepository, key, filename); + } + + /** + * Checks whether there exists a file in an artifact + * + * @param key + * @param filename + * @return true file exists in the artifact + * @throws IOException + */ + public boolean hasFile(IArtifactKey key, String filename) throws IOException { + return ProvisioningUtil.hasFile(artifactRepository, key, filename); + } + + /** + * Get META-INF/MANIFEST.MF + * + * @param repo artifact repo + * @param key key to artifact + * @return manifest or null + * @throws IOException + */ + public Manifest getManifest(IArtifactKey key) throws IOException { + return ProvisioningUtil.getManifest(artifactRepository, key); + } + + /** + * Get META-INF/SIMANTICS.MF + * + * @param repo artifact repo + * @param key key to artifact + * @return manifest or null + * @throws IOException + */ + public Manifest getSimanticsManifest(IArtifactKey key) throws IOException { + return ProvisioningUtil.getManifest(artifactRepository, key); + } + + /** + * Get list of user installable bundles + * + * @param result + * @throws IOException + */ + public void getUserInstallables(List result) throws IOException { + if (userInstallables==null) { + userInstallables = new ArrayList(); + + List topLevelBundles = new ArrayList(); + ProvisioningUtil.getUserInstallables(artifactRepository, topLevelBundles); + + for (String bundleId : topLevelBundles) { + IInstallableUnit ius[] = metadataRepository.query( QueryUtil.createIUQuery(bundleId) , null).toArray( IInstallableUnit.class ); + for (IInstallableUnit iu : ius) { + userInstallables.add( BundleInfo.read(iu) ); + } + } + + } + result.addAll(userInstallables); + } + + + + /////////// + /////////// GRAPHS + /////////// + + + +// /** +// * Get graph bundles +// * +// * @param list to be populated with graph bundle ids +// * @throws ProvisionException +// * @throws IOException +// */ +// public void getGraphs(List graphs) throws ProvisionException, IOException { +// Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); +// for (IInstallableUnit iu : ius) { +// if (isGraph(iu)) { +// BundleInfo b = BundleInfo.read(iu); +// graphs.add( b ); +// } +// } +// } + + /** + * Get graph bundles + * + * @param list to be populated with graph bundle ids + * @throws ProvisionException + * @throws IOException + * @throws TransferableGraphException + */ + public void getGraphBundles(List graphs) throws ProvisionException, IOException, TransferableGraphException { + Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); + for (IInstallableUnit iu : ius) { + for (IArtifactKey key : iu.getArtifacts()) { + if (!ProvisioningUtil.isGraphArtifact(artifactRepository, key)) continue; + TransferableGraph1 tg = ProvisioningUtil.getTransferableGraph( artifactRepository, key ); + GraphBundleEx b = new GraphBundleEx(iu.getId(), tg, key); + graphs.add( b ); + } + } + } + + /** + * Get a list of all features. Features are uris, they are versionless. + * @return fetures + * @throws TransferableGraphException + * @throws IOException + */ + public Set getFeatures() throws IOException, TransferableGraphException { + /* + HashSet result = new HashSet(); + Collection ius = ProvisioningUtil.getInstallableUnits(metadataRepository); + for (IInstallableUnit iu : ius) { + for (IArtifactKey key : iu.getArtifacts()) { + if (!ProvisioningUtil.isGraphArtifact(artifactRepository, key)) continue; + TransferableGraph1 tg = ProvisioningUtil.getTransferableGraph( artifactRepository, key ); + IGraph g = Graphs.createGraph(tg); + + Res PublishedProjectFeatures = UriUtils.uriToPath( ProjectResource.URIs.PublishedProjectFeatures ); + Path HasFeature = UriUtils.uriToPath( ProjectResource.URIs.HasFeature ); + for(Res feature : g.getObjects(PublishedProjectFeatures, HasFeature)) { + String uri = feature.toString(); + String name = feature instanceof PathChild ? ((PathChild)feature).name : uri; + + FeatureInfo fi = new FeatureInfo(name, uri, null, null); + result.add( fi ); + } + } + } + + return result; + */ + return Collections.emptySet(); + } + + /** + * For a set of extact feature ids (id_version), find the set of graph bundles + * required in the database. + * + * @param featureIds feature + * @return graph bundles + */ + public Set getRequiredGraphBundles(Collection featureIds) { + + return null; + } + + /** + * Checks whether artifact is a graph bundle. + * + * @param key key to artifact + * @return true if is a graph bundle + * @throws IOException + */ + public boolean isGraphArtifact(IArtifactKey key) throws IOException { + return ProvisioningUtil.isGraphArtifact(artifactRepository, key); + } + + /** + * Checks wheter iu is graph + * + * @param iu + * @return + * @throws IOException + */ + public boolean isGraph(IInstallableUnit iu) throws IOException { + return ProvisioningUtil.isGraph(iu, metadataRepository, artifactRepository); + } + + /** + * Delete default repositories located in /P2 folder + * @throws IOException + */ + public void delete() throws IOException { + File location1 = new File(metadataAgentLocation); + File location2 = new File(artifactAgentLocation); + File location3 = new File(metadataRepository.getLocation()); + File location4 = new File(artifactRepository.getLocation()); + FileUtils.deleteDir(location1); + FileUtils.deleteDir(location2); + FileUtils.deleteDir(location3); + FileUtils.deleteDir(location4); + location1.mkdirs(); + location2.mkdirs(); + location3.mkdirs(); + location4.mkdirs(); + } + + +} +