X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=runtime%2Forg.argeo.slc.repo%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Frepo%2FRepoUtils.java;h=b0e65bce51612e757daedc4265c343ad9b620f9e;hb=1e6cf7254fb9f150251594cf0383b3b1c5210517;hp=c962daf2e29be57a23c0fb7a974c83518e9d7cde;hpb=142bc73155f308b5e0dd5e9ae4f505db0ca21eec;p=gpl%2Fargeo-slc.git diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java index c962daf2e..b0e65bce5 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.argeo.slc.repo; import java.io.ByteArrayOutputStream; @@ -8,7 +23,9 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.Iterator; +import java.util.Set; import java.util.StringTokenizer; +import java.util.TreeSet; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -25,6 +42,7 @@ import javax.jcr.PropertyIterator; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; +import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.nodetype.NodeType; @@ -32,13 +50,15 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.argeo.ArgeoMonitor; import org.argeo.jcr.ArgeoJcrUtils; import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.ArgeoTypes; import org.argeo.jcr.JcrUtils; -import org.argeo.slc.BasicNameVersion; +import org.argeo.slc.DefaultNameVersion; import org.argeo.slc.NameVersion; import org.argeo.slc.SlcException; +import org.argeo.slc.aether.ArtifactIdComparator; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; import org.argeo.slc.repo.maven.MavenConventionsUtils; @@ -222,17 +242,30 @@ public class RepoUtils implements ArgeoNames, SlcNames { /** Read the OSGi {@link NameVersion} */ public static NameVersion readNameVersion(File artifactFile) { - JarInputStream jarInputStream = null; try { - jarInputStream = new JarInputStream(new FileInputStream( - artifactFile)); - return readNameVersion(jarInputStream.getManifest()); + return readNameVersion(new FileInputStream(artifactFile)); } catch (Exception e) { // probably not a jar, skipping if (log.isDebugEnabled()) { log.debug("Skipping " + artifactFile + " because of " + e); // e.printStackTrace(); } + } + return null; + } + + /** Read the OSGi {@link NameVersion} */ + public static NameVersion readNameVersion(InputStream in) { + JarInputStream jarInputStream = null; + try { + jarInputStream = new JarInputStream(in); + return readNameVersion(jarInputStream.getManifest()); + } catch (Exception e) { + // probably not a jar, skipping + if (log.isDebugEnabled()) { + log.debug("Skipping because of " + e); + e.printStackTrace(); + } } finally { IOUtils.closeQuietly(jarInputStream); } @@ -241,7 +274,7 @@ public class RepoUtils implements ArgeoNames, SlcNames { /** Read the OSGi {@link NameVersion} */ public static NameVersion readNameVersion(Manifest manifest) { - BasicNameVersion nameVersion = new BasicNameVersion(); + DefaultNameVersion nameVersion = new DefaultNameVersion(); nameVersion.setName(manifest.getMainAttributes().getValue( Constants.BUNDLE_SYMBOLICNAME)); @@ -283,6 +316,22 @@ public class RepoUtils implements ArgeoNames, SlcNames { } } + /** + * The path to the PDE source related to this artifact (or artifact version + * base). There may or there may not be a node at this location (the + * returned path will typically be used to test whether PDE sources are + * attached to this artifact). + */ + public static String relatedPdeSourcePath(String artifactBasePath, + Node artifactNode) throws RepositoryException { + Artifact artifact = asArtifact(artifactNode); + Artifact pdeSourceArtifact = new DefaultArtifact(artifact.getGroupId(), + artifact.getArtifactId() + ".source", artifact.getExtension(), + artifact.getVersion()); + return MavenConventionsUtils.artifactPath(artifactBasePath, + pdeSourceArtifact); + } + /** * Copy this bytes array as an artifact, relative to the root of the * repository (typically the workspace root node) @@ -337,11 +386,10 @@ public class RepoUtils implements ArgeoNames, SlcNames { throw new SlcException("Cannot connect to repository " + repoNode, e); } - } /** - * Reads credentials from node, using keyring if there is a password. Cann + * Reads credentials from node, using keyring if there is a password. Can * return null if no credentials needed (local repo) at all, but returns * {@link GuestCredentials} if user id is 'anonymous' . */ @@ -369,14 +417,140 @@ public class RepoUtils implements ArgeoNames, SlcNames { } } + /** + * Shortcut to retrieve a session given variable information: Handle the + * case where we only have an URI of the repository, that we want to connect + * as anonymous or the case of a identified connection to a local or remote + * repository. + * + * Callers must close the session once it has been used + */ + public static Session getRemoteSession(RepositoryFactory repositoryFactory, + Keyring keyring, Node repoNode, String uri, String workspaceName) { + try { + if (repoNode == null && uri == null) + throw new SlcException( + "At least one of repoNode and uri must be defined"); + Repository currRepo = null; + Credentials credentials = null; + // Anonymous URI only workspace + if (repoNode == null) + // Anonymous + currRepo = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, + uri); + else { + currRepo = RepoUtils.getRepository(repositoryFactory, keyring, + repoNode); + credentials = RepoUtils.getRepositoryCredentials(keyring, + repoNode); + } + return currRepo.login(credentials, workspaceName); + } catch (RepositoryException e) { + throw new SlcException("Cannot connect to workspace " + + workspaceName + " of repository " + repoNode + + " with URI " + uri, e); + } + } + + /** + * Shortcut to retrieve a session on a remote Jrc Repository from + * information stored in a local argeo node or from an URI: Handle the case + * where we only have an URI of the repository, that we want to connect as + * anonymous or the case of a identified connection to a local or remote + * repository. + * + * Callers must close the session once it has been used + */ + public static Session getRemoteSession(RepositoryFactory repositoryFactory, + Keyring keyring, Repository localRepository, String repoNodePath, + String uri, String workspaceName) { + Session localSession = null; + Node repoNode = null; + try { + localSession = localRepository.login(); + if (repoNodePath != null && localSession.nodeExists(repoNodePath)) + repoNode = localSession.getNode(repoNodePath); + + return RepoUtils.getRemoteSession(repositoryFactory, keyring, + repoNode, uri, workspaceName); + } catch (RepositoryException e) { + throw new SlcException("Cannot log to workspace " + workspaceName + + " for repo defined in " + repoNodePath, e); + } finally { + JcrUtils.logoutQuietly(localSession); + } + } + + /** + * Write group indexes: 'binaries' lists all bundles and their versions, + * 'sources' list theire sources, and 'sdk' aggregates both. + */ + public static void writeGroupIndexes(Session session, + String artifactBasePath, String groupId, String version, + Set binaries, Set sources) { + try { + Set indexes = new TreeSet( + new ArtifactIdComparator()); + Artifact binariesArtifact = writeIndex(session, artifactBasePath, + groupId, RepoConstants.BINARIES_ARTIFACT_ID, version, + binaries); + indexes.add(binariesArtifact); + if (sources != null) { + Artifact sourcesArtifact = writeIndex(session, + artifactBasePath, groupId, + RepoConstants.SOURCES_ARTIFACT_ID, version, sources); + indexes.add(sourcesArtifact); + } + // sdk + writeIndex(session, artifactBasePath, groupId, + RepoConstants.SDK_ARTIFACT_ID, version, indexes); + session.save(); + } catch (RepositoryException e) { + throw new SlcException("Cannot write indexes for group " + groupId, + e); + } + } + + /** Write a group index. */ + private static Artifact writeIndex(Session session, + String artifactBasePath, String groupId, String artifactId, + String version, Set artifacts) throws RepositoryException { + Artifact artifact = new DefaultArtifact(groupId, artifactId, "pom", + version); + String pom = MavenConventionsUtils.artifactsAsDependencyPom(artifact, + artifacts, null); + Node node = RepoUtils.copyBytesAsArtifact( + session.getNode(artifactBasePath), artifact, pom.getBytes()); + addMavenChecksums(node); + return artifact; + } + + /** Add files containing the SHA-1 and MD5 checksums. */ + public static void addMavenChecksums(Node node) throws RepositoryException { + // TODO optimize + String sha = JcrUtils.checksumFile(node, "SHA-1"); + JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".sha1", + sha.getBytes()); + String md5 = JcrUtils.checksumFile(node, "MD5"); + JcrUtils.copyBytesAsFile(node.getParent(), node.getName() + ".md5", + md5.getBytes()); + } + /** * Custom copy since the one in commons does not fit the needs when copying * a workspace completely. */ public static void copy(Node fromNode, Node toNode) { + copy(fromNode, toNode, null); + } + + public static void copy(Node fromNode, Node toNode, ArgeoMonitor monitor) { try { + String fromPath = fromNode.getPath(); + if (monitor != null) + monitor.subTask("copying node :" + fromPath); if (log.isDebugEnabled()) - log.debug("copy node :" + fromNode.getPath()); + log.debug("copy node :" + fromPath); // FIXME : small hack to enable specific workspace copy if (fromNode.isNodeType("rep:ACL") @@ -457,6 +631,9 @@ public class RepoUtils implements ArgeoNames, SlcNames { if (toNode.isNodeType(SlcTypes.SLC_ARTIFACT)) toNode.getSession().save(); + if (monitor != null) + monitor.worked(1); + } catch (RepositoryException e) { throw new SlcException("Cannot copy " + fromNode + " to " + toNode, e);