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
+ <!-- Sync from to repository -->\r
<flow:flow name="sync">\r
<flow:spec>\r
- <flow:primitive name="sourceRepo"\r
+ <flow:primitive name="sourceRepoUri"\r
value="http://repo.argeo.org/data/pub/java" />\r
<flow:primitive name="sourceWksp" value="" />\r
<flow:primitive name="sourceUsername" value="${user.name}" />\r
<flow:primitive name="targetUsername" value="${user.name}" />\r
<flow:primitive name="targetPassword" type="password"\r
value="" />\r
- <flow:primitive name="targetRepo" value="vm:///java/" />\r
+ <flow:primitive name="targetRepoUri" 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="sourceRepoUri" value="@{sourceRepo}" />\r
<property name="sourceWksp" value="@{sourceWksp}" />\r
<property name="sourceUsername" value="@{sourceUsername}" />\r
<property name="sourcePassword" value="@{sourcePassword}" />\r
<property name="targetUsername" value="@{targetUsername}" />\r
<property name="targetPassword" value="@{targetPassword}" />\r
- <property name="targetRepo" value="@{targetRepo}" />\r
+ <property name="targetRepoUri" value="@{targetRepo}" />\r
<property name="repositoryFactory" ref="repositoryFactory" />\r
</bean>\r
</flow:flow>\r
scope="prototype">
<property name="repository" ref="javaRepository" />
</bean>
+ <bean id="repoSyncCommand" class="org.argeo.slc.client.ui.dist.commands.RepoSyncCommand"
+ scope="prototype">
+ <property name="repositoryFactory" ref="repositoryFactory" />
+ <property name="nodeRepository" ref="nodeRepository" />
+ <property name="keyring" ref="keyring" />
+ </bean>
+ <bean id="unregisterRemoteRepo"
+ class="org.argeo.slc.client.ui.dist.commands.UnregisterRemoteRepo"
+ scope="prototype">
+ <property name="nodeRepository" ref="nodeRepository" />
+ </bean>
+
<bean id="copyWorkspace" class="org.argeo.slc.client.ui.dist.commands.CopyWorkspace"
scope="prototype">
<property name="repository" ref="javaRepository" />
<!-- Commands -->
<extension
point="org.eclipse.ui.commands">
+ <!-- Command which do not need dependency injection -->
+ <command
+ defaultHandler="org.argeo.slc.client.ui.dist.commands.RefreshArtifactBrowser"
+ id="org.argeo.slc.client.ui.dist.refreshArtifactBrowser"
+ name="Refresh Artifact Browser">
+ </command>
<command
defaultHandler="org.argeo.slc.client.ui.dist.commands.ShowSizeColumn"
id="org.argeo.slc.client.ui.dist.showSizeColumn"
</class>
</state>
</command>
+
+ <!-- Command with Spring dependency injection -->
<command
- defaultHandler="org.argeo.slc.client.ui.dist.commands.RefreshArtifactBrowser"
- id="org.argeo.slc.client.ui.dist.refreshArtifactBrowser"
- name="Refresh Artifact Browser">
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ id="org.argeo.slc.client.ui.dist.unregisterRemoteRepo"
+ name="Unregister remote repository">
+ <commandParameter
+ id="org.argeo.slc.client.ui.dist.repoNodePath"
+ name="Remote Repo path">
+ </commandParameter>
</command>
+
<command
id="org.argeo.slc.client.ui.dist.runInOSGi"
defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
name="Add Repository">
</command>
+
+ <command
+ id="org.argeo.slc.client.ui.dist.repoSyncCommand"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Fetch repository">
+ <commandParameter
+ id="targetRepoPath"
+ name="Target repo path">
+ </commandParameter>
+ </command>
<!-- TO MANIPULATE WORKSPACES -->
<command
label="Add repository"
tooltip="Add a repository">
</command>
- <!--
+ <command
+ commandId="org.argeo.slc.client.ui.dist.refreshDistributionsView"
+ icon="icons/refresh.png"
+ label="Refresh"
+ tooltip="Refresh distributions view">
+ </command>
+ <!--
<command
commandId="org.argeo.slc.client.ui.dist.runInOSGi"
icon="icons/showSize.gif"
.getImageDescriptor("icons/artifactVersionBase.gif").createImage();
public final static Image IMG_FILE = DistPlugin.getImageDescriptor(
"icons/file.gif").createImage();
+
+ /** Icons to handle check boxes */
+ public final static Image CHECKED = DistPlugin.getImageDescriptor(
+ "icons/checked.gif").createImage();
+ public final static Image UNCHECKED = DistPlugin.getImageDescriptor(
+ "icons/unchecked.gif").createImage();
}
--- /dev/null
+package org.argeo.slc.client.ui.dist;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.jobs.Job;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
+
+/**
+ * Propagate authentication to an eclipse job. Typically to execute a privileged
+ * action outside the UI thread
+ */
+public abstract class PrivilegedJob extends Job {
+
+ private final Authentication authentication;
+ private Subject subject;
+
+ public PrivilegedJob(String jobName) {
+ super(jobName);
+ authentication = SecurityContextHolder.getContext().getAuthentication();
+ subject = Subject.getSubject(AccessController.getContext());
+ }
+
+ @Override
+ protected IStatus run(final IProgressMonitor progressMonitor) {
+ PrivilegedAction<IStatus> privilegedAction = new PrivilegedAction<IStatus>() {
+ public IStatus run() {
+ SecurityContextHolder.getContext().setAuthentication(
+ authentication);
+ return doRun(progressMonitor);
+ }
+ };
+ return Subject.doAs(subject, privilegedAction);
+ }
+
+ /** Implement here what should be executed with default context authentication*/
+ protected abstract IStatus doRun(IProgressMonitor progressMonitor);
+}
\ No newline at end of file
import org.argeo.jcr.ArgeoTypes;
import org.argeo.jcr.JcrUtils;
import org.argeo.jcr.UserJcrUtils;
+import org.argeo.slc.client.ui.dist.DistPlugin;
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.repo.RepoConstants;
import org.argeo.util.security.Keyring;
public class AddRepository extends AbstractHandler implements ArgeoNames,
SlcNames {
+ public final static String ID = DistPlugin.ID + ".addRepository";
+ public final static String DEFAULT_LABEL = "Register a repository";
+ public final static String DEFAULT_ICON_PATH = "icons/addItem.gif";
+
private RepositoryFactory repositoryFactory;
private Repository nodeRepository;
private Keyring keyring;
import javax.jcr.Session;
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.JcrUtils;
+import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistPlugin;
import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
import org.eclipse.core.commands.AbstractHandler;
*/
public class DeleteWorkspace extends AbstractHandler {
- private static final Log log = LogFactory.getLog(DeleteWorkspace.class);
+ // private static final Log log = LogFactory.getLog(DeleteWorkspace.class);
public final static String ID = DistPlugin.ID + ".deleteWorkspace";
public final static String PARAM_WORKSPACE_NAME = DistPlugin.ID
public Object execute(ExecutionEvent event) throws ExecutionException {
- // MessageDialog.openWarning(DistPlugin.getDefault()
- // .getWorkbench().getDisplay().getActiveShell(),
- // "WARNING", "Not yet implemented");
- // return null;
-
String workspaceName = event.getParameter(PARAM_WORKSPACE_NAME);
- String msg = "Your are about to clear workspace [" + workspaceName
- + "].\n Do you really want to proceed ?";
+
+ String msg = "Your are about to completely delete workspace ["
+ + workspaceName + "].\n Do you really want to proceed ?";
boolean result = MessageDialog.openConfirm(DistPlugin.getDefault()
.getWorkbench().getDisplay().getActiveShell(),
- "Confirm workspace clear", msg);
+ "Confirm workspace deletion", msg);
+
+ if (result) {
+ // msg =
+ // "There is no possible turning back, are your REALLY sure you want to proceed ?";
+ msg = "WARNING: \nCurrent Jackrabbit version used does "
+ + "not support workspace management.\n"
+ + "Thus, the workspace will only be cleaned so "
+ + "that you can launch fetch process again.\n\n"
+ + "Do you still want to proceed ?";
+ result = MessageDialog.openConfirm(DistPlugin.getDefault()
+ .getWorkbench().getDisplay().getActiveShell(),
+ "Confirm workspace deletion", msg);
+ }
+
if (result) {
Session session = null;
try {
session = repository.login(workspaceName);
+ // TODO use this with a newer version of Jackrabbit
+ // Workspace wsp = session.getWorkspace();
+ // wsp.deleteWorkspace(workspaceName);
+
NodeIterator nit = session.getRootNode().getNodes();
while (nit.hasNext()) {
Node node = nit.nextNode();
if (node.isNodeType(NodeType.NT_FOLDER)
|| node.isNodeType(NodeType.NT_UNSTRUCTURED)) {
- String path = node.getPath();
+ // String path = node.getPath();
node.remove();
session.save();
- if (log.isDebugEnabled())
- log.debug("Cleared " + path + " in "
- + workspaceName);
}
}
CommandHelpers.callCommand(RefreshDistributionsView.ID);
} catch (RepositoryException re) {
- throw new ArgeoException(
+ throw new SlcException(
"Unexpected error while deleting workspace ["
+ workspaceName + "].", re);
} finally {
- if (session != null)
- session.logout();
+ JcrUtils.logoutQuietly(session);
}
}
return null;
package org.argeo.slc.client.ui.dist.commands;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistPlugin;
+import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
+import org.argeo.slc.client.ui.dist.wizards.FetchWizard;
import org.argeo.slc.repo.RepoSync;
+import org.argeo.util.security.Keyring;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.ui.handlers.HandlerUtil;
/** Wraps a {@link RepoSync} as an Eclipse command. */
public class RepoSyncCommand extends AbstractHandler {
- public final static String ID = DistPlugin.ID + ".repoSync";
- public final static String PARAM_SOURCE_REPO = "sourceRepo";
- public final static String PARAM_TARGET_REPO = "targetRepo";
- public final static String DEFAULT_LABEL = "Repo sync";
+ // private final static Log log = LogFactory.getLog(RepoSyncCommand.class);
+
+ public final static String ID = DistPlugin.ID + ".repoSyncCommand";
+ public final static String PARAM_TARGET_REPO = "targetRepoPath";
+ public final static String DEFAULT_LABEL = "Fetch ...";
public final static String DEFAULT_ICON_PATH = "icons/addItem.gif";
-
+
+ // DEPENDENCY INJECTION
+ private Keyring keyring;
private RepositoryFactory repositoryFactory;
+ private Repository nodeRepository;
+
+ private Session currSession;
public Object execute(ExecutionEvent event) throws ExecutionException {
- RepoSync repoSync = new RepoSync();
- repoSync.setRepositoryFactory(repositoryFactory);
- repoSync.setSourceRepo(event.getParameter(PARAM_SOURCE_REPO));
- repoSync.setTargetRepo(event.getParameter(PARAM_TARGET_REPO));
- repoSync.run();
- return null;
+ try {
+ currSession = nodeRepository.login();
+ // Target Repository
+ String targetRepoPath = event.getParameter(PARAM_TARGET_REPO);
+ Node targetRepoNode = currSession.getNode(targetRepoPath);
+
+ FetchWizard wizard = new FetchWizard(keyring, repositoryFactory,
+ nodeRepository);
+ wizard.setTargetRepoNode(targetRepoNode);
+
+ WizardDialog dialog = new WizardDialog(
+ HandlerUtil.getActiveShell(event), wizard);
+ dialog.open();
+ CommandHelpers.callCommand(RefreshDistributionsView.ID);
+ return null;
+ } catch (RepositoryException e) {
+ throw new SlcException("Unexpected error while fetching data", e);
+ } finally {
+ JcrUtils.logoutQuietly(currSession);
+ }
}
+ // DEPENDENCY INJECTION
public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
this.repositoryFactory = repositoryFactory;
}
-}
+ public void setKeyring(Keyring keyring) {
+ this.keyring = keyring;
+ }
+
+ public void setNodeRepository(Repository repository) {
+ this.nodeRepository = repository;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.client.ui.dist.commands;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.ui.dist.DistPlugin;
+import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Unregisters a remote repository by deleting the corresponding RepoNode from
+ * the NodeRepository. It does not affect the repository instance
+ */
+
+public class UnregisterRemoteRepo extends AbstractHandler {
+ // private static final Log log = LogFactory
+ // .getLog(UnregisterRemoteRepo.class);
+ public final static String ID = DistPlugin.ID + ".unregisterRemoteRepo";
+ public final static String DEFAULT_LABEL = "Unregister repository";
+ public final static String DEFAULT_ICON_PATH = "icons/removeItem.gif";
+ public final static String PARAM_REPO_PATH = DistPlugin.ID
+ + ".repoNodePath";
+
+ // DEPENCY INJECTION
+ private Repository nodeRepository;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ Session session = null;
+ String repoPath = event.getParameter(PARAM_REPO_PATH);
+ if (repoPath == null)
+ return null;
+
+ try {
+ session = nodeRepository.login();
+ Node rNode = session.getNode(repoPath);
+ if (rNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
+
+ String alias = rNode.getProperty(Property.JCR_TITLE)
+ .getString();
+ String msg = "Your are about to unregister remote repository: "
+ + alias + "\n" + "Are you sure you want to proceed ?";
+
+ boolean result = MessageDialog.openConfirm(DistPlugin
+ .getDefault().getWorkbench().getDisplay()
+ .getActiveShell(), "Confirm Delete", msg);
+
+ if (result) {
+ rNode.remove();
+ session.save();
+ }
+ CommandHelpers.callCommand(RefreshDistributionsView.ID);
+ }
+
+ // } catch (Exception e) {
+ } catch (RepositoryException e) {
+ throw new SlcException(
+ "Unexpected error while deleting artifacts.", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ return null;
+ }
+
+ // DEPENCY INJECTION
+ public void setNodeRepository(Repository nodeRepository) {
+ this.nodeRepository = nodeRepository;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.client.ui.dist.utils;
+
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TreeColumn;
+
+/**
+ * Centralizes useful methods to manage table to display nodes list.
+ */
+public class ViewerUtils {
+
+ /**
+ * Creates a basic column for the given table. For the time being, we do not
+ * support moveable columns.
+ */
+ public static TableColumn createColumn(Table parent, String name,
+ int style, int width) {
+ TableColumn result = new TableColumn(parent, style);
+ result.setText(name);
+ result.setWidth(width);
+ result.setResizable(true);
+ return result;
+ }
+
+ /**
+ * Creates a TableViewerColumn for the given viewer. For the time being, we
+ * do not support moveable columns.
+ */
+ public static TableViewerColumn createTableViewerColumn(TableViewer parent,
+ String name, int style, int width) {
+ TableViewerColumn tvc = new TableViewerColumn(parent, style);
+ final TableColumn column = tvc.getColumn();
+ column.setText(name);
+ column.setWidth(width);
+ column.setResizable(true);
+ return tvc;
+ }
+
+ /**
+ * Creates a TreeViewerColumn for the given viewer. For the time being, we
+ * do not support moveable columns.
+ */
+ public static TreeViewerColumn createTreeViewerColumn(TreeViewer parent,
+ String name, int style, int width) {
+ TreeViewerColumn tvc = new TreeViewerColumn(parent, style);
+ final TreeColumn column = tvc.getColumn();
+ column.setText(name);
+ column.setWidth(width);
+ column.setResizable(true);
+ return tvc;
+ }
+}
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.commands.AddRepository;
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.commands.ManageWorkspaceAuth;
import org.argeo.slc.client.ui.dist.commands.NormalizeDistribution;
+import org.argeo.slc.client.ui.dist.commands.RepoSyncCommand;
+import org.argeo.slc.client.ui.dist.commands.UnregisterRemoteRepo;
import org.argeo.slc.client.ui.dist.editors.DistributionEditor;
import org.argeo.slc.client.ui.dist.editors.DistributionEditorInput;
import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
viewer.setContentProvider(new DistributionsContentProvider());
viewer.addDoubleClickListener(new DistributionsDCL());
+ // Enable selection retrieving from outside the view
+ getSite().setSelectionProvider(viewer);
// Drag'n drop
Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
}
viewer.setInput(nodeRepository);
-
}
/** Programatically configure the context menu */
protected void contextMenuAboutToShow(IMenuManager menuManager) {
IWorkbenchWindow window = DistPlugin.getDefault().getWorkbench()
.getActiveWorkbenchWindow();
- // Get Current selected item :
- Object firstElement = ((IStructuredSelection) viewer.getSelection())
- .getFirstElement();
+ try {
+ // Most of the implemented commands support only one selected
+ // element
+ boolean singleElement = ((IStructuredSelection) viewer
+ .getSelection()).size() == 1;
+ // Get Current selected item :
+ Object firstElement = ((IStructuredSelection) viewer.getSelection())
+ .getFirstElement();
- if (firstElement instanceof TreeParent
- || firstElement instanceof RepoElem) {
- String wsName = null;
+ if (firstElement instanceof TreeParent
+ || firstElement instanceof RepoElem) {
+ String wsName = null;
+ String targetRepoPath = null;
- // Build conditions depending on element type (repo or distribution
- // for the time being)
- boolean isDistribElem = false; // , isRepoElem = false;
+ // Build conditions depending on element type (repo or
+ // distribution
+ // for the time being)
+ boolean isDistribElem = false; // , isRepoElem = false;
- if (firstElement instanceof DistributionElem) {
- isDistribElem = true;
- wsName = ((DistributionElem) firstElement).getName();
- }
+ if (firstElement instanceof DistributionElem) {
+ isDistribElem = true;
+ wsName = ((DistributionElem) firstElement).getName();
+ }
- // create workspace
- CommandHelpers.refreshCommand(menuManager, window,
- CreateWorkspace.ID, CreateWorkspace.DEFAULT_LABEL,
- CreateWorkspace.DEFAULT_ICON_PATH, !isDistribElem);
-
- // Normalize workspace
- Map<String, String> params = new HashMap<String, String>();
- params.put(NormalizeDistribution.PARAM_WORKSPACE, wsName);
- CommandHelpers.refreshParameterizedCommand(menuManager, window,
- NormalizeDistribution.ID,
- NormalizeDistribution.DEFAULT_LABEL,
- NormalizeDistribution.DEFAULT_ICON_PATH, isDistribElem,
- params);
-
- // Copy workspace
- params = new HashMap<String, String>();
- params.put(CopyWorkspace.PARAM_WORKSPACE_NAME, wsName);
- CommandHelpers.refreshParameterizedCommand(menuManager, window,
- CopyWorkspace.ID, CopyWorkspace.DEFAULT_LABEL,
- CopyWorkspace.DEFAULT_ICON_PATH, isDistribElem, params);
-
- // Delete Workspace
- params = new HashMap<String, String>();
- params.put(DeleteWorkspace.PARAM_WORKSPACE_NAME, wsName);
- CommandHelpers.refreshParameterizedCommand(menuManager, window,
- DeleteWorkspace.ID, DeleteWorkspace.DEFAULT_LABEL,
- DeleteWorkspace.DEFAULT_ICON_PATH, isDistribElem, params);
-
- // Manage workspace authorizations
- params = new HashMap<String, String>();
- params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName);
- CommandHelpers.refreshParameterizedCommand(menuManager, window,
- ManageWorkspaceAuth.ID, ManageWorkspaceAuth.DEFAULT_LABEL,
- ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem,
- params);
+ if (firstElement instanceof RepoElem) {
+ Node node = ((RepoElem) firstElement).getRepoNode();
+ targetRepoPath = node.getPath();
+ }
+
+ // create workspace
+ CommandHelpers.refreshCommand(menuManager, window,
+ CreateWorkspace.ID, CreateWorkspace.DEFAULT_LABEL,
+ CreateWorkspace.DEFAULT_ICON_PATH, !isDistribElem
+ && singleElement);
+
+ // Register a remote repository
+ CommandHelpers.refreshCommand(menuManager, window,
+ AddRepository.ID, AddRepository.DEFAULT_LABEL,
+ AddRepository.DEFAULT_ICON_PATH, !isDistribElem
+ && singleElement);
+
+ // Unregister a remote repository
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(UnregisterRemoteRepo.PARAM_REPO_PATH, targetRepoPath);
+ CommandHelpers.refreshParameterizedCommand(menuManager, window,
+ UnregisterRemoteRepo.ID,
+ UnregisterRemoteRepo.DEFAULT_LABEL,
+ UnregisterRemoteRepo.DEFAULT_ICON_PATH, !isDistribElem
+ && singleElement, params);
+
+ // Fetch repository
+ params = new HashMap<String, String>();
+ params.put(RepoSyncCommand.PARAM_TARGET_REPO, targetRepoPath);
+ CommandHelpers.refreshParameterizedCommand(menuManager, window,
+ RepoSyncCommand.ID, RepoSyncCommand.DEFAULT_LABEL,
+ RepoSyncCommand.DEFAULT_ICON_PATH, !isDistribElem
+ && singleElement, params);
+
+ // Normalize workspace
+ params = new HashMap<String, String>();
+ params.put(NormalizeDistribution.PARAM_WORKSPACE, wsName);
+ CommandHelpers.refreshParameterizedCommand(menuManager, window,
+ NormalizeDistribution.ID,
+ NormalizeDistribution.DEFAULT_LABEL,
+ NormalizeDistribution.DEFAULT_ICON_PATH, isDistribElem
+ && singleElement, params);
+
+ // Copy workspace
+ params = new HashMap<String, String>();
+ params.put(CopyWorkspace.PARAM_WORKSPACE_NAME, wsName);
+ CommandHelpers.refreshParameterizedCommand(menuManager, window,
+ CopyWorkspace.ID, CopyWorkspace.DEFAULT_LABEL,
+ CopyWorkspace.DEFAULT_ICON_PATH, isDistribElem
+ && singleElement, params);
+
+ // Delete Workspace
+ params = new HashMap<String, String>();
+ params.put(DeleteWorkspace.PARAM_WORKSPACE_NAME, wsName);
+ CommandHelpers.refreshParameterizedCommand(menuManager, window,
+ DeleteWorkspace.ID, DeleteWorkspace.DEFAULT_LABEL,
+ DeleteWorkspace.DEFAULT_ICON_PATH, isDistribElem
+ && singleElement, params);
+
+ // Manage workspace authorizations
+ params = new HashMap<String, String>();
+ params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName);
+ CommandHelpers.refreshParameterizedCommand(menuManager, window,
+ ManageWorkspaceAuth.ID,
+ ManageWorkspaceAuth.DEFAULT_LABEL,
+ ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem
+ && singleElement, params);
+ }
+ } catch (RepositoryException e) {
+ throw new SlcException("unexpected errror while "
+ + "building context menu", e);
}
}
viewer.getTree().setFocus();
}
- /*
- * DEPENDENCY INJECTION
- */
/**
* Force refresh of the whole view
*/
viewer.setContentProvider(new DistributionsContentProvider());
}
- public void setNodeRepository(Repository repository) {
- this.nodeRepository = repository;
- }
-
- public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
- this.repositoryFactory = repositoryFactory;
- }
-
- public void setKeyring(Keyring keyring) {
- this.keyring = keyring;
- }
-
/*
* INTERNAL CLASSES
*/
}
}
}
+
+ /*
+ * DEPENDENCY INJECTION
+ */
+ public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+ this.repositoryFactory = repositoryFactory;
+ }
+
+ public void setKeyring(Keyring keyring) {
+ this.keyring = keyring;
+ }
+
+ public void setNodeRepository(Repository repository) {
+ this.nodeRepository = repository;
+ }
}
\ No newline at end of file
*/
package org.argeo.slc.client.ui.dist.wizards;
-import java.util.regex.Pattern;
-
import javax.jcr.security.Privilege;
import org.eclipse.jface.wizard.WizardPage;
private Combo authorizationCmb;
// Define acceptable chars for the technical name
- private static Pattern p = Pattern.compile("^[A-Za-z0-9]+$");
+ // private static Pattern p = Pattern.compile("^[A-Za-z0-9]+$");
// USABLE SHORTCUTS
protected final static String[] validAuthType = { Privilege.JCR_READ,
public ChooseRightsPage() {
super("Main");
- setTitle("Manange authorizations on the current workspace");
+ setTitle("Manage authorizations on the current workspace");
}
public void createControl(Composite parent) {
return authorizationCmb.getItem(authorizationCmb.getSelectionIndex());
}
- private static boolean match(String s) {
- return p.matcher(s).matches();
- }
+ // private static boolean match(String s) {
+ // return p.matcher(s).matches();
+ // }
public void modifyText(ModifyEvent event) {
String message = checkComplete();
--- /dev/null
+/*
+ * 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.client.ui.dist.wizards;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoMonitor;
+import org.argeo.eclipse.ui.EclipseArgeoMonitor;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.ui.dist.DistImages;
+import org.argeo.slc.client.ui.dist.DistPlugin;
+import org.argeo.slc.client.ui.dist.PrivilegedJob;
+import org.argeo.slc.client.ui.dist.utils.ViewerUtils;
+import org.argeo.slc.repo.RepoConstants;
+import org.argeo.slc.repo.RepoSync;
+import org.argeo.slc.repo.RepoUtils;
+import org.argeo.util.security.Keyring;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.CheckboxCellEditor;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Defines parameters for the fetch process and run it using a {@link RepoSync}
+ * object.
+ */
+public class FetchWizard extends Wizard {
+
+ // Business objects
+ private Keyring keyring;
+ private RepositoryFactory repositoryFactory;
+ private Session currSession;
+
+ // Caches the workspace list
+ private List<String> wkspToSync = new ArrayList<String>();
+
+ private TableViewer wkspViewer;
+
+ private Node targetRepoNode, sourceRepoNode;
+
+ // This page widget
+ private DefineModelPage page;
+
+ public FetchWizard(Keyring keyring, RepositoryFactory repositoryFactory,
+ Repository nodeRepository) {
+ super();
+ this.keyring = keyring;
+ this.repositoryFactory = repositoryFactory;
+ try {
+ currSession = nodeRepository.login();
+ } catch (RepositoryException e) {
+ throw new SlcException(
+ "Unexpected error while initializing fetch wizard", e);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ JcrUtils.logoutQuietly(currSession);
+ }
+
+ @Override
+ public void addPages() {
+ try {
+ page = new DefineModelPage();
+ addPage(page);
+ setWindowTitle("Fetch ...");
+ } catch (Exception e) {
+ throw new SlcException("Cannot add page to wizard ", e);
+ }
+ }
+
+ @Override
+ public boolean performFinish() {
+ if (!canFinish())
+ return false;
+ try {
+ // Target Repository
+ String targetRepoUri = targetRepoNode.getProperty(
+ ArgeoNames.ARGEO_URI).getString();
+ Repository targetRepo = RepoUtils.getRepository(repositoryFactory,
+ keyring, targetRepoNode);
+ Credentials targetCredentials = RepoUtils.getRepositoryCredentials(
+ keyring, targetRepoNode);
+
+ // Source Repository
+ String sourceRepoUri = sourceRepoNode.getProperty(
+ ArgeoNames.ARGEO_URI).getString();
+ Repository sourceRepo = RepoUtils.getRepository(repositoryFactory,
+ keyring, sourceRepoNode);
+ Credentials sourceCredentials = RepoUtils.getRepositoryCredentials(
+ keyring, sourceRepoNode);
+
+ String msg = "Your are about to fetch data from repository: \n\t"
+ + sourceRepoUri + "\ninto target repository: \n\t"
+ + targetRepoUri + "\nDo you really want to proceed ?";
+
+ boolean result = MessageDialog.openConfirm(DistPlugin.getDefault()
+ .getWorkbench().getDisplay().getActiveShell(),
+ "Confirm Fetch clear", msg);
+
+ if (result) {
+ RepoSync repoSync = new RepoSync(sourceRepo, sourceCredentials,
+ targetRepo, targetCredentials);
+ repoSync.setTargetRepoUri(targetRepoUri);
+ repoSync.setSourceRepoUri(sourceRepoUri);
+
+ // / Specify workspaces to synchronise
+ if (wkspToSync != null && wkspToSync.size() > 0)
+ repoSync.setSourceWkspList(wkspToSync);
+
+ FetchJob job = new FetchJob(repoSync);
+ job.setUser(true);
+ job.schedule();
+ }
+
+ } catch (Exception e) {
+ throw new SlcException(
+ "Unexpected error while launching the fetch", e);
+ }
+ return true;
+ }
+
+ private class DefineModelPage extends WizardPage {
+
+ // This page widget
+ private Combo chooseSourceRepoCmb;
+
+ // Business objects
+ private Map<String, Node> sourceReposMap;
+
+ public DefineModelPage() {
+ super("Main");
+ setTitle("Define fetch parameters");
+ }
+
+ public void createControl(Composite parent) {
+
+ // main layout
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+
+ // Choose source repo
+ new Label(composite, SWT.NONE)
+ .setText("Choose a source repository");
+ chooseSourceRepoCmb = new Combo(composite, SWT.BORDER
+ | SWT.V_SCROLL);
+ chooseSourceRepoCmb.setItems(getSourceRepoUris());
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ chooseSourceRepoCmb.setLayoutData(gd);
+
+ // Workspace table
+ Composite wkspTable = new Composite(composite, SWT.NONE);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ gd.grabExcessVerticalSpace = true;
+ gd.verticalAlignment = SWT.FILL;
+ wkspTable.setLayoutData(gd);
+ wkspTable.setLayout(new GridLayout(1, false));
+ addFilesTablePart(wkspTable);
+
+ chooseSourceRepoCmb.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ String chosenUri = chooseSourceRepoCmb
+ .getItem(chooseSourceRepoCmb.getSelectionIndex());
+ sourceRepoNode = sourceReposMap.get(chosenUri);
+ wkspViewer.setInput(sourceRepoNode);
+ }
+ });
+
+ // initialize to first avalaible repo
+ chooseSourceRepoCmb.select(0);
+
+ // Compulsory
+ setControl(composite);
+ }
+
+ // Helper to populate avalaible source repo list
+ protected String[] getSourceRepoUris() {
+ try {
+ Node repoList = currSession.getNode(UserJcrUtils.getUserHome(
+ currSession).getPath()
+ + RepoConstants.REPOSITORIES_BASE_PATH);
+
+ String targetRepoUri = null;
+ if (targetRepoNode != null) {
+ targetRepoUri = targetRepoNode.getProperty(
+ ArgeoNames.ARGEO_URI).getString();
+ }
+ NodeIterator ni = repoList.getNodes();
+ List<String> sourceRepoNames = new ArrayList<String>();
+ // caches a map of the source repo nodes with their URI as a key
+ // to ease further processing
+ sourceReposMap = new HashMap<String, Node>();
+ while (ni.hasNext()) {
+ Node currNode = ni.nextNode();
+ if (currNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
+ String currUri = currNode.getProperty(
+ ArgeoNames.ARGEO_URI).getString();
+ if (targetRepoUri == null
+ || !targetRepoUri.equals(currUri)) {
+ sourceReposMap.put(currUri, currNode);
+ sourceRepoNames.add(currUri);
+ }
+ }
+ }
+ return sourceRepoNames.toArray(new String[sourceRepoNames
+ .size()]);
+ } catch (RepositoryException e) {
+ throw new SlcException("Error while getting repo aliases", e);
+ }
+ }
+
+ // Create the workspaces table
+ private void addFilesTablePart(Composite parent) {
+
+ final Table table = new Table(parent, SWT.NONE | SWT.H_SCROLL
+ | SWT.V_SCROLL | SWT.BORDER);
+ table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+ wkspViewer = new TableViewer(table);
+
+ // CHECKBOX COLUMN
+ TableViewerColumn column = ViewerUtils.createTableViewerColumn(
+ wkspViewer, "", SWT.NONE, 20);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return null;
+ }
+
+ public Image getImage(Object element) {
+ return wkspToSync.contains(element) ? DistImages.CHECKED
+ : DistImages.UNCHECKED;
+ }
+ });
+ column.setEditingSupport(new CheckboxEditingSupport(wkspViewer));
+ // add select all option
+ column.getColumn().addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ if (wkspToSync.size() > 0)
+ wkspToSync = new ArrayList<String>();
+ else {
+ String[] elements = (String[]) ((IStructuredContentProvider) wkspViewer
+ .getContentProvider()).getElements(null);
+ wkspToSync = Arrays.asList(elements);
+ }
+ wkspViewer.refresh();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+
+ // WORKSPACES COLUMN
+ column = ViewerUtils.createTableViewerColumn(wkspViewer,
+ "Workspaces", SWT.NONE, 400);
+ column.setLabelProvider(new ColumnLabelProvider());
+
+ wkspViewer.setContentProvider(new IStructuredContentProvider() {
+ // caches current repo
+ private Repository currSourceRepo;
+ private Credentials currSourceCred;
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ // update current used repository
+ currSourceRepo = RepoUtils.getRepository(repositoryFactory,
+ keyring, (Node) newInput);
+ currSourceCred = RepoUtils.getRepositoryCredentials(
+ keyring, (Node) newInput);
+ // reset workspace list
+ wkspToSync = new ArrayList<String>();
+ }
+
+ public void dispose() {
+ }
+
+ public Object[] getElements(Object obj) {
+ Session session = null;
+ try {
+ session = currSourceRepo.login(currSourceCred);
+ return session.getWorkspace()
+ .getAccessibleWorkspaceNames();
+ } catch (RepositoryException e) {
+ throw new SlcException(
+ "Unexpected error while initializing fetch wizard",
+ e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+
+ }
+ });
+ }
+
+ /** Select which file to import by editing a checkbox */
+ protected class CheckboxEditingSupport extends EditingSupport {
+
+ private final TableViewer viewer;
+
+ public CheckboxEditingSupport(TableViewer viewer) {
+ super(viewer);
+ this.viewer = viewer;
+ }
+
+ @Override
+ protected boolean canEdit(Object element) {
+ return true;
+ }
+
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ return new CheckboxCellEditor(null, SWT.CHECK | SWT.READ_ONLY);
+ }
+
+ @Override
+ protected Object getValue(Object element) {
+ return wkspToSync.contains(element);
+ }
+
+ @Override
+ protected void setValue(Object element, Object value) {
+ if ((Boolean) value && !wkspToSync.contains(element))
+ wkspToSync.add((String) element);
+ else if (!(Boolean) value && wkspToSync.contains(element))
+ wkspToSync.remove(element);
+ viewer.refresh();
+ }
+ }
+ }
+
+ /**
+ * Define the privileged job that will be run asynchronously to accomplish
+ * the sync
+ */
+ private class FetchJob extends PrivilegedJob {
+ private RepoSync repoSync;
+
+ public FetchJob(RepoSync repoSync) {
+ super("Fetch");
+ this.repoSync = repoSync;
+ }
+
+ @Override
+ protected IStatus doRun(IProgressMonitor progressMonitor) {
+ try {
+ ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor);
+ repoSync.setMonitor(monitor);
+ repoSync.run();
+ } catch (Exception e) {
+ return new Status(IStatus.ERROR, DistPlugin.ID,
+ "Cannot fetch repository", e);
+ }
+ return Status.OK_STATUS;
+ }
+ }
+
+ public void setTargetRepoNode(Node targetRepoNode) {
+ this.targetRepoNode = targetRepoNode;
+ }
+
+ public void setSourceRepoNode(Node sourceRepoNode) {
+ this.sourceRepoNode = sourceRepoNode;
+ }
+
+ // private class FetchJob extends Job {
+ // private RepoSync repoSync;
+ // private final Authentication authentication;
+ // private Subject subject;
+ //
+ // public FetchJob(RepoSync repoSync) {
+ // super("Fetch");
+ // this.repoSync = repoSync;
+ // authentication = SecurityContextHolder.getContext()
+ // .getAuthentication();
+ // subject = Subject.getSubject(AccessController.getContext());
+ // }
+ //
+ // @Override
+ // protected IStatus run(final IProgressMonitor progressMonitor) {
+ // PrivilegedAction<IStatus> privilegedAction = new
+ // PrivilegedAction<IStatus>() {
+ // public IStatus run() {
+ // try {
+ // // SecurityContextHolder.setContext(securityContext);
+ // SecurityContextHolder.getContext().setAuthentication(
+ // authentication);
+ // ArgeoMonitor monitor = new EclipseArgeoMonitor(
+ // progressMonitor);
+ // repoSync.setMonitor(monitor);
+ // repoSync.run();
+ // } catch (Exception e) {
+ // return new Status(IStatus.ERROR, DistPlugin.ID,
+ // "Cannot fetch repository", e);
+ // }
+ // return Status.OK_STATUS;
+ // }
+ //
+ // };
+ // return Subject.doAs(subject, privilegedAction);
+ // }
+ // }
+}
\ No newline at end of file
*/
package org.argeo.slc.repo;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.nodetype.NodeType;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
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.JcrUtils;
import org.argeo.slc.SlcException;
public class RepoSync implements Runnable {
private final static Log log = LogFactory.getLog(RepoSync.class);
- private final Calendar zero;
+ // Centralizes definition of workspaces that must be ignored by the sync.
+ private final static List<String> IGNORED_WSKP_LIST = Arrays.asList(
+ "security", "localrepo");
- private String sourceRepo;
- private String targetRepo;
+ private final Calendar zero;
+ private Session sourceDefaultSession = null;
+ private Session targetDefaultSession = null;
- private String sourceWksp;
+ private Repository sourceRepository;
+ private Credentials sourceCredentials;
+ private Repository targetRepository;
+ private Credentials targetCredentials;
+ // if Repository and Credentials objects are not explicitly set
+ private String sourceRepoUri;
private String sourceUsername;
private char[] sourcePassword;
+ private String targetRepoUri;
private String targetUsername;
private char[] targetPassword;
private RepositoryFactory repositoryFactory;
+ private ArgeoMonitor monitor;
+ private List<String> sourceWkspList;
+
public RepoSync() {
zero = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
zero.setTimeInMillis(0);
}
+ /**
+ *
+ * Shortcut to instantiate a RepoSync with already known repositories and
+ * credentials.
+ *
+ * @param sourceRepository
+ * @param sourceCredentials
+ * @param targetRepository
+ * @param targetCredentials
+ */
+ public RepoSync(Repository sourceRepository, Credentials sourceCredentials,
+ Repository targetRepository, Credentials targetCredentials) {
+ this();
+ this.sourceRepository = sourceRepository;
+ this.sourceCredentials = sourceCredentials;
+ this.targetRepository = targetRepository;
+ this.targetCredentials = targetCredentials;
+ }
+
public void run() {
- Session sourceDefaultSession = null;
- Session targetDefaultSession = null;
try {
long begin = System.currentTimeMillis();
- Repository sourceRepository = ArgeoJcrUtils.getRepositoryByUri(
- repositoryFactory, sourceRepo);
- Repository targetRepository = ArgeoJcrUtils.getRepositoryByUri(
- repositoryFactory, targetRepo);
- Credentials sourceCredentials = null;
- if (sourceUsername != null)
+ // Setup
+ if (sourceRepository == null)
+ sourceRepository = ArgeoJcrUtils.getRepositoryByUri(
+ repositoryFactory, sourceRepoUri);
+ if (sourceCredentials == null && sourceUsername != null)
sourceCredentials = new SimpleCredentials(sourceUsername,
sourcePassword);
- Credentials targetCredentials = null;
- if (targetUsername != null)
+ sourceDefaultSession = sourceRepository.login(sourceCredentials);
+
+ if (targetRepository == null)
+ targetRepository = ArgeoJcrUtils.getRepositoryByUri(
+ repositoryFactory, targetRepoUri);
+ if (targetCredentials == null && targetUsername != null)
targetCredentials = new SimpleCredentials(targetUsername,
targetPassword);
+ targetDefaultSession = targetRepository.login(targetCredentials);
+
+ // Compute job size
+ if (monitor != null) {
+ Long totalAmount = 0l;
+ if (sourceWkspList != null) {
+ for (String wkspName : sourceWkspList) {
+ totalAmount += getNodesNumber(wkspName);
+ }
+ } else
+ for (String sourceWorkspaceName : sourceDefaultSession
+ .getWorkspace().getAccessibleWorkspaceNames()) {
+ totalAmount += getNodesNumber(sourceWorkspaceName);
+ }
+ monitor.beginTask("Fetch", totalAmount.intValue());
+ if (log.isDebugEnabled())
+ log.debug("Nb of nodes to sync: " + totalAmount.intValue());
+ }
Map<String, Exception> errors = new HashMap<String, Exception>();
- sourceDefaultSession = sourceRepository.login(sourceCredentials);
- targetDefaultSession = targetRepository.login(targetCredentials);
for (String sourceWorkspaceName : sourceDefaultSession
.getWorkspace().getAccessibleWorkspaceNames()) {
- if (sourceWksp != null && !sourceWksp.trim().equals("")
- && !sourceWorkspaceName.equals(sourceWksp))
- continue;
- if (sourceWorkspaceName.equals("security"))
+
+ if (sourceWkspList != null
+ && !sourceWkspList.contains(sourceWorkspaceName))
continue;
- if (sourceWorkspaceName.equals("localrepo"))
+ if (IGNORED_WSKP_LIST.contains(sourceWorkspaceName))
continue;
+
Session sourceSession = null;
Session targetSession = null;
try {
} catch (Exception e) {
errors.put("Could not sync workspace "
+ sourceWorkspaceName, e);
+ if (log.isDebugEnabled())
+ e.printStackTrace();
} finally {
JcrUtils.logoutQuietly(sourceSession);
JcrUtils.logoutQuietly(targetSession);
}
}
- // 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);
+
+ if (monitor != null && monitor.isCanceled())
+ log.info("Sync has been canceled by user");
long duration = (System.currentTimeMillis() - begin) / 1000;// s
- log.info("Sync " + sourceRepo + " to " + targetRepo + " in "
+ log.info("Sync " + sourceRepoUri + " to " + targetRepoUri + " in "
+ (duration / 60)
+ "min " + (duration % 60) + "s");
throw new SlcException("Sync failed " + errors);
}
} catch (RepositoryException e) {
- throw new SlcException("Cannot sync " + sourceRepo + " to "
- + targetRepo, e);
+ throw new SlcException("Cannot sync " + sourceRepoUri + " to "
+ + targetRepoUri, e);
} finally {
JcrUtils.logoutQuietly(sourceDefaultSession);
JcrUtils.logoutQuietly(targetDefaultSession);
}
}
+ private long getNodesNumber(String wkspName) {
+ if (IGNORED_WSKP_LIST.contains(wkspName))
+ return 0l;
+ Session sourceSession = null;
+ try {
+ sourceSession = sourceRepository.login(sourceCredentials, wkspName);
+ Query countQuery = sourceDefaultSession
+ .getWorkspace()
+ .getQueryManager()
+ .createQuery("select file from [nt:base] as file",
+ Query.JCR_SQL2);
+ QueryResult result = countQuery.execute();
+ Long expectedCount = result.getNodes().getSize();
+ return expectedCount;
+ } catch (RepositoryException e) {
+ throw new SlcException("Unexpected error while computing "
+ + "the size of the fetch for workspace " + wkspName, e);
+ } finally {
+ JcrUtils.logoutQuietly(sourceSession);
+ }
+ }
+
protected void syncWorkspace(Session sourceSession, Session targetSession) {
try {
+ String msg = "Synchronizing workspace: "
+ + sourceSession.getWorkspace().getName();
+ if (monitor != null)
+ monitor.setTaskName(msg);
if (log.isDebugEnabled())
- log.debug("Syncing " + sourceSession.getWorkspace().getName()
- + "...");
+ log.debug(msg);
for (NodeIterator it = sourceSession.getRootNode().getNodes(); it
.hasNext();) {
Node node = it.nextNode();
if (node.getName().equals("jcr:system"))
continue;
- // ContentHandler targetHandler = targetSession
- // .getWorkspace()
- // .getImportContentHandler(
- // "/",
- // ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
- // sourceSession.exportSystemView(node.getPath(), targetHandler,
- // true, false);
- // if (log.isDebugEnabled())
- // log.debug(" " + node.getPath());
syncNode(node, targetSession.getRootNode());
}
if (log.isDebugEnabled())
}
}
+ /** factorizes monitor management */
+ private void updateMonitor(String msg) {
+ if (monitor != null) {
+ monitor.worked(1);
+ monitor.subTask(msg);
+ }
+ }
+
protected void syncNode(Node sourceNode, Node targetParentNode)
throws RepositoryException, SAXException {
+
+ // enable cancelation of the current fetch process
+ // FIXME insure the repository stays in a stable state
+ if (monitor != null && monitor.isCanceled()) {
+ updateMonitor("Fetched has been canceled, "
+ + "process is terminating");
+ return;
+ }
+
Boolean noRecurse = noRecurse(sourceNode);
Calendar sourceLastModified = null;
if (sourceNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
}
if (!targetParentNode.hasNode(sourceNode.getName())) {
+ String msg = "Adding " + sourceNode.getPath();
+ updateMonitor(msg);
+ if (log.isDebugEnabled())
+ log.debug(msg);
ContentHandler contentHandler = targetParentNode
.getSession()
.getWorkspace()
ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
sourceNode.getSession().exportSystemView(sourceNode.getPath(),
contentHandler, false, noRecurse);
- if (log.isDebugEnabled())
- log.debug("Added " + sourceNode.getPath());
} else {
Node targetNode = targetParentNode.getNode(sourceNode.getName());
if (sourceLastModified != null) {
if (targetLastModified == null
|| targetLastModified.before(sourceLastModified)) {
+ String msg = "Updating " + targetNode.getPath();
+ updateMonitor(msg);
+ if (log.isDebugEnabled())
+ log.debug(msg);
ContentHandler contentHandler = targetParentNode
.getSession()
.getWorkspace()
sourceNode.getSession().exportSystemView(
sourceNode.getPath(), contentHandler, false,
noRecurse);
- if (log.isDebugEnabled())
- log.debug("Updated " + targetNode.getPath());
} else {
+ String msg = "Skipped up to date " + targetNode.getPath();
+ updateMonitor(msg);
if (log.isDebugEnabled())
- log.debug("Skipped up to date " + targetNode.getPath());
- // if (!noRecurse)
+ log.debug(msg);
return;
}
}
targetNode.getSession().save();
}
}
-
}
protected Boolean noRecurse(Node sourceNode) throws RepositoryException {
return true;
}
- public void setSourceRepo(String sourceRepo) {
- this.sourceRepo = sourceRepo;
+ /** synchronise only one workspace retrieved by name */
+ public void setSourceWksp(String sourceWksp) {
+ if (sourceWksp != null && !sourceWksp.trim().equals("")) {
+ List<String> list = new ArrayList<String>();
+ list.add(sourceWksp);
+ setSourceWkspList(list);
+ }
}
- public void setTargetRepo(String targetRepo) {
- this.targetRepo = targetRepo;
+ /** synchronise a list workspace that will be retrieved by name */
+ public void setSourceWkspList(List<String> sourceWkspList) {
+ // clean the list to ease later use
+ this.sourceWkspList = null;
+ if (sourceWkspList != null) {
+ for (String wkspName : sourceWkspList) {
+ if (!wkspName.trim().equals("")) {
+ // only instantiate if needed
+ if (this.sourceWkspList == null)
+ this.sourceWkspList = new ArrayList<String>();
+ this.sourceWkspList.add(wkspName);
+ }
+ }
+ }
}
- public void setSourceWksp(String sourceWksp) {
- this.sourceWksp = sourceWksp;
+ public void setMonitor(ArgeoMonitor monitor) {
+ this.monitor = monitor;
}
public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
this.repositoryFactory = repositoryFactory;
}
+ public void setSourceRepoUri(String sourceRepoUri) {
+ this.sourceRepoUri = sourceRepoUri;
+ }
+
public void setSourceUsername(String sourceUsername) {
this.sourceUsername = sourceUsername;
}
this.sourcePassword = sourcePassword;
}
+ public void setTargetRepoUri(String targetRepoUri) {
+ this.targetRepoUri = targetRepoUri;
+ }
+
public void setTargetUsername(String targetUsername) {
this.targetUsername = targetUsername;
}
this.targetPassword = targetPassword;
}
-}
+ public void setSourceRepository(Repository sourceRepository) {
+ this.sourceRepository = sourceRepository;
+ }
+
+ public void setSourceCredentials(Credentials sourceCredentials) {
+ this.sourceCredentials = sourceCredentials;
+ }
+
+ public void setTargetRepository(Repository targetRepository) {
+ this.targetRepository = targetRepository;
+ }
+
+ public void setTargetCredentials(Credentials targetCredentials) {
+ this.targetCredentials = targetCredentials;
+ }
+}
\ No newline at end of file