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=3d7d5920d04cffa6b7524cd864a7b427d37e9c67;hb=8bc47c1403b47e1e35413ead26a606195c21549e;hp=242cbe0e4242a86412e20e2761bd48b26ead64ce;hpb=44c43b9c874d7c6edd4327f180d5506b3e9c99e6;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 242cbe0e4..3d7d5920d 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; @@ -16,24 +31,39 @@ import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; +import javax.jcr.Credentials; +import javax.jcr.GuestCredentials; import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.Repository; import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; +import javax.jcr.SimpleCredentials; +import javax.jcr.nodetype.NodeType; 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.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.NameVersion; import org.argeo.slc.SlcException; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; +import org.argeo.slc.repo.maven.MavenConventionsUtils; +import org.argeo.util.security.Keyring; import org.osgi.framework.Constants; import org.sonatype.aether.artifact.Artifact; import org.sonatype.aether.util.artifact.DefaultArtifact; /** Utilities around repo */ -public class RepoUtils implements SlcNames { +public class RepoUtils implements ArgeoNames, SlcNames { private final static Log log = LogFactory.getLog(RepoUtils.class); /** Packages a regular sources jar as PDE source. */ @@ -207,15 +237,28 @@ public class RepoUtils implements SlcNames { /** Read the OSGi {@link NameVersion} */ public static NameVersion readNameVersion(File artifactFile) { + try { + 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(new FileInputStream( - artifactFile)); + jarInputStream = new JarInputStream(in); return readNameVersion(jarInputStream.getManifest()); } catch (Exception e) { // probably not a jar, skipping if (log.isDebugEnabled()) { - log.debug("Skipping " + artifactFile + " because of " + e); + log.debug("Skipping because of " + e); // e.printStackTrace(); } } finally { @@ -268,6 +311,184 @@ public class RepoUtils implements SlcNames { } } + /** + * Copy this bytes array as an artifact, relative to the root of the + * repository (typically the workspace root node) + */ + public static Node copyBytesAsArtifact(Node artifactsBase, + Artifact artifact, byte[] bytes) throws RepositoryException { + String parentPath = MavenConventionsUtils.artifactParentPath( + artifactsBase.getPath(), artifact); + Node folderNode = JcrUtils.mkfolders(artifactsBase.getSession(), + parentPath); + return JcrUtils.copyBytesAsFile(folderNode, + MavenConventionsUtils.artifactFileName(artifact), bytes); + } + private RepoUtils() { } + + /** If a source return the base bundle name, does not change otherwise */ + public static String extractBundleNameFromSourceName(String sourceBundleName) { + if (sourceBundleName.endsWith(".source")) + return sourceBundleName.substring(0, sourceBundleName.length() + - ".source".length()); + else + return sourceBundleName; + } + + /* + * SOFTWARE REPOSITORIES + */ + + /** Retrieve repository based on information in the repo node */ + public static Repository getRepository(RepositoryFactory repositoryFactory, + Keyring keyring, Node repoNode) { + try { + Repository repository; + if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) { + String uri = repoNode.getProperty(ARGEO_URI).getString(); + if (uri.startsWith("http")) {// http, https + repository = ArgeoJcrUtils.getRepositoryByUri( + repositoryFactory, uri); + } else if (uri.startsWith("vm:")) {// alias + repository = ArgeoJcrUtils.getRepositoryByUri( + repositoryFactory, uri); + } else { + throw new SlcException("Unsupported repository uri " + uri); + } + return repository; + } else { + throw new SlcException("Unsupported node type " + repoNode); + } + } catch (RepositoryException e) { + throw new SlcException("Cannot connect to repository " + repoNode, + e); + } + + } + + /** + * Reads credentials from node, using keyring if there is a password. Cann + * return null if no credentials needed (local repo) at all, but returns + * {@link GuestCredentials} if user id is 'anonymous' . + */ + public static Credentials getRepositoryCredentials(Keyring keyring, + Node repoNode) { + try { + if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) { + if (!repoNode.hasProperty(ARGEO_USER_ID)) + return null; + + String userId = repoNode.getProperty(ARGEO_USER_ID).getString(); + if (userId.equals("anonymous"))// FIXME hardcoded userId + return new GuestCredentials(); + char[] password = keyring.getAsChars(repoNode.getPath() + '/' + + ARGEO_PASSWORD); + Credentials credentials = new SimpleCredentials(userId, + password); + return credentials; + } else { + throw new SlcException("Unsupported node type " + repoNode); + } + } catch (RepositoryException e) { + throw new SlcException("Cannot connect to repository " + repoNode, + e); + } + } + + /** + * 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) { + try { + if (log.isDebugEnabled()) + log.debug("copy node :" + fromNode.getPath()); + + // FIXME : small hack to enable specific workspace copy + if (fromNode.isNodeType("rep:ACL") + || fromNode.isNodeType("rep:system")) { + if (log.isTraceEnabled()) + log.trace("node " + fromNode + " skipped"); + return; + } + + // add mixins + for (NodeType mixinType : fromNode.getMixinNodeTypes()) { + toNode.addMixin(mixinType.getName()); + } + + // Double check + for (NodeType mixinType : toNode.getMixinNodeTypes()) { + if (log.isDebugEnabled()) + log.debug(mixinType.getName()); + } + + // process properties + PropertyIterator pit = fromNode.getProperties(); + properties: while (pit.hasNext()) { + Property fromProperty = pit.nextProperty(); + String propName = fromProperty.getName(); + try { + String propertyName = fromProperty.getName(); + if (toNode.hasProperty(propertyName) + && toNode.getProperty(propertyName).getDefinition() + .isProtected()) + continue properties; + + if (fromProperty.getDefinition().isProtected()) + continue properties; + + if (propertyName.equals("jcr:created") + || propertyName.equals("jcr:createdBy") + || propertyName.equals("jcr:lastModified") + || propertyName.equals("jcr:lastModifiedBy")) + continue properties; + + if (fromProperty.isMultiple()) { + toNode.setProperty(propertyName, + fromProperty.getValues()); + } else { + toNode.setProperty(propertyName, + fromProperty.getValue()); + } + } catch (RepositoryException e) { + throw new SlcException("Cannot property " + propName, e); + } + } + + // recursively process children nodes + NodeIterator nit = fromNode.getNodes(); + while (nit.hasNext()) { + Node fromChild = nit.nextNode(); + Integer index = fromChild.getIndex(); + String nodeRelPath = fromChild.getName() + "[" + index + "]"; + Node toChild; + if (toNode.hasNode(nodeRelPath)) + toChild = toNode.getNode(nodeRelPath); + else + toChild = toNode.addNode(fromChild.getName(), fromChild + .getPrimaryNodeType().getName()); + copy(fromChild, toChild); + } + + // update jcr:lastModified and jcr:lastModifiedBy in toNode in + // case + // they existed + if (!toNode.getDefinition().isProtected() + && toNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) + JcrUtils.updateLastModified(toNode); + + // Workaround to reduce session size: artifact is a saveable + // unity + if (toNode.isNodeType(SlcTypes.SLC_ARTIFACT)) + toNode.getSession().save(); + + } catch (RepositoryException e) { + throw new SlcException("Cannot copy " + fromNode + " to " + toNode, + e); + } + } + }