--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns:flow="http://www.argeo.org/schema/slc-flow" xmlns="http://www.springframework.org/schema/beans"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"\r
+ xsi:schemaLocation="\r
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+ http://www.argeo.org/schema/slc-flow http://www.argeo.org/schema/slc-flow-1.2.xsd">\r
+\r
+ <!-- Hello world -->\r
+ <flow:flow name="sync">\r
+ <flow:spec>\r
+ <flow:primitive name="sourceRepo"\r
+ value="https://repo.argeo.org/org.argeo.jcr.webapp/remoting/java" />\r
+ <flow:primitive name="sourceWksp" />\r
+ <flow:primitive name="sourceUsername" value="${user.name}" />\r
+ <flow:primitive name="sourcePassword" type="password"/>\r
+ <flow:primitive name="targetRepo" value="vm:///java/" />\r
+ </flow:spec>\r
+ <bean class="org.argeo.slc.repo.RepoSync">\r
+ <flow:variable proxy-target-class="false" />\r
+ <property name="sourceRepo" value="@{sourceRepo}" />\r
+ <property name="sourceWksp" value="@{sourceWksp}" />\r
+ <property name="sourceUsername" value="@{sourceUsername}" />\r
+ <property name="sourcePassword" value="@{sourcePassword}" />\r
+ <property name="targetRepo" value="@{targetRepo}" />\r
+ <property name="repositoryFactory" ref="repositoryFactory" />\r
+ </bean>\r
+ </flow:flow>\r
+\r
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+ <!-- IMPORTS -->\r
+ <beans:import resource="classpath:org/argeo/slc/core/execution/spring.xml" />\r
+ <beans:import resource="classpath:org/argeo/slc/osgi/execution.xml" />\r
+\r
+ <!-- REFERENCES -->\r
+ <reference id="repositoryFactory" interface="javax.jcr.RepositoryFactory" />\r
+</beans:beans>
\ No newline at end of file
</parent>
<artifactId>org.argeo.slc.lib.repo</artifactId>
<name>SLC Lib - Repository Utilities</name>
+ <description>Utilities to transfer, convert, manage software repositories</description>
</project>
<packaging>pom</packaging>
<name>SLC Standard Libs</name>
<description>SLC execution modules for generic tasks, to be used as parent pom</description>
+ <modules>
+ <module>org.argeo.slc.lib.repo</module>
+ </modules>
<properties>
<additionalImports.slc-lib>
com.jcraft.jsch;resolution:=optional,
+++ /dev/null
-package org.argeo.slc.client.ui.dist;
-
-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.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrUtils;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.jcr.SlcNames;
-import org.argeo.slc.jcr.SlcTypes;
-import org.argeo.util.security.Keyring;
-
-/** Static utilities */
-public class DistUiUtils implements ArgeoNames, SlcNames {
- private final static Log log = LogFactory.getLog(DistUiUtils.class);
-
- /** 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 {// alias
- String alias = uri;
- repository = ArgeoJcrUtils.getRepositoryByAlias(
- repositoryFactory, alias);
- }
- 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 ArgeoException("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 ArgeoException("Cannot copy " + fromNode + " to "
- + toNode, e);
- }
- }
-
- private DistUiUtils() {
-
- }
-}
import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
import org.argeo.slc.client.ui.dist.DistPlugin;
-import org.argeo.slc.client.ui.dist.DistUiUtils;
import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
+import org.argeo.slc.repo.RepoUtils;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
newSession = repository.login(newWorkspaceName);
// newSession.save();
Node newRootNode = newSession.getRootNode();
- DistUiUtils.copy(srcRootNode, newRootNode);
+ RepoUtils.copy(srcRootNode, newRootNode);
newSession.save();
CommandHelpers.callCommand(RefreshDistributionsView.ID);
import org.argeo.jcr.UserJcrUtils;
import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistPlugin;
-import org.argeo.slc.client.ui.dist.DistUiUtils;
import org.argeo.slc.client.ui.dist.commands.CopyWorkspace;
import org.argeo.slc.client.ui.dist.commands.CreateWorkspace;
import org.argeo.slc.client.ui.dist.commands.DeleteWorkspace;
import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.repo.RepoConstants;
+import org.argeo.slc.repo.RepoUtils;
import org.argeo.util.security.Keyring;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.NONE);
col.getColumn().setWidth(200);
- // col.getColumn().setText("Workspace");
col.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
if (!repos.hasNode(alias)) {
Node repoNode = repos.addNode(alias,
ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
- repoNode.setProperty(ARGEO_URI, alias);
+ repoNode.setProperty(ARGEO_URI, "vm:///" + alias);
repoNode.addMixin(NodeType.MIX_TITLE);
- repoNode.setProperty(Property.JCR_TITLE, "vm://" + alias);
+ repoNode.setProperty(Property.JCR_TITLE, "Internal "
+ + alias + " repository");
nodeSession.save();
}
}
protected void connect() {
if (repository != null)
return;
- repository = DistUiUtils.getRepository(repositoryFactory, keyring,
- repoNode);
- credentials = DistUiUtils.getRepositoryCredentials(keyring,
+ repository = RepoUtils.getRepository(repositoryFactory, keyring,
repoNode);
+ credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode);
}
public String getLabel() {
try {
String sourceWorkspace = sourceDist.getWorkspaceName();
- Repository sourceRepository = DistUiUtils.getRepository(
+ Repository sourceRepository = RepoUtils.getRepository(
repositoryFactory, keyring, sourceDist
.getWorkspaceNode().getParent());
- Credentials sourceCredentials = DistUiUtils
+ Credentials sourceCredentials = RepoUtils
.getRepositoryCredentials(keyring, sourceDist
.getWorkspaceNode().getParent());
String targetWorkspace = sourceWorkspace;
- Repository targetRepository = DistUiUtils.getRepository(
+ Repository targetRepository = RepoUtils.getRepository(
repositoryFactory, keyring, targetRepo.getRepoNode());
- Credentials targetCredentials = DistUiUtils
+ Credentials targetCredentials = RepoUtils
.getRepositoryCredentials(keyring,
targetRepo.getRepoNode());
<modules>
<module>runtime</module>
<module>modules</module>
- <module>lib</module>
<module>plugins</module>
<module>dep</module>
+ <module>lib</module>
<module>archetypes</module>
<module>dist</module>
<module>demo</module>
--- /dev/null
+package org.argeo.slc.repo;
+
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.ArgeoJcrUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+
+/** Sync to from software repositories */
+public class RepoSync implements Runnable {
+ private final static Log log = LogFactory.getLog(RepoSync.class);
+
+ private String sourceRepo;
+ private String targetRepo;
+
+ private String sourceWksp;
+
+ private String sourceUsername;
+ private char[] sourcePassword;
+
+ private RepositoryFactory repositoryFactory;
+
+ public void run() {
+ try {
+ long begin = System.currentTimeMillis();
+
+ Repository sourceRepository = ArgeoJcrUtils.getRepositoryByUri(
+ repositoryFactory, sourceRepo);
+ Repository targetRepository = ArgeoJcrUtils.getRepositoryByUri(
+ repositoryFactory, targetRepo);
+ Credentials sourceCredentials = null;
+ if (sourceUsername != null)
+ sourceCredentials = new SimpleCredentials(sourceUsername,
+ sourcePassword);
+ Session sourceSession = sourceRepository.login(sourceCredentials,
+ sourceWksp);
+
+ Credentials targetCredentials = null;
+ Session targetSession = targetRepository.login(targetCredentials,
+ sourceWksp);
+
+ Long count = JcrUtils.copyFiles(sourceSession.getRootNode(),
+ targetSession.getRootNode(), true, null);
+
+ long duration = (System.currentTimeMillis() - begin) / 1000;// in
+ // s
+ if (log.isDebugEnabled())
+ log.debug("Copied " + count + " files in " + (duration / 60)
+ + "min " + (duration % 60) + "s");
+ } catch (RepositoryException e) {
+ throw new SlcException("Cannot sync " + sourceRepo + " to "
+ + targetRepo, e);
+ }
+ }
+
+ public void setSourceRepo(String sourceRepo) {
+ this.sourceRepo = sourceRepo;
+ }
+
+ public void setTargetRepo(String targetRepo) {
+ this.targetRepo = targetRepo;
+ }
+
+ public void setSourceWksp(String sourceWksp) {
+ this.sourceWksp = sourceWksp;
+ }
+
+ public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+ this.repositoryFactory = repositoryFactory;
+ }
+
+ public void setSourceUsername(String sourceUsername) {
+ this.sourceUsername = sourceUsername;
+ }
+
+ public void setSourcePassword(char[] sourcePassword) {
+ this.sourcePassword = sourcePassword;
+ }
+
+}
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.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. */
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);
+ }
+ }
+
}