javax.jcr.nodetype;version="2.0.0",
javax.jcr.query,
javax.jcr.query.qom;version="2.0.0",
+ javax.jcr.security,
org.apache.commons.io;version="1.4.0",
org.apache.commons.logging;version="1.1.1",
org.argeo,
<property name="repository" ref="javaRepository" />
<property name="workspace" value="argeo-tp-1-staging" />
</bean>
+ <bean id="createWorkspace"
+ class="org.argeo.slc.client.ui.dist.commands.CreateWorkspace"
+ scope="prototype">
+ <property name="repository" ref="javaRepository" />
+ </bean>
+ <bean id="copyWorkspace"
+ class="org.argeo.slc.client.ui.dist.commands.CopyWorkspace"
+ scope="prototype">
+ <property name="repository" ref="javaRepository" />
+ </bean>
+ <bean id="deleteWorkspace"
+ class="org.argeo.slc.client.ui.dist.commands.DeleteWorkspace"
+ scope="prototype">
+ <property name="repository" ref="javaRepository" />
+ </bean>
+ <bean id="manageWorkspaceAuth"
+ class="org.argeo.slc.client.ui.dist.commands.ManageWorkspaceAuth"
+ scope="prototype">
+ <property name="repository" ref="javaRepository" />
+ </bean>
+ <bean id="refreshDistributionsView"
+ class="org.argeo.slc.client.ui.dist.commands.RefreshDistributionsView"
+ scope="prototype">
+ </bean>
</beans>
id="org.argeo.slc.client.ui.dist.normalizeDistribution"
defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
name="Normalize Distribution">
+ </command>
+
+ <!-- TO MANIPULATE WORKSPACES -->
+ <command
+ id="org.argeo.slc.client.ui.dist.createWorkspace"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Create Workspace">
+ </command>
+ <command
+ id="org.argeo.slc.client.ui.dist.deleteWorkspace"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Delete chosen Workspace">
+ <commandParameter
+ id="org.argeo.slc.client.ui.dist.workspaceName"
+ name="Workspace Name">
+ </commandParameter>
+ </command>
+ <command
+ id="org.argeo.slc.client.ui.dist.copyWorkspace"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Copy chosen Workspace">
+ <commandParameter
+ id="org.argeo.slc.client.ui.dist.workspaceName"
+ name="Workspace Name">
+ </commandParameter>
+ </command>
+ <command
+ id="org.argeo.slc.client.ui.dist.manageWorkspaceAuth"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Manage workspace authorizations">
+ <commandParameter
+ id="org.argeo.slc.client.ui.dist.workspaceName"
+ name="Workspace Name">
+ </commandParameter>
+ </command>
+ <command
+ id="org.argeo.slc.client.ui.dist.refreshDistributionsView"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Refresh Distributions View">
</command>
</extension>
<extension
--- /dev/null
+package org.argeo.slc.client.ui.dist.commands;
+
+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.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.client.ui.dist.DistPlugin;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Create a copy of the chosen workspace in the current repository.
+ */
+
+public class CopyWorkspace extends AbstractHandler {
+ private static final Log log = LogFactory.getLog(CopyWorkspace.class);
+ public final static String ID = DistPlugin.ID + ".copyWorkspace";
+ public final static String PARAM_WORKSPACE_NAME = DistPlugin.ID
+ + ".workspaceName";
+ public final static String DEFAULT_LABEL = "Copy this workspace";
+ public final static String DEFAULT_ICON_PATH = "icons/addItem.gif";
+
+ /* DEPENDENCY INJECTION */
+ private Repository repository;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ String srcWorkspaceName = event.getParameter(PARAM_WORKSPACE_NAME);
+
+ if (log.isTraceEnabled())
+ log.debug("WORKSPACE " + srcWorkspaceName + " About to be copied");
+
+ MessageDialog.openWarning(DistPlugin.getDefault()
+ .getWorkbench().getDisplay().getActiveShell(),
+ "WARNING", "Not yet implemented");
+ return null;
+ //
+ //
+ // IWorkbenchWindow iww = DistPlugin.getDefault().getWorkbench()
+ // .getActiveWorkbenchWindow();
+ // InputDialog inputDialog = new InputDialog(iww.getShell(),
+ // "New copy of the current workspace",
+ // "Choose a name for the workspace to create", "", null);
+ // inputDialog.open();
+ // String newWorkspaceName = inputDialog.getValue();
+ // Session srcSession = null;
+ // Session newSession = null;
+ // try {
+ // srcSession = repository.login(srcWorkspaceName);
+ // // FIXME: simple call to Workspace.create(newName, oldName) does not
+ // // work
+ //
+ // srcSession.getWorkspace().createWorkspace(newWorkspaceName,
+ // srcWorkspaceName);
+ //
+ // // // Create the workspace
+ // // srcSession.getWorkspace().createWorkspace(newWorkspaceName);
+ // // Node srcRootNode = srcSession.getRootNode();
+ // // // log in the newly created workspace
+ // // newSession = repository.login(newWorkspaceName);
+ // // newSession.save();
+ // // Node newRootNode = newSession.getRootNode();
+ // // copy(srcRootNode, newRootNode);
+ // // newSession.save();
+ //
+ // CommandHelpers.callCommand(RefreshDistributionsView.ID);
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Unexpected error while creating the new workspace.", re);
+ // } finally {
+ // if (srcSession != null)
+ // srcSession.logout();
+ // if (newSession != null)
+ // newSession.logout();
+ // }
+ // return null;
+ }
+
+ // FIXME : commons is frozen, cannot fix the problem directly there.
+ // test and report corresponding patch
+ private void copy(Node fromNode, Node toNode) {
+
+ try {
+ // cannot manipulate security nodes this way:
+ if (fromNode.isNodeType("rep:ACL"))
+ return;
+ // process properties
+ PropertyIterator pit = fromNode.getProperties();
+ properties: while (pit.hasNext()) {
+ Property fromProperty = pit.nextProperty();
+ 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());
+ }
+ }
+
+ // update jcr:lastModified and jcr:lastModifiedBy in toNode in case
+ // they existed, before adding the mixins
+ if (!toNode.getDefinition().isProtected())
+ JcrUtils.updateLastModified(toNode);
+
+ // add mixins
+ for (NodeType mixinType : fromNode.getMixinNodeTypes()) {
+ toNode.addMixin(mixinType.getName());
+ }
+
+ // 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);
+ }
+
+ toNode.getSession().save();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot copy " + fromNode + " to "
+ + toNode, e);
+ }
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+}
--- /dev/null
+package org.argeo.slc.client.ui.dist.commands;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+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.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.InputDialog;
+import org.eclipse.ui.IWorkbenchWindow;
+
+/**
+ * Create a new empty workspace in the current repository.
+ */
+
+public class CreateWorkspace extends AbstractHandler {
+ private static final Log log = LogFactory.getLog(CreateWorkspace.class);
+ public final static String ID = DistPlugin.ID + ".createWorkspace";
+ public final static String DEFAULT_LABEL = "Create new workspace";
+ public final static String DEFAULT_ICON_PATH = "icons/addItem.gif";
+
+ /* DEPENDENCY INJECTION */
+ private Repository repository;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IWorkbenchWindow iww = DistPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow();
+ // TODO : add an input validator
+ InputDialog inputDialog = new InputDialog(iww.getShell(),
+ "New workspace", "Choose a name for the workspace to create",
+ "", null);
+ inputDialog.open();
+ String workspaceName = inputDialog.getValue();
+ try {
+ Session session = repository.login();
+ session.getWorkspace().createWorkspace(workspaceName);
+ CommandHelpers.callCommand(RefreshDistributionsView.ID);
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while creating the new workspace.", re);
+ }
+ if (log.isTraceEnabled())
+ log.debug("WORKSPACE " + workspaceName + " CREATED");
+ return null;
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+}
--- /dev/null
+package org.argeo.slc.client.ui.dist.commands;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+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;
+
+/**
+ * Delete chosen workspace in the current repository.
+ */
+
+public class DeleteWorkspace extends AbstractHandler {
+ // 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
+ + ".workspaceName";
+ public final static String DEFAULT_LABEL = "Delete current workspace";
+ public final static String DEFAULT_ICON_PATH = "icons/removeItem.gif";
+
+ /* DEPENDENCY INJECTION */
+ private Repository repository;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ String workspaceName = event.getParameter(PARAM_WORKSPACE_NAME);
+ String msg = "Your are about to definitively delete this workspace ["
+ + workspaceName + "].\n Do you really want to proceed ?";
+
+ MessageDialog.openWarning(DistPlugin.getDefault()
+ .getWorkbench().getDisplay().getActiveShell(),
+ "WARNING", "Not yet implemented");
+ return null;
+
+// boolean result = MessageDialog.openConfirm(DistPlugin.getDefault()
+// .getWorkbench().getDisplay().getActiveShell(),
+// "Confirm deletion", msg);
+// if (result) {
+// Session session = null;
+// try {
+// session = repository.login();
+// session.getWorkspace().deleteWorkspace(workspaceName);
+// CommandHelpers.callCommand(RefreshDistributionsView.ID);
+// } catch (RepositoryException re) {
+// throw new ArgeoException(
+// "Unexpected error while deleting workspace ["
+// + workspaceName + "].", re);
+// } finally {
+// if (session != null)
+// session.logout();
+// }
+// }
+// return null;
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+}
--- /dev/null
+package org.argeo.slc.client.ui.dist.commands;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.Privilege;
+
+import org.argeo.ArgeoException;
+import org.argeo.slc.client.ui.dist.DistPlugin;
+import org.argeo.slc.client.ui.dist.wizards.ChangeRightsWizard;
+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;
+
+/**
+ * Open a dialog to change rights on the root node of the current workspace.
+ */
+
+public class ManageWorkspaceAuth extends AbstractHandler {
+ // private static final Log log =
+ // LogFactory.getLog(ManageWorkspaceAuth.class);
+ public final static String ID = DistPlugin.ID + ".manageWorkspaceAuth";
+ public final static String PARAM_WORKSPACE_NAME = DistPlugin.ID
+ + ".workspaceName";
+ public final static String DEFAULT_LABEL = "Change rights for current workspace";
+ public final static String DEFAULT_ICON_PATH = "icons/changeRights.gif";
+
+ /* DEPENDENCY INJECTION */
+ private Repository repository;
+
+ private Session session;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ String workspaceName = event.getParameter(PARAM_WORKSPACE_NAME);
+ try {
+ session = repository.login(workspaceName);
+ ChangeRightsWizard wizard = new ChangeRightsWizard(session);
+ WizardDialog dialog = new WizardDialog(
+ HandlerUtil.getActiveShell(event), wizard);
+ dialog.open();
+ return null;
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while creating the new workspace.", re);
+ } finally {
+ if (session != null)
+ session.logout();
+ }
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+}
--- /dev/null
+package org.argeo.slc.client.ui.dist.commands;
+
+import org.argeo.slc.client.ui.dist.DistPlugin;
+import org.argeo.slc.client.ui.dist.views.DistributionsView;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * Force refresh of the DistributionsView
+ */
+
+public class RefreshDistributionsView extends AbstractHandler {
+ // private static final Log log = LogFactory
+ // .getLog(RefreshDistributionsView.class);
+ public final static String ID = DistPlugin.ID + ".refreshDistributionsView";
+ public final static String DEFAULT_LABEL = "Refresh the distribution view";
+ public final static String DEFAULT_ICON_PATH = "icons/refresh.png";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IWorkbenchPart activePart = DistPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage().getActivePart();
+ if (activePart instanceof DistributionsView)
+ ((DistributionsView) activePart).refresh();
+ return null;
+ }
+}
*/
package org.argeo.slc.client.ui.dist.editors;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.qom.Ordering;
-import javax.jcr.query.qom.QueryObjectModel;
-import javax.jcr.query.qom.QueryObjectModelFactory;
-import javax.jcr.query.qom.Selector;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.jcr.JcrUtils;
import org.argeo.slc.client.ui.dist.DistPlugin;
import org.argeo.slc.jcr.SlcNames;
-import org.argeo.slc.jcr.SlcTypes;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-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.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.osgi.framework.Constants;
/**
* Editor to browse, analyze and modify an OSGi distribution
*/
public class DistributionEditor extends FormEditor implements SlcNames {
- private final static Log log = LogFactory.getLog(DistributionEditor.class);
+ // private final static Log log =
+ // LogFactory.getLog(DistributionEditor.class);
public final static String ID = DistPlugin.ID + ".distributionEditor";
private Session session;
package org.argeo.slc.client.ui.dist.editors;
+import java.util.ArrayList;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.QueryManager;
import org.argeo.eclipse.ui.ErrorFeedback;
import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.client.ui.dist.utils.NodeViewerComparator;
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.jcr.SlcTypes;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Table;
private TableViewer viewer;
private Session session;
+ private NodeViewerComparator comparator;
+
public DistributionOverviewPage(FormEditor formEditor, String title,
Session session) {
super(formEditor, "distributionPage", title);
GridLayout layout = new GridLayout(1, false);
form.getBody().setLayout(layout);
+ // helpers to enable sorting by column
+ List<String> propertiesList = new ArrayList<String>();
+ List<Integer> propertyTypesList = new ArrayList<Integer>();
+
// Define the TableViewer
viewer = new TableViewer(form.getBody(), SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
return JcrUtils.get((Node) element, SLC_SYMBOLIC_NAME);
}
});
+ col.getColumn().addSelectionListener(getSelectionAdapter(0));
+ propertiesList.add(SLC_SYMBOLIC_NAME);
+ propertyTypesList.add(PropertyType.STRING);
+
col = new TableViewerColumn(viewer, SWT.NONE);
col.getColumn().setWidth(100);
col.getColumn().setText("Version");
return JcrUtils.get((Node) element, SLC_BUNDLE_VERSION);
}
});
+ col.getColumn().addSelectionListener(getSelectionAdapter(1));
+ propertiesList.add(SLC_BUNDLE_VERSION);
+ propertyTypesList.add(PropertyType.STRING);
+
col = new TableViewerColumn(viewer, SWT.NONE);
col.getColumn().setWidth(150);
col.getColumn().setText("Group ID");
return JcrUtils.get((Node) element, SLC_GROUP_ID);
}
});
+ col.getColumn().addSelectionListener(getSelectionAdapter(2));
+ propertiesList.add(SLC_GROUP_ID);
+ propertyTypesList.add(PropertyType.STRING);
+
col = new TableViewerColumn(viewer, SWT.NONE);
col.getColumn().setWidth(300);
col.getColumn().setText("Name");
+ Constants.BUNDLE_NAME);
}
});
+ col.getColumn().addSelectionListener(getSelectionAdapter(3));
+ propertiesList.add(SLC_ + Constants.BUNDLE_NAME);
+ propertyTypesList.add(PropertyType.STRING);
final Table table = viewer.getTable();
table.setHeaderVisible(true);
viewer.setContentProvider(new DistributionsContentProvider());
viewer.setInput(session);
+ comparator = new NodeViewerComparator(1,
+ NodeViewerComparator.DESCENDING, propertiesList,
+ propertyTypesList);
+ viewer.setComparator(comparator);
}
@Override
return result.getNodes();
}
+ private SelectionAdapter getSelectionAdapter(final int index) {
+ SelectionAdapter selectionAdapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Table table = viewer.getTable();
+ comparator.setColumn(index);
+ int dir = table.getSortDirection();
+ if (table.getSortColumn() == table.getColumn(index)) {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ } else {
+ dir = SWT.DOWN;
+ }
+ table.setSortDirection(dir);
+ table.setSortColumn(table.getColumn(index));
+ viewer.refresh();
+ }
+ };
+ return selectionAdapter;
+ }
+
private static class DistributionsContentProvider implements
IStructuredContentProvider {
private Session session;
--- /dev/null
+package org.argeo.slc.client.ui.dist.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.argeo.ArgeoException;
+import org.argeo.slc.client.ui.dist.DistPlugin;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.Parameterization;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.menus.CommandContributionItem;
+import org.eclipse.ui.menus.CommandContributionItemParameter;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * Centralizes useful methods to manage command updates
+ */
+public class CommandHelpers {
+
+ /**
+ * Refresh the given command.
+ */
+ public static void refreshCommand(IMenuManager menuManager,
+ IServiceLocator locator, String cmdId, String label, String iconPath,
+ boolean showCommand) {
+ IContributionItem ici = menuManager.find(cmdId);
+ if (ici != null)
+ menuManager.remove(ici);
+
+ if (showCommand) {
+ // Set Params
+ CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter(
+ locator, null, cmdId, SWT.PUSH);
+ contributionItemParameter.label = label;
+ contributionItemParameter.icon = DistPlugin.getImageDescriptor(iconPath);
+ CommandContributionItem cci = new CommandContributionItem(
+ contributionItemParameter);
+ cci.setId(cmdId);
+ menuManager.add(cci);
+ }
+ }
+
+ /**
+ * Refresh the given command and optionally corresponding parameters.
+ *
+ * @param menuManager
+ * @param locator
+ * @param cmdId
+ * @param label
+ * @param showCommand
+ * Command must be explicitly removed from the context menu at
+ * each refresh setting this to false.
+ * @param params
+ * maps a paramId with a String value
+ */
+ public static void refreshParameterizedCommand(IMenuManager menuManager,
+ IServiceLocator locator, String cmdId, String label, String iconPath,
+ boolean showCommand, Map<String, String> params) {
+ IContributionItem ici = menuManager.find(cmdId);
+ if (ici != null)
+ menuManager.remove(ici);
+
+ if (showCommand) {
+ // Set Params
+ CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter(
+ locator, null, cmdId, SWT.PUSH);
+ contributionItemParameter.label = label;
+ contributionItemParameter.icon = DistPlugin.getImageDescriptor(iconPath);
+
+ if (params != null)
+ contributionItemParameter.parameters = params;
+
+ CommandContributionItem cci = new CommandContributionItem(
+ contributionItemParameter);
+ cci.setId(cmdId);
+ menuManager.add(cci);
+ }
+ }
+
+ /** Helper to call a command without parameter easily */
+ public static void callCommand(String commandID) {
+ callCommand(commandID, null);
+ }
+
+ /** Helper to call a command with a single parameter easily */
+ public static void callCommand(String commandID, String parameterID,
+ String parameterValue) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(parameterID, parameterValue);
+ callCommand(commandID, params);
+ }
+
+ /**
+ * Helper to call a command with a map of parameters easily
+ *
+ * @param paramMap
+ * a map that links various commands ids with corresponding
+ * String values.
+ */
+ public static void callCommand(String commandID,
+ Map<String, String> paramMap) {
+ try {
+ IWorkbench iw = DistPlugin.getDefault().getWorkbench();
+ IHandlerService handlerService = (IHandlerService) iw
+ .getService(IHandlerService.class);
+ ICommandService cmdService = (ICommandService) iw
+ .getActiveWorkbenchWindow().getService(
+ ICommandService.class);
+ Command cmd = cmdService.getCommand(commandID);
+
+ ArrayList<Parameterization> parameters = null;
+ ParameterizedCommand pc;
+
+ if (paramMap != null) {
+ // Set parameters of the command to launch :
+ parameters = new ArrayList<Parameterization>();
+ Parameterization parameterization;
+ for (String id : paramMap.keySet()) {
+ parameterization = new Parameterization(
+ cmd.getParameter(id), paramMap.get(id));
+ parameters.add(parameterization);
+ }
+ pc = new ParameterizedCommand(cmd,
+ parameters.toArray(new Parameterization[parameters.size()]));
+ } else
+ pc = new ParameterizedCommand(cmd, null);
+
+ // build the parameterized command
+ // execute the command
+ handlerService.executeCommand(pc, null);
+ } catch (Exception e) {
+ throw new ArgeoException(
+ "Unexepected exception while opening node editor", e);
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.slc.client.ui.dist.utils;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.GenericTableComparator;
+import org.eclipse.jface.viewers.Viewer;
+
+public class NodeViewerComparator extends GenericTableComparator {
+ private final static Log log = LogFactory
+ .getLog(NodeViewerComparator.class);
+
+ protected List<String> propertiesList;
+ protected List<Integer> propertyTypesList;
+ protected Integer propertyType;
+ protected String property;
+
+ public NodeViewerComparator(int defaultColIndex, int defaultDirection,
+ List<String> propertiesList, List<Integer> propertyTypesList) {
+ super(defaultColIndex, defaultDirection);
+ this.propertiesList = propertiesList;
+ this.propertyTypesList = propertyTypesList;
+ this.propertyIndex = defaultColIndex;
+ this.propertyType = propertyTypesList.get(defaultColIndex);
+ this.property = propertiesList.get(defaultColIndex);
+ setColumn(defaultColIndex);
+ }
+
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ int rc = 0;
+ long lc = 0;
+
+ try {
+ Node n1 = (Node) e1;
+ Node n2 = (Node) e2;
+
+ Value v1 = null;
+ Value v2 = null;
+ if (n1.hasProperty(property))
+ v1 = n1.getProperty(property).getValue();
+ if (n2.hasProperty(property))
+ v2 = n2.getProperty(property).getValue();
+
+ if (v2 == null && v1 == null)
+ return 0;
+ else if (v2 == null)
+ return -1;
+ else if (v1 == null)
+ return 1;
+
+ switch (propertyType) {
+ case PropertyType.STRING:
+ rc = v1.getString().compareTo(v2.getString());
+ break;
+ case PropertyType.BOOLEAN:
+ boolean b1 = v1.getBoolean();
+ boolean b2 = v2.getBoolean();
+ if (b1 == b2)
+ rc = 0;
+ else
+ // we assume true is greater than false
+ rc = b1 ? 1 : -1;
+ break;
+ case PropertyType.DATE:
+ Calendar c1 = v1.getDate();
+ Calendar c2 = v2.getDate();
+ if (c1 == null || c2 == null)
+ log.trace("undefined date");
+ lc = c1.getTimeInMillis() - c2.getTimeInMillis();
+ if (lc < Integer.MIN_VALUE)
+ // rc = Integer.MIN_VALUE;
+ rc = -1;
+ else if (lc > Integer.MAX_VALUE)
+ // rc = Integer.MAX_VALUE;
+ rc = 1;
+ else
+ rc = (int) lc;
+ break;
+ case PropertyType.LONG:
+ long l1;
+ long l2;
+ // FIXME sometimes an empty string is set instead of the id
+ try {
+ l1 = v1.getLong();
+ } catch (ValueFormatException ve) {
+ l1 = 0;
+ }
+ try {
+ l2 = v2.getLong();
+ } catch (ValueFormatException ve) {
+ l2 = 0;
+ }
+
+ lc = l1 - l2;
+ if (lc < Integer.MIN_VALUE)
+ // rc = Integer.MIN_VALUE;
+ rc = -1;
+ else if (lc > Integer.MAX_VALUE)
+ // rc = Integer.MAX_VALUE;
+ rc = 1;
+ else
+ rc = (int) lc;
+ break;
+ case PropertyType.DECIMAL:
+ BigDecimal bd1 = v1.getDecimal();
+ BigDecimal bd2 = v2.getDecimal();
+ rc = bd1.compareTo(bd2);
+ break;
+ default:
+ throw new ArgeoException(
+ "Unimplemented comparaison for PropertyType "
+ + propertyType);
+ }
+
+ // If descending order, flip the direction
+ if (direction == DESCENDING) {
+ rc = -rc;
+ }
+
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unexpected error "
+ + "while comparing nodes", re);
+ }
+ return rc;
+ }
+
+ @Override
+ public void setColumn(int column) {
+ if (column == this.propertyIndex) {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ } else {
+ // New column; do a descending sort
+ this.propertyIndex = column;
+ this.propertyType = propertyTypesList.get(column);
+ this.property = propertiesList.get(column);
+ direction = ASCENDING;
+ }
+ }
+}
\ No newline at end of file
*/
package org.argeo.slc.client.ui.dist.views;
+import java.util.HashMap;
+import java.util.Map;
+
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.argeo.eclipse.ui.ErrorFeedback;
import org.argeo.eclipse.ui.TreeParent;
import org.argeo.slc.client.ui.dist.DistPlugin;
+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.editors.DistributionEditor;
import org.argeo.slc.client.ui.dist.editors.DistributionEditorInput;
+import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
import org.argeo.slc.jcr.SlcNames;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
viewer.setContentProvider(new DistributionsContentProvider());
viewer.addDoubleClickListener(new DistributionsDCL());
+
+ MenuManager menuManager = new MenuManager();
+ Menu menu = menuManager.createContextMenu(viewer.getTree());
+ menuManager.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ contextMenuAboutToShow(manager);
+ }
+ });
+ viewer.getTree().setMenu(menu);
+ getSite().registerContextMenu(menuManager, viewer);
+
viewer.setInput(getSite());
+
}
@Override
viewer.getTree().setFocus();
}
+ /**
+ * Force refresh of the whole view
+ */
+ public void refresh() {
+ viewer.setContentProvider(new DistributionsContentProvider());
+ }
+
public void setRepository(Repository repository) {
this.repository = repository;
}
+ /** 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();
+ String wsName = null;
+ if (firstElement instanceof TreeParent) {
+ wsName = ((TreeParent) firstElement).getName();
+ }
+
+ // Build conditions depending on element type (repo or workspace)
+
+ // create workspace
+ CommandHelpers.refreshCommand(menuManager, window, CreateWorkspace.ID,
+ CreateWorkspace.DEFAULT_LABEL,
+ CreateWorkspace.DEFAULT_ICON_PATH, true);
+
+ // Copy workspace
+ Map<String, String> 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, true, 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, true, 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, true, params);
+ }
+
private class DistributionsContentProvider extends
AbstractTreeContentProvider {
}
}
+
}
--- /dev/null
+package org.argeo.slc.client.ui.dist.wizards;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.eclipse.jface.wizard.Wizard;
+
+/**
+ * Small wizard to manage authorizations on the root node of the current
+ * workspace
+ */
+public class ChangeRightsWizard extends Wizard {
+
+ private Session currentSession;
+
+ // This page widget
+ private ChooseRightsPage page;
+
+ public ChangeRightsWizard(Session currentSession) {
+ super();
+ this.currentSession = currentSession;
+ }
+
+ @Override
+ public void addPages() {
+ try {
+ page = new ChooseRightsPage();
+ addPage(page);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot add page to wizard ", e);
+ }
+ }
+
+ @Override
+ public boolean performFinish() {
+ if (!canFinish())
+ return false;
+ try {
+ JcrUtils.addPrivilege(currentSession, "/", page.getGroupName(),
+ page.getAuthTypeStr());
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while setting privileges", re);
+ }
+ return true;
+ }
+}
--- /dev/null
+package org.argeo.slc.client.ui.dist.wizards;
+
+import java.util.regex.Pattern;
+
+import javax.jcr.security.Privilege;
+
+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.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.Text;
+
+public class ChooseRightsPage extends WizardPage implements ModifyListener {
+
+ // This page widget
+ private Text groupNameTxt;
+ private Combo authorizationCmb;
+
+ // Define acceptable chars for the technical name
+ private static Pattern p = Pattern.compile("^[A-Za-z0-9]+$");
+
+ // USABLE SHORTCUTS
+ protected final static String[] validAuthType = { Privilege.JCR_READ,
+ Privilege.JCR_WRITE, Privilege.JCR_ALL };
+
+ public ChooseRightsPage() {
+ super("Main");
+ setTitle("Manange authorizations on the current workspace");
+ }
+
+ public void createControl(Composite parent) {
+ // specify subject
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ Label lbl = new Label(composite, SWT.LEAD);
+ lbl.setText("Group or user name (no blank, no special chars)");
+ lbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
+ groupNameTxt = new Text(composite, SWT.LEAD | SWT.BORDER);
+ groupNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
+ false));
+ if (groupNameTxt != null)
+ groupNameTxt.addModifyListener(this);
+
+ // Choose rigths
+ new Label(composite, SWT.NONE).setText("Choose corresponding rights");
+ authorizationCmb = new Combo(composite, SWT.BORDER | SWT.V_SCROLL);
+ authorizationCmb.setItems(validAuthType);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ authorizationCmb.setLayoutData(gd);
+
+ authorizationCmb.select(0);
+
+ // Compulsory
+ setControl(composite);
+ }
+
+ protected String getGroupName() {
+ return groupNameTxt.getText();
+ }
+
+ protected String getAuthTypeStr() {
+ return authorizationCmb.getItem(authorizationCmb.getSelectionIndex());
+ }
+
+ private static boolean match(String s) {
+ return p.matcher(s).matches();
+ }
+
+ public void modifyText(ModifyEvent event) {
+ String message = checkComplete();
+ if (message != null)
+ setMessage(message, WizardPage.ERROR);
+ else {
+ setMessage("Complete", WizardPage.INFORMATION);
+ setPageComplete(true);
+ }
+ }
+
+ /** @return error message or null if complete */
+ protected String checkComplete() {
+ String groupStr = groupNameTxt.getText();
+ if (groupStr == null || "".equals(groupStr))
+ return "Please enter a short technical name for the new repository.";
+ else if (!match(groupStr))
+ return "Please use only alphanumerical chars for the short technical name.";
+
+ return null;
+ }
+}