<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="src" path="src/main/resources"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>>>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
+++ /dev/null
-#Thu Feb 24 08:49:06 CET 2011
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.5
-source.. = src/main/java/,\
- src/main/resources
-output.. = target/classes/
-bin.includes = META-INF/,\
- .,\
- plugin.xml,\
- plugin.properties
+source.. = src/
+++ /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.jcr.ui.explorer;
-
-/** Constants used across the application. */
-public interface JcrExplorerConstants {
- /*
- * MISCEALLENEOUS
- */
- public final static String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm";
-
- public final static String PARAM_PATH = "org.argeo.jcr.ui.explorer.nodePath";
-
-}
+++ /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.jcr.ui.explorer;
-
-import org.eclipse.ui.IFolderLayout;
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-/** Base perspective for JcrExplorer browser */
-public class JcrExplorerPerspective implements IPerspectiveFactory {
- public static String BROWSER_VIEW_ID = JcrExplorerPlugin.ID
- + ".browserView";
-
- public void createInitialLayout(IPageLayout layout) {
- layout.setEditorAreaVisible(true);
-
- IFolderLayout upperLeft = layout.createFolder(JcrExplorerPlugin.ID
- + ".upperLeft", IPageLayout.LEFT, 0.4f, layout.getEditorArea());
- upperLeft.addView(BROWSER_VIEW_ID);
-
-// String editorArea = layout.getEditorArea();
-// String logViewId = "org.argeo.security.ui.logView";
-// IFolderLayout bottom = layout.createFolder("bottom",
-// IPageLayout.BOTTOM, 0.50f, editorArea);
-// bottom.addView(logViewId);
- }
-
-}
+++ /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.jcr.ui.explorer;
-
-import java.util.ResourceBundle;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class JcrExplorerPlugin extends AbstractUIPlugin {
- private final static Log log = LogFactory.getLog(JcrExplorerPlugin.class);
- private ResourceBundle messages;
-
- // The plug-in ID
- public static final String ID = "org.argeo.jcr.ui.explorer"; //$NON-NLS-1$
-
- // The shared instance
- private static JcrExplorerPlugin plugin;
-
- /**
- * The constructor
- */
- public JcrExplorerPlugin() {
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
- * )
- */
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
- messages = ResourceBundle
- .getBundle("org.argeo.jcr.ui.explorer.messages");
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
- * )
- */
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- super.stop(context);
- }
-
- /**
- * Returns the shared instance
- *
- * @return the shared instance
- */
- public static JcrExplorerPlugin getDefault() {
- return plugin;
- }
-
- public static ImageDescriptor getImageDescriptor(String path) {
- return imageDescriptorFromPlugin(ID, path);
- }
-
- /** Returns the internationalized label for the given key */
- public static String getMessage(String key) {
- try {
- return getDefault().messages.getString(key);
- } catch (NullPointerException npe) {
- log.warn(key + " not found.");
- return key;
- }
- }
-
- /**
- * Gives access to the internationalization message bundle. Returns null in
- * case the ClientUiPlugin is not started (for JUnit tests, by instance)
- */
- public static ResourceBundle getMessagesBundle() {
- if (getDefault() != null)
- // To avoid NPE
- return getDefault().messages;
- else
- return null;
- }
-
-}
+++ /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.jcr.ui.explorer;
-
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-
-public class JcrExplorerView extends GenericJcrBrowser {
-
-}
+++ /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.jcr.ui.explorer.browser;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.RepositoryRegister;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.jcr.ui.explorer.model.RepositoriesElem;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.util.security.Keyring;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Implementation of the {@code ITreeContentProvider} to display multiple
- * repository environment in a tree like structure
- *
- */
-public class NodeContentProvider implements ITreeContentProvider {
- final private RepositoryRegister repositoryRegister;
- final private RepositoryFactory repositoryFactory;
- /**
- * A session of the logged in user on the default workspace of the node
- * repository.
- */
- final private Session userSession;
- final private Keyring keyring;
- private boolean sortChildren;
-
- // reference for cleaning
- private SingleJcrNodeElem homeNode = null;
- private RepositoriesElem repositoriesNode = null;
-
- // Utils
- private TreeBrowserComparator itemComparator = new TreeBrowserComparator();
-
- public NodeContentProvider(Session userSession, Keyring keyring,
- RepositoryRegister repositoryRegister,
- RepositoryFactory repositoryFactory, Boolean sortChildren) {
- this.userSession = userSession;
- this.keyring = keyring;
- this.repositoryRegister = repositoryRegister;
- this.repositoryFactory = repositoryFactory;
- this.sortChildren = sortChildren;
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- if (newInput == null)// dispose
- return;
-
- if (userSession != null) {
- Node userHome = UserJcrUtils.getUserHome(userSession);
- if (userHome != null) {
- // TODO : find a way to dynamically get alias for the node
- if (homeNode != null)
- homeNode.dispose();
- homeNode = new SingleJcrNodeElem(null, userHome,
- userSession.getUserID(), ArgeoJcrConstants.ALIAS_NODE);
- }
- }
- if (repositoryRegister != null) {
- if (repositoriesNode != null)
- repositoriesNode.dispose();
- repositoriesNode = new RepositoriesElem("Repositories",
- repositoryRegister, repositoryFactory, null, userSession,
- keyring);
- }
- }
-
- /**
- * Sends back the first level of the Tree. Independent from inputElement
- * that can be null
- */
- public Object[] getElements(Object inputElement) {
- List<Object> objs = new ArrayList<Object>();
- if (homeNode != null)
- objs.add(homeNode);
- if (repositoriesNode != null)
- objs.add(repositoriesNode);
- return objs.toArray();
- }
-
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof TreeParent) {
- if (sortChildren) {
- // TreeParent[] arr = (TreeParent[]) ((TreeParent)
- // parentElement)
- // .getChildren();
- Object[] tmpArr = ((TreeParent) parentElement).getChildren();
- TreeParent[] arr = new TreeParent[tmpArr.length];
- for (int i = 0; i < tmpArr.length; i++)
- arr[i] = (TreeParent) tmpArr[i];
-
- Arrays.sort(arr, itemComparator);
- return arr;
- } else
- return ((TreeParent) parentElement).getChildren();
-
- } else {
- return new Object[0];
- }
- }
-
- /**
- * Sets whether the content provider should order the children nodes or not.
- * It is user duty to call a full refresh of the tree after changing this
- * parameter.
- */
- public void setSortChildren(boolean sortChildren) {
- this.sortChildren = sortChildren;
- }
-
- public Object getParent(Object element) {
- if (element instanceof TreeParent) {
- return ((TreeParent) element).getParent();
- } else
- return null;
- }
-
- public boolean hasChildren(Object element) {
- if (element instanceof RepositoriesElem) {
- RepositoryRegister rr = ((RepositoriesElem) element)
- .getRepositoryRegister();
- return rr.getRepositories().size() > 0;
- } else if (element instanceof TreeParent) {
- TreeParent tp = (TreeParent) element;
- return tp.hasChildren();
- }
- return false;
- }
-
- public void dispose() {
- if (homeNode != null)
- homeNode.dispose();
- if (repositoriesNode != null) {
- // logs out open sessions
- // see https://bugzilla.argeo.org/show_bug.cgi?id=23
- repositoriesNode.dispose();
- }
- }
-
- /**
- * Specific comparator for this view. See spec in BUG :
- * https://www.argeo.org/bugzilla/show_bug.cgi?id=139
- */
- private class TreeBrowserComparator implements Comparator<TreeParent> {
-
- public int category(TreeParent element) {
- if (element instanceof SingleJcrNodeElem) {
- Node node = ((SingleJcrNodeElem) element).getNode();
- try {
- if (node.isNodeType(NodeType.NT_FOLDER))
- return 5;
- } catch (RepositoryException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- return 10;
- }
-
- public int compare(TreeParent o1, TreeParent o2) {
- int cat1 = category(o1);
- int cat2 = category(o2);
-
- if (cat1 != cat2) {
- return cat1 - cat2;
- }
- return o1.getName().compareTo(o2.getName());
- }
- }
-}
\ 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.jcr.ui.explorer.browser;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.jcr.DefaultNodeLabelProvider;
-import org.argeo.eclipse.ui.jcr.JcrImages;
-import org.argeo.jcr.ui.explorer.model.RemoteRepositoryElem;
-import org.argeo.jcr.ui.explorer.model.RepositoriesElem;
-import org.argeo.jcr.ui.explorer.model.RepositoryElem;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.eclipse.swt.graphics.Image;
-
-public class NodeLabelProvider extends DefaultNodeLabelProvider {
- // Images
-
- public String getText(Object element) {
- try {
- if (element instanceof SingleJcrNodeElem) {
- SingleJcrNodeElem sjn = (SingleJcrNodeElem) element;
- return getText(sjn.getNode());
- } else
- return super.getText(element);
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected JCR error while getting node name.");
- }
- }
-
- protected String getText(Node node) throws RepositoryException {
- String label = node.getName();
- StringBuffer mixins = new StringBuffer("");
- for (NodeType type : node.getMixinNodeTypes())
- mixins.append(' ').append(type.getName());
-
- return label + " [" + node.getPrimaryNodeType().getName() + mixins
- + "]";
- }
-
- @Override
- public Image getImage(Object element) {
- if (element instanceof RemoteRepositoryElem) {
- if (((RemoteRepositoryElem) element).isConnected())
- return JcrImages.REMOTE_CONNECTED;
- else
- return JcrImages.REMOTE_DISCONNECTED;
- } else if (element instanceof RepositoryElem) {
- if (((RepositoryElem) element).isConnected())
- return JcrImages.REPOSITORY_CONNECTED;
- else
- return JcrImages.REPOSITORY_DISCONNECTED;
- } else if (element instanceof WorkspaceElem) {
- if (((WorkspaceElem) element).isConnected())
- return JcrImages.WORKSPACE_CONNECTED;
- else
- return JcrImages.WORKSPACE_DISCONNECTED;
- } else if (element instanceof RepositoriesElem) {
- return JcrImages.REPOSITORIES;
- } else if (element instanceof SingleJcrNodeElem)
- try {
- return super.getImage(((SingleJcrNodeElem) element).getNode());
- } catch (RepositoryException e) {
- return null;
- }
- return super.getImage(element);
- }
-
-}
+++ /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.jcr.ui.explorer.browser;
-
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-public class PropertiesContentProvider implements IStructuredContentProvider {
- private JcrItemsComparator itemComparator = new JcrItemsComparator();
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- public Object[] getElements(Object inputElement) {
- try {
- if (inputElement instanceof Node) {
- Set<Property> props = new TreeSet<Property>(itemComparator);
- PropertyIterator pit = ((Node) inputElement).getProperties();
- while (pit.hasNext())
- props.add(pit.nextProperty());
- return props.toArray();
- }
- return new Object[] {};
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot get element for " + inputElement,
- e);
- }
- }
-
-}
+++ /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.jcr.ui.explorer.commands;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.eclipse.ui.dialogs.SingleValue;
-import org.argeo.eclipse.ui.jcr.JcrUiPlugin;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * Adds a node of type nt:folder, only on {@link SingleJcrNodeElem} and
- * {@link WorkspaceElem} TreeObject types.
- *
- *
- * This handler assumes that a selection provider is available and picks only
- * first selected item. It is UI's job to enable the command only when the
- * selection contains one and only one element. Thus no parameter is passed
- * through the command.
- *
- * This handler is still 'hard linked' to a GenericJcrBrowser view to enable
- * correct tree refresh when a node is added. This must be corrected in future
- * versions.
- */
-public class AddFolderNode extends AbstractHandler {
-
- public final static String ID = JcrExplorerPlugin.ID + ".addFolderNode";
-
- // public final static String DEFAULT_LABEL = JcrExplorerPlugin
- // .getMessage("addFolderNodeCmdLbl");
- // public final static String DEFAULT_ICON_REL_PATH = "icons/addRepo.gif";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
-
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
-
- GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(HandlerUtil.getActivePartId(event));
-
- if (selection != null && !selection.isEmpty()
- && selection instanceof IStructuredSelection) {
- Object obj = ((IStructuredSelection) selection).getFirstElement();
- TreeParent treeParentNode = null;
- Node jcrParentNode = null;
-
- if (obj instanceof SingleJcrNodeElem) {
- treeParentNode = (TreeParent) obj;
- jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode();
- } else if (obj instanceof WorkspaceElem) {
- treeParentNode = (TreeParent) obj;
- jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode();
- } else
- return null;
-
- String folderName = SingleValue.ask("Folder name",
- "Enter folder name");
- if (folderName != null) {
- try {
- jcrParentNode.addNode(folderName, NodeType.NT_FOLDER);
- jcrParentNode.getSession().save();
- view.nodeAdded(treeParentNode);
- } catch (RepositoryException e) {
- ErrorFeedback.show("Cannot create folder " + folderName
- + " under " + treeParentNode, e);
- }
- }
- } else {
- ErrorFeedback.show(JcrUiPlugin
- .getMessage("errorUnvalidNtFolderNodeType"));
- }
- return null;
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.argeo.jcr.ui.explorer.wizards.ChangeRightsWizard;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * Open a dialog to change rights on the selected node.
- */
-
-public class AddPrivileges extends AbstractHandler {
- public final static String ID = JcrExplorerPlugin.ID + ".addPrivileges";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
-
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
- if (selection != null && !selection.isEmpty()
- && selection instanceof IStructuredSelection) {
- Object obj = ((IStructuredSelection) selection).getFirstElement();
- TreeParent treeParentNode = null;
- Node jcrParentNode = null;
-
- if (obj instanceof SingleJcrNodeElem) {
- treeParentNode = (TreeParent) obj;
- jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode();
- } else if (obj instanceof WorkspaceElem) {
- treeParentNode = (TreeParent) obj;
- jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode();
- } else
- return null;
-
- try {
- ChangeRightsWizard wizard = new ChangeRightsWizard(
- jcrParentNode.getSession(), jcrParentNode.getPath());
- 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);
- }
- } else {
- ErrorFeedback.show("Cannot add privileges");
- }
- return null;
- }
-}
\ 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.jcr.ui.explorer.commands;
-
-import java.net.URI;
-import java.util.Hashtable;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.utils.CommandUtils;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
-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.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Connect to a remote repository and, if successful publish it as an OSGi
- * service.
- */
-public class AddRemoteRepository extends AbstractHandler implements
- JcrExplorerConstants, ArgeoNames {
-
- private RepositoryFactory repositoryFactory;
- private Repository nodeRepository;
- private Keyring keyring;
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(
- Display.getDefault().getActiveShell());
- if (dlg.open() == Dialog.OK) {
- CommandUtils.callCommand(Refresh.ID);
- }
- return null;
- }
-
- public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
- this.repositoryFactory = repositoryFactory;
- }
-
- public void setKeyring(Keyring keyring) {
- this.keyring = keyring;
- }
-
- public void setNodeRepository(Repository nodeRepository) {
- this.nodeRepository = nodeRepository;
- }
-
- class RemoteRepositoryLoginDialog extends TitleAreaDialog {
- private Text name;
- private Text uri;
- private Text username;
- private Text password;
- private Button saveInKeyring;
-
- public RemoteRepositoryLoginDialog(Shell parentShell) {
- super(parentShell);
- }
-
- protected Point getInitialSize() {
- return new Point(600, 400);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
- true));
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
- false));
- setMessage("Login to remote repository", IMessageProvider.NONE);
- name = createLT(composite, "Name", "remoteRepository");
- uri = createLT(composite, "URI",
- "http://localhost:7070/data/jcr/node");
- username = createLT(composite, "User", "");
- password = createLP(composite, "Password");
-
- saveInKeyring = createLC(composite, "Remember password", false);
- parent.pack();
- return composite;
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- super.createButtonsForButtonBar(parent);
- Button test = createButton(parent, 2, "Test", false);
- test.addSelectionListener(new SelectionAdapter() {
- public void widgetSelected(SelectionEvent arg0) {
- testConnection();
- }
- });
- }
-
- void testConnection() {
- Session session = null;
- try {
- URI checkedUri = new URI(uri.getText());
- String checkedUriStr = checkedUri.toString();
-
- Hashtable<String, String> params = new Hashtable<String, String>();
- params.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, checkedUriStr);
- Repository repository = repositoryFactory.getRepository(params);
- if (username.getText().trim().equals("")) {// anonymous
- session = repository.login();
- } else {
- // FIXME use getTextChars() when upgrading to 3.7
- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412
- char[] pwd = password.getText().toCharArray();
- SimpleCredentials sc = new SimpleCredentials(
- username.getText(), pwd);
- session = repository.login(sc);
- MessageDialog.openInformation(getParentShell(), "Success",
- "Connection to '" + uri.getText() + "' successful");
- }
- } catch (Exception e) {
- ErrorFeedback.show(
- "Connection test failed for " + uri.getText(), e);
- } finally {
- JcrUtils.logoutQuietly(session);
- }
- }
-
- @Override
- protected void okPressed() {
- Session nodeSession = null;
- try {
- nodeSession = nodeRepository.login();
- Node home = UserJcrUtils.getUserHome(nodeSession);
-
- Node remote = home.hasNode(ARGEO_REMOTE) ? home
- .getNode(ARGEO_REMOTE) : home.addNode(ARGEO_REMOTE);
- if (remote.hasNode(name.getText()))
- throw new ArgeoException(
- "There is already a remote repository named "
- + name.getText());
- Node remoteRepository = remote.addNode(name.getText(),
- ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
- remoteRepository.setProperty(ARGEO_URI, uri.getText());
- remoteRepository.setProperty(ARGEO_USER_ID, username.getText());
- nodeSession.save();
- if (saveInKeyring.getSelection()) {
- String pwdPath = remoteRepository.getPath() + '/'
- + ARGEO_PASSWORD;
- keyring.set(pwdPath, password.getText().toCharArray());
- }
- nodeSession.save();
- MessageDialog.openInformation(
- getParentShell(),
- "Repository Added",
- "Remote repository '" + username.getText() + "@"
- + uri.getText() + "' added");
-
- super.okPressed();
- } catch (Exception e) {
- ErrorFeedback.show("Cannot add remote repository", e);
- } finally {
- JcrUtils.logoutQuietly(nodeSession);
- }
- }
-
- /** Creates label and text. */
- protected Text createLT(Composite parent, String label, String initial) {
- new Label(parent, SWT.NONE).setText(label);
- Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- text.setText(initial);
- return text;
- }
-
- /** Creates label and check. */
- protected Button createLC(Composite parent, String label,
- Boolean initial) {
- new Label(parent, SWT.NONE).setText(label);
- Button check = new Button(parent, SWT.CHECK);
- check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- check.setSelection(initial);
- return check;
- }
-
- protected Text createLP(Composite parent, String label) {
- new Label(parent, SWT.NONE).setText(label);
- Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER
- | SWT.PASSWORD);
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- return text;
- }
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import java.util.Arrays;
-
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.dialogs.SingleValue;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.model.RepositoryElem;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Creates a new JCR workspace */
-public class CreateWorkspace extends AbstractHandler {
-
- public final static String ID = JcrExplorerPlugin.ID + ".addFolderNode";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
-
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
-
- GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(HandlerUtil.getActivePartId(event));
-
- if (selection != null && !selection.isEmpty()
- && selection instanceof IStructuredSelection) {
- Object obj = ((IStructuredSelection) selection).getFirstElement();
- if (!(obj instanceof RepositoryElem))
- return null;
-
- RepositoryElem repositoryNode = (RepositoryElem) obj;
- String workspaceName = SingleValue.ask("Workspace name",
- "Enter workspace name");
- if (workspaceName != null) {
- if (Arrays.asList(repositoryNode.getAccessibleWorkspaceNames())
- .contains(workspaceName)) {
- ErrorFeedback.show("Workspace " + workspaceName
- + " already exists.");
- } else {
- repositoryNode.createWorkspace(workspaceName);
- view.nodeAdded(repositoryNode);
- }
- }
- } else {
- ErrorFeedback.show("Cannot create workspace");
- }
- return null;
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import java.util.Iterator;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * Deletes the selected nodes: both in the JCR repository and in the UI view.
- * Warning no check is done, except implementation dependent native checks,
- * handle with care.
- *
- * This handler is still 'hard linked' to a GenericJcrBrowser view to enable
- * correct tree refresh when a node is added. This must be corrected in future
- * versions.
- */
-public class DeleteNodes extends AbstractHandler {
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
- if (selection == null || !(selection instanceof IStructuredSelection))
- return null;
-
- GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(HandlerUtil.getActivePartId(event));
-
- // confirmation
- StringBuffer buf = new StringBuffer("");
- Iterator<?> lst = ((IStructuredSelection) selection).iterator();
- while (lst.hasNext()) {
- SingleJcrNodeElem sjn = ((SingleJcrNodeElem) lst.next());
- buf.append(sjn.getName()).append(' ');
- }
- Boolean ok = MessageDialog.openConfirm(
- HandlerUtil.getActiveShell(event), "Confirm deletion",
- "Do you want to delete " + buf + "?");
-
- // operation
- if (ok) {
- Iterator<?> it = ((IStructuredSelection) selection).iterator();
- Object obj = null;
- SingleJcrNodeElem ancestor = null;
- WorkspaceElem rootAncestor = null;
- try {
- while (it.hasNext()) {
- obj = it.next();
- if (obj instanceof SingleJcrNodeElem) {
- // Cache objects
- SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj;
- TreeParent tp = (TreeParent) sjn.getParent();
- Node node = sjn.getNode();
-
- // Jcr Remove
- node.remove();
- node.getSession().save();
- // UI remove
- tp.removeChild(sjn);
-
- // Check if the parent is the root node
- if (tp instanceof WorkspaceElem)
- rootAncestor = (WorkspaceElem) tp;
- else
- ancestor = getOlder(ancestor, (SingleJcrNodeElem) tp);
- }
- }
- if (rootAncestor != null)
- view.nodeRemoved(rootAncestor);
- else if (ancestor != null)
- view.nodeRemoved(ancestor);
- } catch (Exception e) {
- ErrorFeedback.show("Cannot delete selected node ", e);
- }
- }
- return null;
- }
-
- private SingleJcrNodeElem getOlder(SingleJcrNodeElem A, SingleJcrNodeElem B) {
- try {
- if (A == null)
- return B == null ? null : B;
- // Todo enhanced this method
- else
- return A.getNode().getDepth() <= B.getNode().getDepth() ? A : B;
- } catch (RepositoryException re) {
- throw new ArgeoException("Cannot find ancestor", re);
- }
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.specific.OpenFile;
-import org.argeo.eclipse.ui.utils.CommandUtils;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * If the method
- * <code> HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection() </code>
- * exits and has a SingleJcrNodeElem as first element, it canonically calls the
- * JCR Session.exportSystemView() method on the underlying node with both
- * skipBinary & noRecurse boolean flags set to false.
- *
- * Resulting stream is saved in a tmp file and opened via the "open file"
- * single-sourced command.
- */
-public class DumpNode extends AbstractHandler {
- public final static String ID = JcrExplorerPlugin.ID + ".dumpNode";
-
- private final static DateFormat df = new SimpleDateFormat(
- "yyyy-MM-dd_HH-mm");
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
- if (selection == null || !(selection instanceof IStructuredSelection))
- return null;
-
- Iterator<?> lst = ((IStructuredSelection) selection).iterator();
- if (lst.hasNext()) {
- Object element = lst.next();
- if (element instanceof SingleJcrNodeElem) {
- SingleJcrNodeElem sjn = (SingleJcrNodeElem) element;
- Node node = sjn.getNode();
-
- // TODO add a dialog to configure the export and ask for
- // confirmation
- // Boolean ok = MessageDialog.openConfirm(
- // HandlerUtil.getActiveShell(event), "Confirm deletion",
- // "Do you want to delete " + buf + "?");
-
- File tmpFile;
- FileOutputStream fos;
- try {
- tmpFile = File.createTempFile("JcrExport", ".xml");
- tmpFile.deleteOnExit();
- fos = new FileOutputStream(tmpFile);
- String dateVal = df.format(new GregorianCalendar()
- .getTime());
- node.getSession().exportSystemView(node.getPath(), fos,
- true, false);
- openGeneratedFile(tmpFile.getAbsolutePath(),
- "Dump-" + JcrUtils.replaceInvalidChars(node.getName())+ "-" + dateVal + ".xml");
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unable to perform SystemExport on " + node, e);
- } catch (IOException e) {
- throw new ArgeoException("Unable to SystemExport " + node,
- e);
- }
- }
- }
- return null;
- }
-
- private synchronized void openGeneratedFile(String path, String fileName) {
- Map<String, String> params = new HashMap<String, String>();
- params.put(OpenFile.PARAM_FILE_NAME, fileName);
- params.put(OpenFile.PARAM_FILE_URI, "file://" + path);
- CommandUtils.callCommand("org.argeo.security.ui.specific.openFile",
- params);
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Property;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.jcr.editors.NodeEditorInput;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Generic command to open a path in an editor. */
-public class EditNode extends AbstractHandler {
- public final static String EDITOR_PARAM = "editor";
-
- private String defaultEditorId;
-
- private Map<String, String> nodeTypeToEditor = new HashMap<String, String>();
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- String path = event.getParameter(Property.JCR_PATH);
-
- String type = event.getParameter(NodeType.NT_NODE_TYPE);
- if (type == null)
- type = NodeType.NT_UNSTRUCTURED;
-
- String editorId = event.getParameter(NodeType.NT_NODE_TYPE);
- if (editorId == null)
- editorId = nodeTypeToEditor.containsKey(type) ? nodeTypeToEditor
- .get(type) : defaultEditorId;
-
- NodeEditorInput nei = new NodeEditorInput(path);
-
- try {
- HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
- .openEditor(nei, editorId);
- } catch (PartInitException e) {
- ErrorFeedback.show("Cannot open " + editorId + " with " + path
- + " of type " + type, e);
- }
- // TODO Auto-generated method stub
- return null;
- }
-
- public void setDefaultEditorId(String defaultEditorId) {
- this.defaultEditorId = defaultEditorId;
- }
-
-}
+++ /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.jcr.ui.explorer.commands;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.Node;
-
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Opens the generic node editor. */
-public class GetNodeSize extends AbstractHandler {
- // private final static Log log = LogFactory.getLog(GetNodeSize.class);
-
- public final static String ID = JcrExplorerPlugin.ID + ".getNodeSize";
-
- // public final static String DEFAULT_ICON_REL_PATH = "icons/getSize.gif";
- // public final static String DEFAULT_LABEL = JcrExplorerPlugin
- // .getMessage("getNodeSizeCmdLbl");
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- // JcrUtils.getRepositoryByAlias(repositoryRegister,
- // ArgeoJcrConstants.ALIAS_NODE);
-
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
-
- if (selection != null && !selection.isEmpty()
- && selection instanceof IStructuredSelection) {
-
- // IStructuredSelection iss = (IStructuredSelection) selection;
- // if (iss.size() > 1)
- // ErrorFeedback.show(JcrExplorerPlugin
- // .getMessage("warningInvalidMultipleSelection"), null);
-
- long size = 0;
-
- Iterator<?> it = ((IStructuredSelection) selection).iterator();
-
- // as the size method is recursive, we keep track of nodes for which
- // we already have computed size so that we don't count them twice.
- // In a first approximation, we assume that the structure selection
- // keep the nodes ordered.
- // TODO : enhance that.
- List<String> importedPathes = new ArrayList<String>();
- try {
- nodesIt: while (it.hasNext()) {
- Object obj = it.next();
- String curPath;
- Node node;
- if (obj instanceof SingleJcrNodeElem) {
- node = ((SingleJcrNodeElem) obj).getNode();
- curPath = node.getSession().getWorkspace().getName();
- curPath += "/" + node.getPath();
- } else if (obj instanceof WorkspaceElem) {
- node = ((WorkspaceElem) obj).getRootNode();
- curPath = node.getSession().getWorkspace().getName();
- } else
- // unvalid object type
- continue nodesIt;
-
- Iterator<String> itPath = importedPathes.iterator();
- while (itPath.hasNext()) {
- String refPath = itPath.next();
- if (curPath.startsWith(refPath))
- // Already done : skip node
- continue nodesIt;
- }
- size += JcrUtils.getNodeApproxSize(node);
- importedPathes.add(curPath);
- }
- } catch (Exception e) {
- ErrorFeedback.show("Cannot Get size of selected node ", e);
- }
-
- String[] labels = { "OK" };
- Shell shell = HandlerUtil.getActiveWorkbenchWindow(event)
- .getShell();
- MessageDialog md = new MessageDialog(shell, "Node size", null,
- "Node size is: " + size / 1024 + " KB",
- MessageDialog.INFORMATION, labels, 0);
- md.open();
- }
- return null;
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import javax.jcr.Node;
-
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.argeo.jcr.ui.explorer.wizards.ImportFileSystemWizard;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Import a local file system directory tree. */
-public class ImportFileSystem extends AbstractHandler {
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
- GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(HandlerUtil.getActivePartId(event));
- if (selection != null && !selection.isEmpty()
- && selection instanceof IStructuredSelection) {
- Object obj = ((IStructuredSelection) selection).getFirstElement();
- try {
- Node folder = null;
- if (obj instanceof SingleJcrNodeElem) {
- folder = ((SingleJcrNodeElem) obj).getNode();
- } else if (obj instanceof WorkspaceElem) {
- folder = ((WorkspaceElem) obj).getRootNode();
- } else {
- ErrorFeedback.show(JcrExplorerPlugin
- .getMessage("warningInvalidNodeToImport"));
- }
- if (folder != null) {
- ImportFileSystemWizard wizard = new ImportFileSystemWizard(
- folder);
- WizardDialog dialog = new WizardDialog(
- HandlerUtil.getActiveShell(event), wizard);
- dialog.open();
- view.nodeAdded((TreeParent) obj);
- }
- } catch (Exception e) {
- ErrorFeedback.show("Cannot import files to " + obj, e);
- }
- }
- return null;
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.jcr.editors.NodeEditorInput;
-import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.editors.GenericNodeEditor;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Opens the generic node editor. */
-public class OpenGenericNodeEditor extends AbstractHandler {
- public final static String ID = JcrExplorerPlugin.ID + ".openGenericNodeEditor";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- String path = event.getParameter(JcrExplorerConstants.PARAM_PATH);
- try {
- NodeEditorInput nei = new NodeEditorInput(path);
- HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
- .openEditor(nei, GenericNodeEditor.ID);
- } catch (Exception e) {
- throw new ArgeoException("Cannot open editor", e);
- }
- return null;
- }
-
-}
+++ /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.jcr.ui.explorer.commands;
-
-import java.util.Iterator;
-
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.utils.JcrUiUtils;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-
-/**
- * Force the selected objects of the active view to be refreshed doing the
- * following:
- * <ol>
- * <li>The model objects are recomputed</li>
- * <li>the view is refreshed</li>
- * </ol>
- */
-public class Refresh extends AbstractHandler {
-
- public final static String ID = JcrExplorerPlugin.ID + ".refresh";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
-
- AbstractJcrBrowser view = (AbstractJcrBrowser) JcrExplorerPlugin
- .getDefault().getWorkbench().getActiveWorkbenchWindow()
- .getActivePage().getActivePart();//
-
- ISelection selection = JcrExplorerPlugin.getDefault().getWorkbench()
- .getActiveWorkbenchWindow().getActivePage().getSelection();
-
- if (selection != null && selection instanceof IStructuredSelection
- && !selection.isEmpty()) {
- Iterator<?> it = ((IStructuredSelection) selection).iterator();
- while (it.hasNext()) {
- Object obj = it.next();
- if (obj instanceof TreeParent) {
- TreeParent tp = (TreeParent) obj;
- JcrUiUtils.forceRefreshIfNeeded(tp);
- view.refresh(obj);
- }
- }
- } else if (view instanceof GenericJcrBrowser)
- ((GenericJcrBrowser) view).refresh(null); // force full refresh
-
- return null;
- }
-}
+++ /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.jcr.ui.explorer.commands;
-
-import org.argeo.jcr.ui.explorer.model.RemoteRepositoryElem;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Remove a registered remote repository */
-public class RemoveRemoteRepository extends AbstractHandler {
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
-
- ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getSelection();
-
- GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(HandlerUtil.getActivePartId(event));
-
- if (selection != null && !selection.isEmpty()
- && selection instanceof IStructuredSelection) {
- Object obj = ((IStructuredSelection) selection).getFirstElement();
-
- if (obj instanceof RemoteRepositoryElem) {
- ((RemoteRepositoryElem) obj).remove();
- view.refresh(null);
- }
- }
- return null;
- }
-
-}
+++ /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.jcr.ui.explorer.commands;
-
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.Command;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.commands.State;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.commands.ICommandService;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * Change isSorted state of the JcrExplorer Browser
- */
-public class SortChildNodes extends AbstractHandler {
- public final static String ID = JcrExplorerPlugin.ID + ".sortChildNodes";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(GenericJcrBrowser.ID);
-
- ICommandService service = (ICommandService) PlatformUI.getWorkbench()
- .getService(ICommandService.class);
- Command command = service.getCommand(ID);
- State state = command.getState(ID + ".toggleState");
-
- boolean wasSorted = (Boolean) state.getValue();
- view.setSortChildNodes(!wasSorted);
- state.setValue(!wasSorted);
- return null;
- }
-}
+++ /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.jcr.ui.explorer.dialogs;
-
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/** Dialog to change the current user password */
-public class ChooseNameDialog extends TitleAreaDialog {
- private Text nameT;
-
- public ChooseNameDialog(Shell parentShell) {
- super(parentShell);
- setTitle("Choose name");
- }
-
- protected Point getInitialSize() {
- return new Point(300, 250);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- nameT = createLT(composite, "Name");
-
- setMessage("Choose name", IMessageProvider.INFORMATION);
- parent.pack();
- return composite;
- }
-
- /** Creates label and text. */
- protected Text createLT(Composite parent, String label) {
- new Label(parent, SWT.NONE).setText(label);
- Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- return text;
- }
-
- public String getName() {
- return nameT.getText();
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import javax.jcr.Node;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
-import org.argeo.jcr.ui.explorer.providers.SingleNodeAsTreeContentProvider;
-import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-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;
-
-/**
- * List all childs of the current node and brings some browsing capabilities
- * accross the repository
- */
-public class ChildNodesPage extends FormPage {
- // private final static Log log = LogFactory.getLog(ChildNodesPage.class);
-
- // business objects
- private Node currentNode;
-
- // this page UI components
- private SingleNodeAsTreeContentProvider nodeContentProvider;
- private TreeViewer nodesViewer;
-
- public ChildNodesPage(FormEditor editor, String title, Node currentNode) {
- super(editor, "ChildNodesPage", title);
- this.currentNode = currentNode;
- }
-
- protected void createFormContent(IManagedForm managedForm) {
- try {
- ScrolledForm form = managedForm.getForm();
- form.setText(JcrExplorerPlugin.getMessage("childNodesPageTitle"));
- Composite body = form.getBody();
- GridLayout twt = new GridLayout(1, false);
- twt.marginWidth = twt.marginHeight = 5;
- body.setLayout(twt);
- if (!currentNode.hasNodes()) {
- managedForm.getToolkit().createLabel(body,
- JcrExplorerPlugin.getMessage("warningNoChildNode"));
- } else {
-
- nodeContentProvider = new SingleNodeAsTreeContentProvider();
- nodesViewer = createNodeViewer(body, nodeContentProvider);
- nodesViewer.setInput(currentNode);
- }
- } catch (Exception e) {
- throw new ArgeoException(
- "Unexpected error while creating child node page", e);
- }
- }
-
- protected TreeViewer createNodeViewer(Composite parent,
- final ITreeContentProvider nodeContentProvider) {
-
- final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
-
- tmpNodeViewer.getTree().setLayoutData(
- new GridData(SWT.FILL, SWT.FILL, true, true));
-
- tmpNodeViewer.setContentProvider(nodeContentProvider);
- tmpNodeViewer.setLabelProvider(new NodeLabelProvider());
- tmpNodeViewer
- .addDoubleClickListener(new GenericNodeDoubleClickListener(
- tmpNodeViewer));
- return tmpNodeViewer;
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Label;
-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;
-
-/**
- * This page is only used at editor's creation time when current node has not
- * yet been set
- */
-public class EmptyNodePage extends FormPage {
- // private final static Log log = LogFactory.getLog(EmptyNodePage.class);
-
- public EmptyNodePage(FormEditor editor, String title) {
- super(editor, "Empty Page", title);
- }
-
- protected void createFormContent(IManagedForm managedForm) {
- try {
- ScrolledForm form = managedForm.getForm();
- GridLayout twt = new GridLayout(1, false);
- twt.marginWidth = twt.marginHeight = 0;
- form.getBody().setLayout(twt);
- Label lbl = new Label(form.getBody(), SWT.NONE);
- lbl.setText("Empty page");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import org.argeo.eclipse.ui.jcr.editors.AbstractJcrQueryEditor;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Text;
-
-/** Enables end user to type and execute any JCR query. */
-public class GenericJcrQueryEditor extends AbstractJcrQueryEditor {
- public final static String ID = JcrExplorerPlugin.ID + ".genericJcrQueryEditor";
-
- private Text queryField;
-
- @Override
- public void createQueryForm(Composite parent) {
- parent.setLayout(new GridLayout(1, false));
-
- queryField = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP);
- queryField.setText(initialQuery);
- queryField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- Button execute = new Button(parent, SWT.PUSH);
- execute.setText("Execute");
-
- Listener executeListener = new Listener() {
- public void handleEvent(Event event) {
- executeQuery(queryField.getText());
- }
- };
-
- execute.addListener(SWT.Selection, executeListener);
- // queryField.addListener(SWT.DefaultSelection, executeListener);
- }
-
- @Override
- public void setFocus() {
- queryField.setFocus();
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import javax.jcr.Node;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.forms.editor.FormEditor;
-
-/**
- * Container for the node editor page. At creation time, it takes a JCR Node
- * that cannot be changed afterwards.
- */
-public class GenericNodeEditor extends FormEditor {
-
- // private final static Log log =
- // LogFactory.getLog(GenericNodeEditor.class);
- public final static String ID = JcrExplorerPlugin.ID + ".genericNodeEditor";
-
- private Node currentNode;
-
- private GenericPropertyPage genericPropertyPage;
- private ChildNodesPage childNodesPage;
- private NodeRightsManagementPage nodeRightsManagementPage;
- private NodeVersionHistoryPage nodeVersionHistoryPage;
-
- public void init(IEditorSite site, IEditorInput input)
- throws PartInitException {
- super.init(site, input);
- GenericNodeEditorInput nei = (GenericNodeEditorInput) getEditorInput();
- currentNode = nei.getCurrentNode();
- this.setPartName(JcrUtils.lastPathElement(nei.getPath()));
- }
-
- @Override
- protected void addPages() {
- try {
- // genericNodePage = new GenericNodePage(this,
- // JcrExplorerPlugin.getMessage("genericNodePageTitle"),
- // currentNode);
- // addPage(genericNodePage);
-
- genericPropertyPage = new GenericPropertyPage(this,
- JcrExplorerPlugin.getMessage("genericNodePageTitle"),
- currentNode);
- addPage(genericPropertyPage);
-
- childNodesPage = new ChildNodesPage(this,
- JcrExplorerPlugin.getMessage("childNodesPageTitle"),
- currentNode);
- addPage(childNodesPage);
-
- nodeRightsManagementPage = new NodeRightsManagementPage(this,
- JcrExplorerPlugin
- .getMessage("nodeRightsManagementPageTitle"),
- currentNode);
- addPage(nodeRightsManagementPage);
-
- nodeVersionHistoryPage = new NodeVersionHistoryPage(
- this,
- JcrExplorerPlugin.getMessage("nodeVersionHistoryPageTitle"),
- currentNode);
- addPage(nodeVersionHistoryPage);
- } catch (PartInitException e) {
- throw new ArgeoException("Not able to add an empty page ", e);
- }
- }
-
- @Override
- public void doSaveAs() {
- // unused compulsory method
- }
-
- @Override
- public void doSave(IProgressMonitor monitor) {
- try {
- // Automatically commit all pages of the editor
- commitPages(true);
- firePropertyChange(PROP_DIRTY);
- } catch (Exception e) {
- throw new ArgeoException("Error while saving node", e);
- }
-
- }
-
- @Override
- public boolean isSaveAsAllowed() {
- return true;
- }
-
- Node getCurrentNode() {
- return currentNode;
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-/**
- * An editor input based the JCR node object.
- * */
-
-public class GenericNodeEditorInput implements IEditorInput {
- private final Node currentNode;
-
- // cache key properties at creation time to avoid Exception at recoring time
- // when the session has been closed
- private String path;
- private String uid;
- private String name;
-
- public GenericNodeEditorInput(Node currentNode) {
- this.currentNode = currentNode;
- try {
- name = currentNode.getName();
- uid = currentNode.getIdentifier();
- path = currentNode.getPath();
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "unexpected error while getting node key values at creation time",
- re);
- }
- }
-
- public Node getCurrentNode() {
- return currentNode;
- }
-
- public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
- return null;
- }
-
- public boolean exists() {
- return true;
- }
-
- public ImageDescriptor getImageDescriptor() {
- return null;
- }
-
- public String getName() {
- return name;
- }
-
- public String getUid() {
- return uid;
- }
-
- public String getToolTipText() {
- return path;
- }
-
- public String getPath() {
- return path;
- }
-
- public IPersistableElement getPersistable() {
- return null;
- }
-
- /**
- * equals method based on UID that is unique within a workspace and path of
- * the node, thus 2 shared node that have same UID as defined in the spec
- * but 2 different pathes will open two distinct editors.
- *
- * TODO enhance this method to support multirepository and multiworkspace
- * environments
- */
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
-
- GenericNodeEditorInput other = (GenericNodeEditorInput) obj;
- if (!getUid().equals(other.getUid()))
- return false;
- if (!getPath().equals(other.getPath()))
- return false;
- return true;
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.ListIterator;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
-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.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.AbstractFormPart;
-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.FormToolkit;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-
-/**
- * Main node editor page. Lists all properties of the current node and enable
- * access and editing for some of them.
- */
-
-public class GenericNodePage extends FormPage implements JcrExplorerConstants {
- // private final static Log log = LogFactory.getLog(GenericNodePage.class);
-
- // local constants
- private final static String JCR_PROPERTY_NAME = "jcr:name";
-
- // Utils
- protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
-
- // Main business Objects
- private Node currentNode;
-
- // This page widgets
- private FormToolkit tk;
- private List<Control> modifyableProperties = new ArrayList<Control>();
-
- public GenericNodePage(FormEditor editor, String title, Node currentNode) {
- super(editor, "id", title);
- this.currentNode = currentNode;
- }
-
- protected void createFormContent(IManagedForm managedForm) {
- tk = managedForm.getToolkit();
- ScrolledForm form = managedForm.getForm();
- GridLayout twt = new GridLayout(3, false);
- twt.marginWidth = twt.marginHeight = 5;
-
- form.getBody().setLayout(twt);
- createPropertiesPart(form.getBody());
- }
-
- private void createPropertiesPart(Composite parent) {
- try {
-
- PropertyIterator pi = currentNode.getProperties();
-
- // Initializes form part
- AbstractFormPart part = new AbstractFormPart() {
- public void commit(boolean onSave) {
- try {
- if (onSave) {
- ListIterator<Control> it = modifyableProperties
- .listIterator();
- while (it.hasNext()) {
- // we only support Text controls for the time
- // being
- Text curControl = (Text) it.next();
- String value = curControl.getText();
- currentNode.setProperty((String) curControl
- .getData(JCR_PROPERTY_NAME), value);
- }
-
- // We only commit when onSave = true,
- // thus it is still possible to save after a tab
- // change.
- super.commit(onSave);
- }
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while saving properties", re);
- }
- }
- };
-
- while (pi.hasNext()) {
- Property prop = pi.nextProperty();
- addPropertyLine(parent, part, prop);
- }
-
- getManagedForm().addPart(part);
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Error during creation of network details section", re);
- }
-
- }
-
- private void addPropertyLine(Composite parent, AbstractFormPart part,
- Property prop) {
- try {
- tk.createLabel(parent, prop.getName());
- tk.createLabel(parent,
- "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]");
-
- if (prop.getDefinition().isProtected()) {
- tk.createLabel(parent, formatReadOnlyPropertyValue(prop));
- } else
- addModifyableValueWidget(parent, part, prop);
- } catch (RepositoryException re) {
- throw new ArgeoException("Cannot get property " + prop, re);
- }
- }
-
- private String formatReadOnlyPropertyValue(Property prop) {
- try {
- String strValue;
-
- if (prop.getType() == PropertyType.BINARY)
- strValue = "<binary>";
- else if (prop.isMultiple())
- strValue = Arrays.asList(prop.getValues()).toString();
- else if (prop.getType() == PropertyType.DATE)
- strValue = timeFormatter.format(prop.getValue().getDate()
- .getTime());
- else
- strValue = prop.getValue().getString();
-
- return strValue;
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while formatting read only property value",
- re);
- }
- }
-
- private Control addModifyableValueWidget(Composite parent,
- AbstractFormPart part, Property prop) {
- GridData gd;
- try {
- if (prop.getType() == PropertyType.STRING) {
- Text txt = tk.createText(parent, prop.getString());
- gd = new GridData(GridData.FILL_HORIZONTAL);
- txt.setLayoutData(gd);
- txt.addModifyListener(new ModifiedFieldListener(part));
- txt.setData(JCR_PROPERTY_NAME, prop.getName());
- modifyableProperties.add(txt);
- } else {
- // unsupported property type for editing, we create a read only
- // label.
- return tk
- .createLabel(parent, formatReadOnlyPropertyValue(prop));
- }
- return null;
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while formatting read only property value",
- re);
- }
-
- }
-
- //
- // LISTENERS
- //
-
- private class ModifiedFieldListener implements ModifyListener {
-
- private AbstractFormPart formPart;
-
- public ModifiedFieldListener(AbstractFormPart generalPart) {
- this.formPart = generalPart;
- }
-
- public void modifyText(ModifyEvent e) {
- formPart.markDirty();
- }
- }
-
-}
+++ /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.jcr.ui.explorer.editors;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.providers.PropertyLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-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;
-
-/**
- * Generic editor property page. Lists all properties of current node as a
- * complex tree. TODO: enable editing
- */
-
-public class GenericPropertyPage extends FormPage implements
- JcrExplorerConstants {
- // private final static Log log =
- // LogFactory.getLog(GenericPropertyPage.class);
-
- // Main business Objects
- private Node currentNode;
-
- public GenericPropertyPage(FormEditor editor, String title, Node currentNode) {
- super(editor, "id", title);
- this.currentNode = currentNode;
- }
-
- protected void createFormContent(IManagedForm managedForm) {
- ScrolledForm form = managedForm.getForm();
- form.setText(JcrExplorerPlugin.getMessage("genericNodePageTitle"));
- FillLayout layout = new FillLayout();
- layout.marginHeight = 5;
- layout.marginWidth = 5;
- form.getBody().setLayout(layout);
-
- createComplexTree(form.getBody());
-
- // TODO remove following
- // createPropertiesPart(form.getBody());
- }
-
- private TreeViewer createComplexTree(Composite parent) {
- int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION;
- Tree tree = new Tree(parent, style);
- createColumn(tree, "Property", SWT.LEFT, 200);
- createColumn(tree, "Value(s)", SWT.LEFT, 300);
- createColumn(tree, "Attributes", SWT.LEFT, 65);
- tree.setLinesVisible(true);
- tree.setHeaderVisible(true);
-
- TreeViewer result = new TreeViewer(tree);
- result.setContentProvider(new TreeContentProvider());
- result.setLabelProvider(new PropertyLabelProvider());
- result.setInput(currentNode);
- result.expandAll();
- return result;
- }
-
- private static TreeColumn createColumn(Tree parent, String name, int style,
- int width) {
- TreeColumn result = new TreeColumn(parent, style);
- result.setText(name);
- result.setWidth(width);
- result.setMoveable(true);
- result.setResizable(true);
- return result;
- }
-
- //
- // private void createPropertiesPart(Composite parent) {
- // try {
- //
- // PropertyIterator pi = currentNode.getProperties();
- //
- // // Initializes form part
- // AbstractFormPart part = new AbstractFormPart() {
- // public void commit(boolean onSave) {
- // try {
- // if (onSave) {
- // ListIterator<Control> it = modifyableProperties
- // .listIterator();
- // while (it.hasNext()) {
- // // we only support Text controls for the time
- // // being
- // Text curControl = (Text) it.next();
- // String value = curControl.getText();
- // currentNode.setProperty((String) curControl
- // .getData(JCR_PROPERTY_NAME), value);
- // }
- //
- // // We only commit when onSave = true,
- // // thus it is still possible to save after a tab
- // // change.
- // super.commit(onSave);
- // }
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Unexpected error while saving properties", re);
- // }
- // }
- // };
- //
- // while (pi.hasNext()) {
- // Property prop = pi.nextProperty();
- // addPropertyLine(parent, part, prop);
- // }
- //
- // getManagedForm().addPart(part);
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Error during creation of network details section", re);
- // }
- //
- // }
- //
- // private void addPropertyLine(Composite parent, AbstractFormPart part,
- // Property prop) {
- // try {
- // tk.createLabel(parent, prop.getName());
- // tk.createLabel(parent,
- // "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]");
- //
- // if (prop.getDefinition().isProtected()) {
- // tk.createLabel(parent, formatReadOnlyPropertyValue(prop));
- // } else
- // addModifyableValueWidget(parent, part, prop);
- // } catch (RepositoryException re) {
- // throw new ArgeoException("Cannot get property " + prop, re);
- // }
- // }
- //
- // private String formatReadOnlyPropertyValue(Property prop) {
- // try {
- // String strValue;
- //
- // if (prop.getType() == PropertyType.BINARY)
- // strValue = "<binary>";
- // else if (prop.isMultiple())
- // strValue = Arrays.asList(prop.getValues()).toString();
- // else if (prop.getType() == PropertyType.DATE)
- // strValue = timeFormatter.format(prop.getValue().getDate()
- // .getTime());
- // else
- // strValue = prop.getValue().getString();
- //
- // return strValue;
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Unexpected error while formatting read only property value",
- // re);
- // }
- // }
- //
- // private Control addModifyableValueWidget(Composite parent,
- // AbstractFormPart part, Property prop) {
- // GridData gd;
- // try {
- // if (prop.getType() == PropertyType.STRING) {
- // Text txt = tk.createText(parent, prop.getString());
- // gd = new GridData(GridData.FILL_HORIZONTAL);
- // txt.setLayoutData(gd);
- // txt.addModifyListener(new ModifiedFieldListener(part));
- // txt.setData(JCR_PROPERTY_NAME, prop.getName());
- // modifyableProperties.add(txt);
- // } else {
- // // unsupported property type for editing, we create a read only
- // // label.
- // return tk
- // .createLabel(parent, formatReadOnlyPropertyValue(prop));
- // }
- // return null;
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Unexpected error while formatting read only property value",
- // re);
- // }
- //
- // }
-
- // Multiple Value Model
- // protected class MultipleValueItem {
- // private int index;
- // private Value value;
- //
- // public MultipleValueItem(int index, Value value) {
- // this.index = index;
- // this.value = value;
- // }
- //
- // public int getIndex() {
- // return index;
- // }
- //
- // public Object getValue() {
- // return value;
- // }
- // }
-
- private class TreeContentProvider implements ITreeContentProvider {
- public Object[] getElements(Object parent) {
- Object[] props = null;
- try {
-
- if (parent instanceof Node) {
- Node node = (Node) parent;
- PropertyIterator pi;
- pi = node.getProperties();
- List<Property> propList = new ArrayList<Property>();
- while (pi.hasNext()) {
- propList.add(pi.nextProperty());
- }
- props = propList.toArray();
- }
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception while listing node properties", e);
- }
- return props;
- }
-
- public Object getParent(Object child) {
- return null;
- }
-
- public Object[] getChildren(Object parent) {
- Object[] result = null;
- if (parent instanceof Property) {
- Property prop = (Property) parent;
- try {
-
- if (prop.isMultiple()) {
- Value[] values = prop.getValues();
- // List<MultipleValueItem> list = new
- // ArrayList<MultipleValueItem>();
- // for (int i = 0; i < values.length; i++) {
- // MultipleValueItem mvi = new MultipleValueItem(i,
- // values[i]);
- // list.add(mvi);
- // }
-
- return values;
- }
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected error getting multiple values property.",
- e);
- }
- }
- return result;
- }
-
- public boolean hasChildren(Object parent) {
- try {
- if (parent instanceof Property
- && ((Property) parent).isMultiple()) {
- return true;
- }
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception while checking if property is multiple",
- e);
- }
- return false;
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- public void dispose() {
- }
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import javax.jcr.Node;
-import javax.jcr.security.AccessControlManager;
-import javax.jcr.security.Privilege;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-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.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-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;
-
-/**
- * This comments will be nicely fill by mbaudier in.
- */
-public class NodeRightsManagementPage extends FormPage {
- // private final static Log log =
- // LogFactory.getLog(NodeRightsManagementPage.class);
-
- private Node currentNode;
-
- private TableViewer viewer;
-
- public NodeRightsManagementPage(FormEditor editor, String title,
- Node currentNode) {
- super(editor, "NodeRightsManagementPage", title);
- this.currentNode = currentNode;
- }
-
- protected void createFormContent(IManagedForm managedForm) {
- ScrolledForm form = managedForm.getForm();
- form.setText(JcrExplorerPlugin
- .getMessage("nodeRightsManagementPageTitle"));
- FillLayout layout = new FillLayout();
- layout.marginHeight = 5;
- layout.marginWidth = 5;
- form.getBody().setLayout(layout);
- createRightsPart(form.getBody());
- }
-
- /** Creates the rights part */
- protected void createRightsPart(Composite parent) {
- Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
- table.setLinesVisible(true);
- table.setHeaderVisible(true);
- viewer = new TableViewer(table);
-
- // check column
- TableViewerColumn column = createTableViewerColumn(viewer, "checked",
- 20);
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- return null;
- }
-
- public Image getImage(Object element) {
- return null;
- }
- });
- // column.setEditingSupport(new RoleEditingSupport(rolesViewer, part));
-
- // role column
- column = createTableViewerColumn(viewer, "Role", 200);
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- Privilege p = (Privilege) element;
- return p.getName();
- }
-
- public Image getImage(Object element) {
- return null;
- }
- });
- viewer.setContentProvider(new RightsContentProvider());
- viewer.setInput(getEditorSite());
- }
-
- protected TableViewerColumn createTableViewerColumn(TableViewer viewer,
- String title, int bound) {
- final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
- SWT.NONE);
- final TableColumn column = viewerColumn.getColumn();
- column.setText(title);
- column.setWidth(bound);
- column.setResizable(true);
- column.setMoveable(true);
- return viewerColumn;
- }
-
- private class RightsContentProvider implements IStructuredContentProvider {
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- public Object[] getElements(Object inputElement) {
- try {
- AccessControlManager accessControlManager = currentNode
- .getSession().getAccessControlManager();
- Privilege[] privileges = accessControlManager
- .getPrivileges(currentNode.getPath());
- return privileges;
- } catch (Exception e) {
- throw new ArgeoException("Cannot retrieve rights", e);
- }
- }
-
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
-import javax.jcr.version.VersionManager;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.PropertyDiff;
-import org.argeo.jcr.VersionDiff;
-import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.providers.FullVersioningTreeContentProvider;
-import org.argeo.jcr.ui.explorer.providers.VersionLabelProvider;
-import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.AbstractFormPart;
-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.FormToolkit;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.eclipse.ui.forms.widgets.Section;
-import org.eclipse.ui.forms.widgets.TableWrapData;
-import org.eclipse.ui.forms.widgets.TableWrapLayout;
-
-/**
- * Offers two main sections : one to display a text area with a summary of all
- * variations between a version and its predecessor and one tree view that
- * enable browsing
- * */
-public class NodeVersionHistoryPage extends FormPage implements
- JcrExplorerConstants {
- // private final static Log log = LogFactory
- // .getLog(NodeVersionHistoryPage.class);
-
- // Utils
- protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
-
- // business objects
- private Node currentNode;
-
- // this page UI components
- private FullVersioningTreeContentProvider nodeContentProvider;
- private TreeViewer nodesViewer;
- private FormToolkit tk;
-
- public NodeVersionHistoryPage(FormEditor editor, String title,
- Node currentNode) {
- super(editor, "NodeVersionHistoryPage", title);
- this.currentNode = currentNode;
- }
-
- protected void createFormContent(IManagedForm managedForm) {
- ScrolledForm form = managedForm.getForm();
- form.setText(JcrExplorerPlugin
- .getMessage("nodeVersionHistoryPageTitle"));
- tk = managedForm.getToolkit();
- GridLayout twt = new GridLayout(1, false);
- twt.marginWidth = twt.marginHeight = 5;
- Composite body = form.getBody();
- body.setLayout(twt);
-
- try {
- if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) {
- tk.createLabel(body, JcrExplorerPlugin
- .getMessage("warningUnversionableNode"));
- } else {
- createHistorySection(form.getBody());
- createTreeSection(form.getBody());
- }
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected error while checking if node is versionable", e);
- }
- }
-
- protected void createTreeSection(Composite parent) {
- // Section Layout & MetaData
- Section section = tk.createSection(parent, Section.TWISTIE);
- section.setLayoutData(new GridData(GridData.FILL_BOTH));
- section.setText(JcrExplorerPlugin.getMessage("versionTreeSectionTitle"));
-
- // Section Body
- Composite body = tk.createComposite(section, SWT.FILL);
- // WARNING : 2 following lines are compulsory or body won't be
- // displayed.
- body.setLayout(new GridLayout());
- section.setClient(body);
-
- body.setLayoutData(new GridData(GridData.FILL_BOTH));
- section.setExpanded(true);
-
- nodeContentProvider = new FullVersioningTreeContentProvider();
- nodesViewer = createNodeViewer(body, nodeContentProvider);
- nodesViewer.setInput(currentNode);
- }
-
- protected TreeViewer createNodeViewer(Composite parent,
- final ITreeContentProvider nodeContentProvider) {
-
- final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
-
- tmpNodeViewer.getTree().setLayoutData(
- new GridData(SWT.FILL, SWT.FILL, true, true));
-
- tmpNodeViewer.setContentProvider(nodeContentProvider);
- tmpNodeViewer.setLabelProvider(new VersionLabelProvider());
- tmpNodeViewer
- .addDoubleClickListener(new GenericNodeDoubleClickListener(
- tmpNodeViewer));
- return tmpNodeViewer;
- }
-
- protected void createHistorySection(Composite parent) {
-
- // Section Layout
- Section section = tk.createSection(parent, Section.TWISTIE);
- section.setLayoutData(new GridData(TableWrapData.FILL_GRAB));
- TableWrapLayout twt = new TableWrapLayout();
- section.setLayout(twt);
-
- // Set title of the section
- section.setText(JcrExplorerPlugin
- .getMessage("versionHistorySectionTitle"));
-
- final Text styledText = tk.createText(section, "", SWT.FULL_SELECTION
- | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
- styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- section.setClient(styledText);
- refreshHistory(styledText);
- styledText.setEditable(false);
- section.setExpanded(false);
-
- AbstractFormPart part = new AbstractFormPart() {
- public void commit(boolean onSave) {
- }
-
- public void refresh() {
- super.refresh();
- refreshHistory(styledText);
- }
- };
- getManagedForm().addPart(part);
- }
-
- protected void refreshHistory(Text styledText) {
- try {
- List<VersionDiff> lst = listHistoryDiff();
- StringBuffer main = new StringBuffer("");
-
- for (int i = lst.size() - 1; i >= 0; i--) {
- if (i == 0)
- main.append("Creation (");
- else
- main.append("Update " + i + " (");
-
- if (lst.get(i).getUserId() != null)
- main.append("UserId : " + lst.get(i).getUserId());
-
- if (lst.get(i).getUserId() != null
- && lst.get(i).getUpdateTime() != null)
- main.append(", ");
-
- if (lst.get(i).getUpdateTime() != null)
- main.append("Date : "
- + timeFormatter.format(lst.get(i).getUpdateTime()
- .getTime()) + ")\n");
-
- StringBuffer buf = new StringBuffer("");
- Map<String, PropertyDiff> diffs = lst.get(i).getDiffs();
- for (String prop : diffs.keySet()) {
- PropertyDiff pd = diffs.get(prop);
- // String propName = pd.getRelPath();
- Value refValue = pd.getReferenceValue();
- Value newValue = pd.getNewValue();
- String refValueStr = "";
- String newValueStr = "";
-
- if (refValue != null) {
- if (refValue.getType() == PropertyType.DATE) {
- refValueStr = timeFormatter.format(refValue
- .getDate().getTime());
- } else
- refValueStr = refValue.getString();
- }
- if (newValue != null) {
- if (newValue.getType() == PropertyType.DATE) {
- newValueStr = timeFormatter.format(newValue
- .getDate().getTime());
- } else
- newValueStr = newValue.getString();
- }
-
- if (pd.getType() == PropertyDiff.MODIFIED) {
- buf.append(prop).append(": ");
- buf.append(refValueStr);
- buf.append(" > ");
- buf.append(newValueStr);
- buf.append("\n");
- } else if (pd.getType() == PropertyDiff.ADDED
- && !"".equals(newValueStr)) {
- // we don't list property that have been added with an
- // empty string as value
- buf.append(prop).append(": ");
- buf.append(" + ");
- buf.append(newValueStr);
- buf.append("\n");
- } else if (pd.getType() == PropertyDiff.REMOVED) {
- buf.append(prop).append(": ");
- buf.append(" - ");
- buf.append(refValueStr);
- buf.append("\n");
- }
- }
- buf.append("\n");
- main.append(buf);
- }
- styledText.setText(main.toString());
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot generate history for node", e);
- }
-
- }
-
- public List<VersionDiff> listHistoryDiff() {
- try {
- List<VersionDiff> res = new ArrayList<VersionDiff>();
- VersionManager versionManager = currentNode.getSession()
- .getWorkspace().getVersionManager();
- VersionHistory versionHistory = versionManager
- .getVersionHistory(currentNode.getPath());
-
- VersionIterator vit = versionHistory.getAllLinearVersions();
- while (vit.hasNext()) {
- Version version = vit.nextVersion();
- Node node = version.getFrozenNode();
- Version predecessor = null;
- try {
- predecessor = version.getLinearPredecessor();
- } catch (Exception e) {
- // no predecessor seems to throw an exception even if it
- // shouldn't...
- }
- if (predecessor == null) {// original
- } else {
- Map<String, PropertyDiff> diffs = JcrUtils.diffProperties(
- predecessor.getFrozenNode(), node);
- if (!diffs.isEmpty()) {
- String lastUserName = null;
- Calendar lastUpdate = null;
- try {
- if (currentNode
- .isNodeType(NodeType.MIX_LAST_MODIFIED)) {
- lastUserName = node.getProperty(
- Property.JCR_LAST_MODIFIED_BY)
- .getString();
- lastUpdate = node.getProperty(
- Property.JCR_LAST_MODIFIED).getDate();
- } else
- lastUpdate = version.getProperty(
- Property.JCR_CREATED).getDate();
-
- } catch (Exception e) {
- // Silent that info is optional
- }
- VersionDiff vd = new VersionDiff(lastUserName,
- lastUpdate, diffs);
- res.add(vd);
- }
- }
- }
- return res;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot generate history for node ");
- }
-
- }
-
- @Override
- public void setActive(boolean active) {
- super.setActive(active);
- }
-}
+++ /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.jcr.ui.explorer.editors;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-/**
- * An editor input based on three strings define a node :
- * <ul>
- * <li>complete path to the node</li>
- * <li>the workspace name</li>
- * <li>the repository alias</li>
- * </ul>
- * In a single workspace and/or repository environment, name and alias can be
- * null.
- *
- * Note : unused for the time being.
- */
-
-public class StringNodeEditorInput implements IEditorInput {
- private final String path;
- private final String repositoryAlias;
- private final String workspaceName;
-
- /**
- * In order to implement a generic explorer that supports remote and multi
- * workspaces repositories, node path can be detailed by these strings.
- *
- * @param repositoryAlias
- * : can be null
- * @param workspaceName
- * : can be null
- * @param path
- */
- public StringNodeEditorInput(String repositoryAlias, String workspaceName,
- String path) {
- this.path = path;
- this.repositoryAlias = repositoryAlias;
- this.workspaceName = workspaceName;
- }
-
- public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
- return null;
- }
-
- public boolean exists() {
- return true;
- }
-
- public ImageDescriptor getImageDescriptor() {
- return null;
- }
-
- public String getName() {
- return path;
- }
-
- public String getRepositoryAlias() {
- return repositoryAlias;
- }
-
- public String getWorkspaceName() {
- return workspaceName;
- }
-
- public IPersistableElement getPersistable() {
- return null;
- }
-
- public String getToolTipText() {
- return path;
- }
-
- public String getPath() {
- return path;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
-
- StringNodeEditorInput other = (StringNodeEditorInput) obj;
-
- if (!path.equals(other.getPath()))
- return false;
-
- String own = other.getWorkspaceName();
- if ((workspaceName == null && own != null)
- || (workspaceName != null && (own == null || !workspaceName
- .equals(own))))
- return false;
-
- String ora = other.getRepositoryAlias();
- if ((repositoryAlias == null && ora != null)
- || (repositoryAlias != null && (ora == null || !repositoryAlias
- .equals(ora))))
- return false;
-
- return true;
- }
-}
+++ /dev/null
-package org.argeo.jcr.ui.explorer.model;
-
-import javax.jcr.Repository;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.MaintainedRepository;
-
-/** Wraps a {@link MaintainedRepository} */
-public class MaintainedRepositoryElem extends RepositoryElem {
-
- public MaintainedRepositoryElem(String alias, Repository repository,
- TreeParent parent) {
- super(alias, repository, parent);
- if (!(repository instanceof MaintainedRepository)) {
- throw new ArgeoException("Repository " + alias
- + " is not amiantained repository");
- }
- }
-
- protected MaintainedRepository getMaintainedRepository() {
- return (MaintainedRepository) getRepository();
- }
-}
+++ /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.jcr.ui.explorer.model;
-
-import java.util.Arrays;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ArgeoJcrUtils;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.util.security.Keyring;
-
-/** Root of a remote repository */
-public class RemoteRepositoryElem extends RepositoryElem {
- private final Keyring keyring;
- /**
- * A session of the logged in user on the default workspace of the node
- * repository.
- */
- private final Session userSession;
- private final String remoteNodePath;
-
- private final RepositoryFactory repositoryFactory;
- private final String uri;
-
- public RemoteRepositoryElem(String alias,
- RepositoryFactory repositoryFactory, String uri, TreeParent parent,
- Session userSession, Keyring keyring, String remoteNodePath) {
- super(alias, null, parent);
- this.repositoryFactory = repositoryFactory;
- this.uri = uri;
- this.keyring = keyring;
- this.userSession = userSession;
- this.remoteNodePath = remoteNodePath;
- }
-
- @Override
- protected Session repositoryLogin(String workspaceName)
- throws RepositoryException {
- Node remoteRepository = userSession.getNode(remoteNodePath);
- String userID = remoteRepository.getProperty(ArgeoNames.ARGEO_USER_ID)
- .getString();
- String pwdPath = remoteRepository.getPath() + '/'
- + ArgeoNames.ARGEO_PASSWORD;
- char[] password = keyring.getAsChars(pwdPath);
-
- try {
- SimpleCredentials credentials = new SimpleCredentials(userID,
- password);
- return getRepository().login(credentials, workspaceName);
- } finally {
- Arrays.fill(password, 0, password.length, ' ');
- }
- }
-
- @Override
- public Repository getRepository() {
- if (repository == null)
- repository = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory,
- uri);
- return super.getRepository();
- }
-
- public void remove() {
- try {
- Node remoteNode = userSession.getNode(remoteNodePath);
- remoteNode.remove();
- remoteNode.getSession().save();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot remove " + remoteNodePath, e);
- }
- }
-
-}
+++ /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.jcr.ui.explorer.model;
-
-import java.util.Map;
-
-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.ArgeoException;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.MaintainedRepository;
-import org.argeo.jcr.RepositoryRegister;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.util.security.Keyring;
-
-/**
- * UI Tree component. Implements the Argeo abstraction of a
- * {@link RepositoryFactory} that enable a user to "mount" various repositories
- * in a single Tree like View. It is usually meant to be at the root of the UI
- * Tree and thus {@link getParent()} method will return null.
- *
- * The {@link RepositoryFactory} is injected at instantiation time and must be
- * use get or register new {@link Repository} objects upon which a reference is
- * kept here.
- */
-
-public class RepositoriesElem extends TreeParent implements ArgeoNames {
- private final RepositoryRegister repositoryRegister;
- private final RepositoryFactory repositoryFactory;
-
- /**
- * A session of the logged in user on the default workspace of the node
- * repository.
- */
- private final Session userSession;
- private final Keyring keyring;
-
- public RepositoriesElem(String name, RepositoryRegister repositoryRegister,
- RepositoryFactory repositoryFactory, TreeParent parent,
- Session userSession, Keyring keyring) {
- super(name);
- this.repositoryRegister = repositoryRegister;
- this.repositoryFactory = repositoryFactory;
- this.userSession = userSession;
- this.keyring = keyring;
- }
-
- /**
- * Override normal behavior to initialize the various repositories only at
- * request time
- */
- @Override
- public synchronized Object[] getChildren() {
- if (isLoaded()) {
- return super.getChildren();
- } else {
- // initialize current object
- Map<String, Repository> refRepos = repositoryRegister
- .getRepositories();
- for (String name : refRepos.keySet()) {
- Repository repository = refRepos.get(name);
- if (repository instanceof MaintainedRepository)
- super.addChild(new MaintainedRepositoryElem(name,
- repository, this));
- else
- super.addChild(new RepositoryElem(name, repository, this));
- }
-
- // remote
- if (keyring != null) {
- try {
- addRemoteRepositories(keyring);
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Cannot browse remote repositories", e);
- }
- }
- return super.getChildren();
- }
- }
-
- protected void addRemoteRepositories(Keyring jcrKeyring)
- throws RepositoryException {
- Node userHome = UserJcrUtils.getUserHome(userSession);
- if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) {
- NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes();
- while (it.hasNext()) {
- Node remoteNode = it.nextNode();
- String uri = remoteNode.getProperty(ARGEO_URI).getString();
- try {
- RemoteRepositoryElem remoteRepositoryNode = new RemoteRepositoryElem(
- remoteNode.getName(), repositoryFactory, uri, this,
- userSession, jcrKeyring, remoteNode.getPath());
- super.addChild(remoteRepositoryNode);
- } catch (Exception e) {
- ErrorFeedback.show("Cannot add remote repository "
- + remoteNode, e);
- }
- }
- }
- }
-
- public void registerNewRepository(String alias, Repository repository) {
- // TODO: implement this
- // Create a new RepositoryNode Object
- // add it
- // super.addChild(new RepositoriesNode(...));
- }
-
- /** Returns the {@link RepositoryRegister} wrapped by this object. */
- public RepositoryRegister getRepositoryRegister() {
- return repositoryRegister;
- }
-}
+++ /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.jcr.ui.explorer.model;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-
-/**
- * UI Tree component. Wraps a JCR {@link Repository}. It also keeps a reference
- * to its parent Tree Ui component; typically the unique {@link Repositories}
- * object of the current view to enable bi-directionnal browsing in the tree.
- */
-
-public class RepositoryElem extends TreeParent {
- private String alias;
- protected Repository repository;
- private Session defaultSession = null;
-
- /** Create a new repository with distinct name & alias */
- public RepositoryElem(String alias, Repository repository, TreeParent parent) {
- super(alias);
- this.repository = repository;
- setParent(parent);
- this.alias = alias;
- }
-
- public void login() {
- try {
- defaultSession = repositoryLogin(null);
- String[] wkpNames = defaultSession.getWorkspace()
- .getAccessibleWorkspaceNames();
- for (String wkpName : wkpNames) {
- if (wkpName.equals(defaultSession.getWorkspace().getName()))
- addChild(new WorkspaceElem(this, wkpName, defaultSession));
- else
- addChild(new WorkspaceElem(this, wkpName));
- }
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot connect to repository " + alias, e);
- }
- }
-
- /**
- * Actual call to the
- * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
- * overridden.
- */
- protected Session repositoryLogin(String workspaceName)
- throws RepositoryException {
- return repository.login(workspaceName);
- }
-
- public String[] getAccessibleWorkspaceNames() {
- try {
- return defaultSession.getWorkspace().getAccessibleWorkspaceNames();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot retrieve workspace names", e);
- }
- }
-
- public void createWorkspace(String workspaceName) {
- if (!isConnected())
- login();
- try {
- defaultSession.getWorkspace().createWorkspace(workspaceName);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot create workspace", e);
- }
- }
-
- /** returns the {@link Repository} referenced by the current UI Node */
- public Repository getRepository() {
- return repository;
- }
-
- public String getAlias() {
- return alias;
- }
-
- public Boolean isConnected() {
- if (defaultSession != null && defaultSession.isLive())
- return true;
- else
- return false;
- }
-}
+++ /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.jcr.ui.explorer.model;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Workspace;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-
-/**
- * UI Tree component. Wraps a node of a JCR {@link Workspace}. It also keeps a
- * reference to its parent node that can either be a {@link WorkspaceElem}, a
- * {@link SingleJcrNodeElem} or null if the node is "mounted" as the root of the UI
- * tree.
- */
-
-public class SingleJcrNodeElem extends TreeParent {
-
- private final Node node;
- private String alias = null;
-
- // keeps a local reference to the node's name to avoid exception when the
- // session is lost
- // private final String name;
-
- /** Creates a new UiNode in the UI Tree */
- public SingleJcrNodeElem(TreeParent parent, Node node, String name) {
- super(name);
- setParent(parent);
- this.node = node;
- }
-
- /**
- * Creates a new UiNode in the UI Tree, keeping a reference to the alias of
- * the corresponding repository in the current UI environment. It is useful
- * to be able to mount nodes as roots of the UI tree.
- */
- public SingleJcrNodeElem(TreeParent parent, Node node, String name, String alias) {
- super(name);
- setParent(parent);
- this.node = node;
- this.alias = alias;
- }
-
- /** returns the node wrapped by the current Ui object */
- public Node getNode() {
- return node;
- }
-
- protected String getRepositoryAlias() {
- return alias;
- }
-
- /**
- * Override normal behavior to initialize children only when first requested
- */
- @Override
- public synchronized Object[] getChildren() {
- if (isLoaded()) {
- return super.getChildren();
- } else {
- // initialize current object
- try {
- NodeIterator ni = node.getNodes();
- while (ni.hasNext()) {
- Node curNode = ni.nextNode();
- addChild(new SingleJcrNodeElem(this, curNode, curNode.getName()));
- }
- return super.getChildren();
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexcpected error while initializing children SingleJcrNode",
- re);
- }
- }
- }
-
- @Override
- public boolean hasChildren() {
- try {
- if (node.getSession().isLive())
- return node.hasNodes();
- else
- return false;
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while checking children node existence",
- re);
- }
- }
-
-}
+++ /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.jcr.ui.explorer.model;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Workspace;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also
- * keeps a reference to its parent {@link RepositoryElem}, to be able to
- * retrieve alias of the current used repository
- */
-public class WorkspaceElem extends TreeParent {
- private Session session = null;
-
- public WorkspaceElem(RepositoryElem parent, String name) {
- this(parent, name, null);
- }
-
- public WorkspaceElem(RepositoryElem parent, String name, Session session) {
- super(name);
- this.session = session;
- setParent(parent);
- }
-
- public Session getSession() {
- return session;
- }
-
- public Node getRootNode() {
- try {
- if (session != null)
- return session.getRootNode();
- else
- return null;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot get root node of workspace "
- + getName(), e);
- }
- }
-
- public void login() {
- try {
- session = ((RepositoryElem) getParent()).repositoryLogin(getName());
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot connect to repository "
- + getName(), e);
- }
- }
-
- public Boolean isConnected() {
- if (session != null && session.isLive())
- return true;
- else
- return false;
- }
-
- @Override
- public synchronized void dispose() {
- logout();
- super.dispose();
- }
-
- /** Logouts the session, does not nothing if there is no live session. */
- public void logout() {
- clearChildren();
- JcrUtils.logoutQuietly(session);
- }
-
- @Override
- public boolean hasChildren() {
- try {
- if (isConnected())
- return session.getRootNode().hasNodes();
- else
- return false;
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while checking children node existence",
- re);
- }
- }
-
- /** Override normal behaviour to initialize display of the workspace */
- @Override
- public synchronized Object[] getChildren() {
- if (isLoaded()) {
- return super.getChildren();
- } else {
- // initialize current object
- try {
- Node rootNode;
- if (session == null)
- return null;
- else
- rootNode = session.getRootNode();
- NodeIterator ni = rootNode.getNodes();
- while (ni.hasNext()) {
- Node node = ni.nextNode();
- addChild(new SingleJcrNodeElem(this, node, node.getName()));
- }
- return super.getChildren();
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Cannot initialize WorkspaceNode UI object."
- + getName(), e);
- }
- }
- }
-}
+++ /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.jcr.ui.explorer.providers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
-import javax.jcr.version.VersionManager;
-
-import org.argeo.ArgeoException;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Implementation of the {@code ITreeContentProvider} in order to display some
- * version informations of a JCR full versionable node in a tree like structure
- *
- */
-public class FullVersioningTreeContentProvider implements ITreeContentProvider {
- // private Node rootNode;
- // private ItemComparator itemComparator = new ItemComparator();
-
- /**
- * Sends back the first level of the Tree. input element must be a single
- * node object
- */
- public Object[] getElements(Object inputElement) {
- try {
- Node rootNode = (Node) inputElement;
- String curPath = rootNode.getPath();
- VersionManager vm = rootNode.getSession().getWorkspace()
- .getVersionManager();
-
- VersionHistory vh = vm.getVersionHistory(curPath);
- List<Version> result = new ArrayList<Version>();
- VersionIterator vi = vh.getAllLinearVersions();
-
- while (vi.hasNext()) {
- result.add(vi.nextVersion());
- }
- return result.toArray();
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while getting version elements", re);
- }
- }
-
- public Object[] getChildren(Object parentElement) {
- try {
- if (parentElement instanceof Version) {
- List<Node> tmp = new ArrayList<Node>();
- tmp.add(((Version) parentElement).getFrozenNode());
- return tmp.toArray();
- }
- } catch (RepositoryException re) {
- throw new ArgeoException("Unexpected error while getting child "
- + "node for version element", re);
- }
- return null;
- }
-
- public Object getParent(Object element) {
- try {
- // this will not work in a simpleVersionning environment, parent is
- // not a node.
- if (element instanceof Node
- && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) {
- Node node = (Node) element;
- return node.getParent();
- } else
- return null;
- } catch (RepositoryException e) {
- return null;
- }
- }
-
- public boolean hasChildren(Object element) {
- try {
- if (element instanceof Version)
- return true;
- else if (element instanceof Node)
- return ((Node) element).hasNodes();
- else
- return false;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot check children of " + element, e);
- }
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
-}
+++ /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.jcr.ui.explorer.providers;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ViewerCell;
-
-public class PropertyLabelProvider extends ColumnLabelProvider implements
- JcrExplorerConstants {
-
- // To be able to change column order easily
- public static final int COLUMN_PROPERTY = 0;
- public static final int COLUMN_VALUE = 1;
- public static final int COLUMN_ATTRIBUTES = 2;
-
- // Utils
- protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
-
- public void update(ViewerCell cell) {
- Object element = cell.getElement();
- cell.setText(getColumnText(element, cell.getColumnIndex()));
- // Image image = getImage(element);
- // cell.setImage(image);
- // cell.setBackground(getBackground(element));
- // cell.setForeground(getForeground(element));
- // cell.setFont(getFont(element));
- }
-
- public String getColumnText(Object element, int columnIndex) {
- try {
- if (element instanceof Property) {
- Property prop = (Property) element;
- if (prop.isMultiple()) {
- switch (columnIndex) {
- case COLUMN_PROPERTY:
- return prop.getName();
- case COLUMN_VALUE:
- // Corresponding values are listed on children
- return "";
- case COLUMN_ATTRIBUTES:
- return JcrUtils.getPropertyDefinitionAsString(prop);
- }
- } else {
- switch (columnIndex) {
- case COLUMN_PROPERTY:
- return prop.getName();
- case COLUMN_VALUE:
- return formatValueAsString(prop.getValue());
- case COLUMN_ATTRIBUTES:
- return JcrUtils.getPropertyDefinitionAsString(prop);
- }
- }
- } else if (element instanceof Value) {
- Value val = (Value) element;
-
- switch (columnIndex) {
- case COLUMN_PROPERTY:
- // Nothing to show
- return "";
- case COLUMN_VALUE:
- return formatValueAsString(val);
- case COLUMN_ATTRIBUTES:
- // Corresponding attributes are listed on the parent
- return "";
- }
- }
-
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexepected error while getting property values", re);
- }
- return null;
- }
-
- private String formatValueAsString(Value value) {
- // TODO enhance this method
- try {
- String strValue;
-
- if (value.getType() == PropertyType.BINARY)
- strValue = "<binary>";
- else if (value.getType() == PropertyType.DATE)
- strValue = timeFormatter.format(value.getDate().getTime());
- else
- strValue = value.getString();
- return strValue;
- } catch (RepositoryException e) {
- throw new ArgeoException("unexpected error while formatting value",
- e);
- }
- }
-}
+++ /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.jcr.ui.explorer.providers;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Implementation of the {@code ITreeContentProvider} in order to display a
- * single JCR node and its children in a tree like structure
- *
- */
-public class SingleNodeAsTreeContentProvider implements ITreeContentProvider {
- // private Node rootNode;
- private JcrItemsComparator itemComparator = new JcrItemsComparator();
-
- /**
- * Sends back the first level of the Tree. input element must be a single
- * node object
- */
- public Object[] getElements(Object inputElement) {
- try {
- Node rootNode = (Node) inputElement;
- List<Node> result = new ArrayList<Node>();
- NodeIterator ni = rootNode.getNodes();
- while (ni.hasNext()) {
- result.add(ni.nextNode());
- }
-
- return result.toArray();
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while getting child nodes for children editor page ",
- re);
- }
- }
-
- public Object[] getChildren(Object parentElement) {
- return childrenNodes((Node) parentElement);
- }
-
- public Object getParent(Object element) {
- try {
- Node node = (Node) element;
- if (!node.getPath().equals("/"))
- return node.getParent();
- else
- return null;
- } catch (RepositoryException e) {
- return null;
- }
- }
-
- public boolean hasChildren(Object element) {
- try {
- return ((Node) element).hasNodes();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot check children of " + element, e);
- }
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- protected Object[] childrenNodes(Node parentNode) {
- try {
- List<Node> children = new ArrayList<Node>();
- NodeIterator nit = parentNode.getNodes();
- while (nit.hasNext()) {
- Node node = nit.nextNode();
- children.add(node);
- }
- Node[] arr = children.toArray(new Node[children.size()]);
- Arrays.sort(arr, itemComparator);
- return arr;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot list children of " + parentNode, e);
- }
- }
-}
+++ /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.jcr.ui.explorer.providers;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-
-import org.argeo.ArgeoException;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-
-/**
- * simple wrapping of the ColumnLabelProvider class to provide text display in
- * order to build a tree for version. The Get text method does not assume that
- * Version extends Node class to respect JCR 2.0 specification
- *
- */
-public class VersionLabelProvider extends ColumnLabelProvider {
-
- public String getText(Object element) {
- try {
- if (element instanceof Version) {
- Version version = (Version) element;
- return version.getName();
- } else if (element instanceof Node) {
- return ((Node) element).getName();
- }
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while getting element name", re);
- }
- return super.getText(element);
- }
-}
+++ /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.jcr.ui.explorer.utils;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.jcr.utils.JcrFileProvider;
-import org.argeo.eclipse.ui.specific.FileHandler;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.editors.GenericNodeEditor;
-import org.argeo.jcr.ui.explorer.editors.GenericNodeEditorInput;
-import org.argeo.jcr.ui.explorer.model.RepositoryElem;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.ui.PartInitException;
-
-/**
- * Centralizes the management of double click on a NodeTreeViewer
- */
-public class GenericNodeDoubleClickListener implements IDoubleClickListener {
-
- // private final static Log log = LogFactory
- // .getLog(GenericNodeDoubleClickListener.class);
-
- private TreeViewer nodeViewer;
- private JcrFileProvider jfp;
- private FileHandler fileHandler;
-
- public GenericNodeDoubleClickListener(TreeViewer nodeViewer) {
- this.nodeViewer = nodeViewer;
- jfp = new JcrFileProvider();
- // Commented out. see https://www.argeo.org/bugzilla/show_bug.cgi?id=188
- fileHandler = null;
- // fileHandler = new FileHandler(jfp);
- }
-
- public void doubleClick(DoubleClickEvent event) {
- if (event.getSelection() == null || event.getSelection().isEmpty())
- return;
- Object obj = ((IStructuredSelection) event.getSelection())
- .getFirstElement();
- if (obj instanceof RepositoryElem) {
- RepositoryElem rpNode = (RepositoryElem) obj;
- if (!rpNode.isConnected()) {
- rpNode.login();
- nodeViewer.refresh(obj);
- }
- // else do nothing
- } else if (obj instanceof WorkspaceElem) {
- WorkspaceElem wn = (WorkspaceElem) obj;
- if (wn.isConnected())
- wn.logout();
- else
- wn.login();
- nodeViewer.refresh(obj);
- } else if (obj instanceof SingleJcrNodeElem) {
- SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj;
- Node node = sjn.getNode();
- try {
- if (node.isNodeType(NodeType.NT_FILE)) {
- // double click on a file node triggers its opening
- String name = node.getName();
- String id = node.getIdentifier();
-
- // For the file provider to be able to browse the
- // various
- // repository.
- // TODO : enhanced that.
- // ITreeContentProvider itcp = (ITreeContentProvider)
- // nodeViewer
- // .getContentProvider();
- jfp.setReferenceNode(node);
- if (fileHandler != null)
- fileHandler.openFile(name, id);
- }
- GenericNodeEditorInput gnei = new GenericNodeEditorInput(node);
- JcrExplorerPlugin.getDefault().getWorkbench()
- .getActiveWorkbenchWindow().getActivePage()
- .openEditor(gnei, GenericNodeEditor.ID);
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Repository error while getting node info", re);
- } catch (PartInitException pie) {
- throw new ArgeoException(
- "Unexepected exception while opening node editor", pie);
- }
- }
- }
-}
+++ /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.jcr.ui.explorer.utils;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ui.explorer.model.RepositoriesElem;
-import org.argeo.jcr.ui.explorer.model.RepositoryElem;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
-
-/** Centralizes some useful methods to build UIs with JCR */
-public class JcrUiUtils {
-
- /** Insure that the UI component is not stale, refresh if needed */
- public static void forceRefreshIfNeeded(TreeParent element) {
- Node curNode = null;
-
- boolean doRefresh = false;
-
- try {
- if (element instanceof SingleJcrNodeElem) {
- curNode = ((SingleJcrNodeElem) element).getNode();
- } else if (element instanceof WorkspaceElem) {
- curNode = ((WorkspaceElem) element).getRootNode();
- }
-
- if (curNode != null
- && element.getChildren().length != curNode.getNodes()
- .getSize())
- doRefresh = true;
- else if (element instanceof RepositoryElem) {
- RepositoryElem rn = (RepositoryElem) element;
- if (rn.isConnected()) {
- String[] wkpNames = rn.getAccessibleWorkspaceNames();
- if (element.getChildren().length != wkpNames.length)
- doRefresh = true;
- }
- } else if (element instanceof RepositoriesElem) {
- doRefresh = true;
- // Always force refresh for RepositoriesElem : the condition
- // below does not take remote repository into account and it is
- // not trivial to do so.
-
- // RepositoriesElem rn = (RepositoriesElem) element;
- // if (element.getChildren().length !=
- // rn.getRepositoryRegister()
- // .getRepositories().size())
- // doRefresh = true;
- }
- if (doRefresh) {
- element.clearChildren();
- element.getChildren();
- }
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while synchronising the UI with the JCR repository",
- re);
- }
- }
-
- /**
- * Insure that a model element is inline with the underlying data by
- * cleaning the corresponding subtree and building it again.
- */
- public static void forceRebuild(TreeParent element) {
- // TODO implement this method if needed.
- }
- /**
- * Workaround to get the alias of the repository that contains the given
- * element. As we cannot browse the UI tree upward we recursively browse it
- * downward until we find the given element
- * */
- // public static String getRepositoryAliasFromITreeElement(
- // NodeContentProvider ncp, Object element) {
- // RepositoryNode repositoryNode = null;
- // if (element instanceof RepositoryNode)
- // return ((RepositoryNode) element).getName();
- // else if (element instanceof RepositoryRegister)
- // throw new ArgeoException(
- // "Cannot get alias for a repository register");
- //
- // // Get root elements
- // Object[] elements = ncp.getElements(null);
- //
- // try {
- // for (int i = 0; i < elements.length; i++) {
- // if (elements[i] instanceof Node) {
- // Node curNode = (Node) elements[i];
- // if (curNode.isNodeType(ArgeoTypes.ARGEO_USER_HOME)) {
- // // Do nothing, we'll find the node in the "normal" tree
- // // and
- // // get corresponding alias this way round
- // } else
- // throw new ArgeoException(
- // "Normal nodes should not be at the root of NodeTreeViewer");
- // } else if (elements[i] instanceof RepositoryRegister) {
- // RepositoryRegister repositoryRegister = (RepositoryRegister) elements[i];
- // Map<String, Repository> repositories = repositoryRegister
- // .getRepositories();
- //
- // for (String name : repositories.keySet()) {
- // boolean found = isElementInCurrentTreePart(
- // ncp,
- // new RepositoryNode(name, repositories.get(name)),
- // (Node) element);
- // if (found)
- // return name;
- // }
- // } else
- // throw new ArgeoException(
- // "Unexpected object class at the root of NodeTreeViewer");
- // }
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Unexpected error while retrieving Alias name", re);
- // }
- // return null;
- // }
- //
- // /** implements the recursivity */
- // private static boolean isElementInCurrentTreePart(NodeContentProvider
- // ncp,
- // Object parentElement, NodParente searchedElement) {
- // boolean found = false;
- // if (parentElement instanceof WorkspaceNode) {
- // WorkspaceNode wn = (WorkspaceNode) parentElement;
- // Object[] children = wn.getChildren();
- // int i = children.length - 1;
- // while (!found && i >= 0) {
- // found = isElementInCurrentTreePart(ncp, children[i],
- // searchedElement);
- // }
- // return found;
- // } else if (parentElement instanceof RepositoryNode) {
- // RepositoryNode rn = (RepositoryNode) parentElement;
- // Object[] children = rn.getChildren();
- // int i = children.length - 1;
- // while (!found && i >= 0) {
- // found = isElementInCurrentTreePart(ncp, children[i],
- // searchedElement);
- // }
- // return found;
- // } else {
- // Node node = (Node) parentElement;
- // if (node.equals(searchedElement))
- // return true;
- // NodeIterator ni;
- // try {
- // ni = node.getNodes();
- // while (!found && ni.hasNext()) {
- // found = isElementInCurrentTreePart(ncp, ni.nextNode(),
- // searchedElement);
- // }
- // } catch (RepositoryException e) {
- // throw new ArgeoException("unexpected erreur while recursively"
- // + " recovering RepositoryNode for selected object", e);
- // }
- //
- // return found;
- // }
- // }
-}
+++ /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.jcr.ui.explorer.utils;
-
-import java.util.Comparator;
-
-import org.argeo.eclipse.ui.TreeParent;
-
-public class TreeObjectsComparator implements Comparator<TreeParent> {
- public int compare(TreeParent o1, TreeParent o2) {
- return o1.getName().compareTo(o2.getName());
- }
-}
\ 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.jcr.ui.explorer.views;
-
-import java.util.List;
-
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventListener;
-import javax.jcr.observation.ObservationManager;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
-import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer;
-import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser;
-import org.argeo.jcr.RepositoryRegister;
-import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
-import org.argeo.jcr.ui.explorer.browser.NodeContentProvider;
-import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
-import org.argeo.jcr.ui.explorer.browser.PropertiesContentProvider;
-import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
-import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
-import org.argeo.jcr.ui.explorer.utils.JcrUiUtils;
-import org.argeo.util.security.Keyring;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Menu;
-
-/**
- * Basic View to display a sash form to browse a JCR compliant multirepository
- * environment
- */
-public class GenericJcrBrowser extends AbstractJcrBrowser {
- public final static String ID = JcrExplorerPlugin.ID + ".browserView";
- private boolean sortChildNodes = true;
-
- /* DEPENDENCY INJECTION */
- private Keyring keyring;
- private RepositoryRegister repositoryRegister;
- private RepositoryFactory repositoryFactory;
- private Repository nodeRepository;
- /**
- * A session of the logged in user on the default workspace of the node
- * repository.
- */
- private Session userSession;
-
- // This page widgets
- private TreeViewer nodesViewer;
- private NodeContentProvider nodeContentProvider;
- private TableViewer propertiesViewer;
- private EventListener resultsObserver;
-
- @Override
- public void createPartControl(Composite parent) {
- parent.setLayout(new FillLayout());
- SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
- sashForm.setSashWidth(4);
- sashForm.setLayout(new FillLayout());
-
- // Create the tree on top of the view
- Composite top = new Composite(sashForm, SWT.NONE);
- GridLayout gl = new GridLayout(1, false);
- top.setLayout(gl);
-
- try {
- this.userSession = this.nodeRepository.login();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot open user session", e);
- }
-
- nodeContentProvider = new NodeContentProvider(userSession, keyring,
- repositoryRegister, repositoryFactory, sortChildNodes);
-
- // nodes viewer
- nodesViewer = createNodeViewer(top, nodeContentProvider);
-
- // context menu : it is completely defined in the plugin.xml file.
- MenuManager menuManager = new MenuManager();
- Menu menu = menuManager.createContextMenu(nodesViewer.getTree());
-
- nodesViewer.getTree().setMenu(menu);
- getSite().registerContextMenu(menuManager, nodesViewer);
- getSite().setSelectionProvider(nodesViewer);
-
- nodesViewer.setInput(getViewSite());
-
- // Create the property viewer on the bottom
- Composite bottom = new Composite(sashForm, SWT.NONE);
- bottom.setLayout(new GridLayout(1, false));
- propertiesViewer = createPropertiesViewer(bottom);
-
- sashForm.setWeights(getWeights());
- nodesViewer.setComparer(new NodeViewerComparer());
- }
-
- @Override
- public void refresh(Object obj) {
- // Enable full refresh from a command when no element of the tree is
- // selected
- if (obj == null) {
- Object[] elements = nodeContentProvider.getElements(null);
- for (Object el : elements) {
- if (el instanceof TreeParent)
- JcrUiUtils.forceRefreshIfNeeded((TreeParent) el);
- getNodeViewer().refresh(el);
- }
- }
- super.refresh(obj);
- }
-
- /**
- * To be overridden to adapt size of form and result frames.
- */
- protected int[] getWeights() {
- return new int[] { 70, 30 };
- }
-
- protected TreeViewer createNodeViewer(Composite parent,
- final ITreeContentProvider nodeContentProvider) {
-
- final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
-
- tmpNodeViewer.getTree().setLayoutData(
- new GridData(SWT.FILL, SWT.FILL, true, true));
-
- tmpNodeViewer.setContentProvider(nodeContentProvider);
- tmpNodeViewer.setLabelProvider(new NodeLabelProvider());
- tmpNodeViewer
- .addSelectionChangedListener(new ISelectionChangedListener() {
- public void selectionChanged(SelectionChangedEvent event) {
- if (!event.getSelection().isEmpty()) {
- IStructuredSelection sel = (IStructuredSelection) event
- .getSelection();
- Object firstItem = sel.getFirstElement();
- if (firstItem instanceof SingleJcrNodeElem)
- propertiesViewer
- .setInput(((SingleJcrNodeElem) firstItem)
- .getNode());
- } else {
- propertiesViewer.setInput(getViewSite());
- }
- }
- });
-
- resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay());
- if (keyring != null)
- try {
- ObservationManager observationManager = userSession
- .getWorkspace().getObservationManager();
- observationManager.addEventListener(resultsObserver,
- Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/",
- true, null, null, false);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot register listeners", e);
- }
-
- tmpNodeViewer
- .addDoubleClickListener(new GenericNodeDoubleClickListener(
- tmpNodeViewer));
- return tmpNodeViewer;
- }
-
- protected TableViewer createPropertiesViewer(Composite parent) {
- propertiesViewer = new TableViewer(parent);
- propertiesViewer.getTable().setLayoutData(
- new GridData(SWT.FILL, SWT.FILL, true, true));
- propertiesViewer.getTable().setHeaderVisible(true);
- propertiesViewer.setContentProvider(new PropertiesContentProvider());
- TableViewerColumn col = new TableViewerColumn(propertiesViewer,
- SWT.NONE);
- col.getColumn().setText("Name");
- col.getColumn().setWidth(200);
- col.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- try {
- return ((Property) element).getName();
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception in label provider", e);
- }
- }
- });
- col = new TableViewerColumn(propertiesViewer, SWT.NONE);
- col.getColumn().setText("Value");
- col.getColumn().setWidth(400);
- col.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- try {
- Property property = (Property) element;
- if (property.getType() == PropertyType.BINARY)
- return "<binary>";
- else if (property.isMultiple()) {
- StringBuffer buf = new StringBuffer("[");
- Value[] values = property.getValues();
- for (int i = 0; i < values.length; i++) {
- if (i != 0)
- buf.append(", ");
- buf.append(values[i].getString());
- }
- buf.append(']');
- return buf.toString();
- } else
- return property.getValue().getString();
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception in label provider", e);
- }
- }
- });
- col = new TableViewerColumn(propertiesViewer, SWT.NONE);
- col.getColumn().setText("Type");
- col.getColumn().setWidth(200);
- col.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- try {
- return PropertyType.nameFromValue(((Property) element)
- .getType());
- } catch (RepositoryException e) {
- throw new ArgeoException(
- "Unexpected exception in label provider", e);
- }
- }
- });
- propertiesViewer.setInput(getViewSite());
- return propertiesViewer;
- }
-
- @Override
- public void dispose() {
- super.dispose();
- }
-
- @Override
- protected TreeViewer getNodeViewer() {
- return nodesViewer;
- }
-
- /**
- * Resets the tree content provider
- *
- * @param sortChildNodes
- * if true the content provider will use a comparer to sort nodes
- * that might slow down the display
- * */
- public void setSortChildNodes(boolean sortChildNodes) {
- this.sortChildNodes = sortChildNodes;
- ((NodeContentProvider) nodesViewer.getContentProvider())
- .setSortChildren(sortChildNodes);
- nodesViewer.setInput(getViewSite());
- }
-
- /** Notifies the current view that a node has been added */
- public void nodeAdded(TreeParent parentNode) {
- // insure that Ui objects have been correctly created:
- JcrUiUtils.forceRefreshIfNeeded(parentNode);
- getNodeViewer().refresh(parentNode);
- getNodeViewer().expandToLevel(parentNode, 1);
- }
-
- /** Notifies the current view that a node has been removed */
- public void nodeRemoved(TreeParent parentNode) {
- IStructuredSelection newSel = new StructuredSelection(parentNode);
- getNodeViewer().setSelection(newSel, true);
- // Force refresh
- IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer()
- .getSelection();
- getNodeViewer().refresh(tmpSel.getFirstElement());
- }
-
- class TreeObserver extends AsyncUiEventListener {
-
- public TreeObserver(Display display) {
- super(display);
- }
-
- @Override
- protected Boolean willProcessInUiThread(List<Event> events)
- throws RepositoryException {
- for (Event event : events) {
- if (getLog().isTraceEnabled())
- getLog().debug("Received event " + event);
- String path = event.getPath();
- int index = path.lastIndexOf('/');
- String propertyName = path.substring(index + 1);
- if (getLog().isTraceEnabled())
- getLog().debug("Concerned property " + propertyName);
- }
- return false;
- }
-
- protected void onEventInUiThread(List<Event> events)
- throws RepositoryException {
- if (getLog().isTraceEnabled())
- getLog().trace("Refresh result list");
- nodesViewer.refresh();
- }
-
- }
-
- public boolean getSortChildNodes() {
- return sortChildNodes;
- }
-
- /* DEPENDENCY INJECTION */
- public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
- this.repositoryRegister = repositoryRegister;
- }
-
- public void setKeyring(Keyring keyring) {
- this.keyring = keyring;
- }
-
- public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
- this.repositoryFactory = repositoryFactory;
- }
-
- public void setNodeRepository(Repository nodeRepository) {
- this.nodeRepository = nodeRepository;
- }
-
-}
+++ /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.jcr.ui.explorer.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;
- private String path;
-
- // This page widget
- private ChooseRightsPage page;
-
- public ChangeRightsWizard(Session currentSession, String path) {
- super();
- this.currentSession = currentSession;
- this.path = path;
- }
-
- @Override
- public void addPages() {
- try {
- page = new ChooseRightsPage(path);
- 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, path, page.getGroupName(),
- page.getAuthTypeStr());
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unexpected error while setting privileges", re);
- }
- return true;
- }
-}
+++ /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.jcr.ui.explorer.wizards;
-
-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;
-
- // USABLE SHORTCUTS
- protected final static String[] validAuthType = { Privilege.JCR_READ,
- Privilege.JCR_WRITE, Privilege.JCR_ALL };
-
- public ChooseRightsPage(String path) {
- super("Main");
- setTitle("Add privilege to " + path);
- }
-
- 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());
- }
-
- 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 the name of the corresponding group.";
- // Remove regexp check for the time being.
- // else if (!match(groupStr))
- // return
- // "Please use only alphanumerical chars for the short technical name.";
- return null;
- }
-}
+++ /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.jcr.ui.explorer.wizards;
-
-import java.io.File;
-import java.io.FileInputStream;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-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.eclipse.ui.specific.ImportToServerWizardPage;
-import org.argeo.eclipse.ui.specific.UploadFileWizardPage;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.wizard.Wizard;
-
-public class ImportFileSystemWizard extends Wizard {
- private final static Log log = LogFactory
- .getLog(ImportFileSystemWizard.class);
-
- private UploadFileWizardPage importPage;
- private final Node folder;
-
- public ImportFileSystemWizard(Node folder) {
- this.folder = folder;
- setWindowTitle("Import from file system");
- }
-
- @Override
- public void addPages() {
- importPage = new UploadFileWizardPage();
- addPage(importPage);
- setNeedsProgressMonitor(importPage.getNeedsProgressMonitor());
- }
-
- /**
- * Called when the user click on 'Finish' in the wizard. The real upload to
- * the JCR repository is done here.
- */
- @Override
- public boolean performFinish() {
-
- // Initialization
- final String objectType = importPage.getObjectType();
- final String objectPath = importPage.getObjectPath();
-
- // We do not display a progress bar for one file only
- if (ImportToServerWizardPage.FILE_ITEM_TYPE.equals(objectType)) {
- // In Rap we must force the "real" upload of the file
- importPage.performFinish();
- try {
- Node fileNode = folder.addNode(importPage.getObjectName(),
- NodeType.NT_FILE);
- Node resNode = fileNode.addNode(Property.JCR_CONTENT,
- NodeType.NT_RESOURCE);
- Binary binary = null;
- try {
- binary = folder.getSession().getValueFactory()
- .createBinary(importPage.getFileInputStream());
- resNode.setProperty(Property.JCR_DATA, binary);
- } finally {
- if (binary != null)
- binary.dispose();
- IOUtils.closeQuietly(importPage.getFileInputStream());
- }
- folder.getSession().save();
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- return true;
- } else if (ImportToServerWizardPage.FOLDER_ITEM_TYPE.equals(objectType)) {
- if (objectPath == null || !new File(objectPath).exists()) {
- ErrorFeedback.show("Directory " + objectPath
- + " does not exist");
- return false;
- }
-
- Boolean failed = false;
- final File dir = new File(objectPath).getAbsoluteFile();
- final Long sizeB = directorySize(dir, 0l);
- final Stats stats = new Stats();
- Long begin = System.currentTimeMillis();
- try {
- getContainer().run(true, true, new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor) {
- try {
- Integer sizeKB = (int) (sizeB / FileUtils.ONE_KB);
- monitor.beginTask("", sizeKB);
- importDirectory(folder, dir, monitor, stats);
- monitor.done();
- } catch (Exception e) {
- if (e instanceof RuntimeException)
- throw (RuntimeException) e;
- else
- throw new ArgeoException("Cannot import "
- + objectPath, e);
- }
- }
- });
- } catch (Exception e) {
- ErrorFeedback.show("Cannot import " + objectPath, e);
- failed = true;
- }
-
- Long duration = System.currentTimeMillis() - begin;
- Long durationS = duration / 1000l;
- String durationStr = (durationS / 60) + " min " + (durationS % 60)
- + " s";
- StringBuffer message = new StringBuffer("Imported\n");
- message.append(stats.fileCount).append(" files\n");
- message.append(stats.dirCount).append(" directories\n");
- message.append(FileUtils.byteCountToDisplaySize(stats.sizeB));
- if (failed)
- message.append(" of planned ").append(
- FileUtils.byteCountToDisplaySize(sizeB));
- message.append("\n");
- message.append("in ").append(durationStr).append("\n");
- if (failed)
- MessageDialog.openError(getShell(), "Import failed",
- message.toString());
- else
- MessageDialog.openInformation(getShell(), "Import successful",
- message.toString());
-
- return true;
- }
- return false;
-
- }
-
- /** Recursively computes the size of the directory in bytes. */
- protected Long directorySize(File dir, Long currentSize) {
- Long size = currentSize;
- File[] files = dir.listFiles();
- for (File file : files) {
- if (file.isDirectory()) {
- size = directorySize(file, size);
- } else {
- size = size + file.length();
- }
- }
- return size;
- }
-
- /**
- * Import recursively a directory and its content to the repository.
- */
- protected void importDirectory(Node folder, File dir,
- IProgressMonitor monitor, Stats stats) {
- try {
- File[] files = dir.listFiles();
- for (File file : files) {
- if (file.isDirectory()) {
- Node childFolder = folder.addNode(file.getName(),
- NodeType.NT_FOLDER);
- importDirectory(childFolder, file, monitor, stats);
- folder.getSession().save();
- stats.dirCount++;
- } else {
- Long fileSize = file.length();
-
- // we skip tempory files that are created by apps when a
- // file is being edited.
- // TODO : make this configurable.
- if (file.getName().lastIndexOf('~') != file.getName()
- .length() - 1) {
-
- monitor.subTask(file.getName() + " ("
- + FileUtils.byteCountToDisplaySize(fileSize)
- + ") " + file.getCanonicalPath());
- try {
- Node fileNode = folder.addNode(file.getName(),
- NodeType.NT_FILE);
- Node resNode = fileNode.addNode(
- Property.JCR_CONTENT, NodeType.NT_RESOURCE);
- Binary binary = null;
- try {
- binary = folder
- .getSession()
- .getValueFactory()
- .createBinary(new FileInputStream(file));
- resNode.setProperty(Property.JCR_DATA, binary);
- } finally {
- if (binary != null)
- binary.dispose();
- }
- folder.getSession().save();
- stats.fileCount++;
- stats.sizeB = stats.sizeB + fileSize;
- } catch (Exception e) {
- log.warn("Import of "
- + file
- + " ("
- + FileUtils
- .byteCountToDisplaySize(fileSize)
- + ") failed: " + e);
- folder.getSession().refresh(false);
- }
- monitor.worked((int) (fileSize / FileUtils.ONE_KB));
- }
- }
- }
- } catch (Exception e) {
- throw new ArgeoException("Cannot import " + dir + " to " + folder,
- e);
- }
- }
-
- static class Stats {
- public Long fileCount = 0l;
- public Long dirCount = 0l;
- public Long sizeB = 0l;
- }
-}
+++ /dev/null
-## English labels for Agreo JCR UI application
-
-## Generic labels
-
-## Errors & warnings
-errorUnvalidNtFolderNodeType= Error: folder can only be created on a Jcr Node
-warningInvalidNodeToImport=Can only import to a node
-warningInvalidMultipleSelection=This functionality is implemented only on a single node for the time being.
-warningUnversionableNode= Current node is not versionable.
-warningNoChildNode= Current node has no child.
-
-## Commands
-getNodeSizeCmdLbl= Get approx. size
-addFolderNodeCmdLbl= Add Folder
-
-## GenericNodeEditor
-nodeEditorLbl=Generic node editor
-genericNodePageTitle=Properties
-childNodesPageTitle=Children
-nodeRightsManagementPageTitle=Rights
-nodeVersionHistoryPageTitle=History
-
-# History
-versionTreeSectionTitle=Version list
-versionHistorySectionTitle=History
-
-## Dummy ones
-testLbl=Internationalizations of messages seems to work properly.
--- /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.jcr.ui.explorer;
+
+/** Constants used across the application. */
+public interface JcrExplorerConstants {
+ /*
+ * MISCEALLENEOUS
+ */
+ public final static String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm";
+
+ public final static String PARAM_PATH = "org.argeo.jcr.ui.explorer.nodePath";
+
+}
--- /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.jcr.ui.explorer;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/** Base perspective for JcrExplorer browser */
+public class JcrExplorerPerspective implements IPerspectiveFactory {
+ public static String BROWSER_VIEW_ID = JcrExplorerPlugin.ID
+ + ".browserView";
+
+ public void createInitialLayout(IPageLayout layout) {
+ layout.setEditorAreaVisible(true);
+
+ IFolderLayout upperLeft = layout.createFolder(JcrExplorerPlugin.ID
+ + ".upperLeft", IPageLayout.LEFT, 0.4f, layout.getEditorArea());
+ upperLeft.addView(BROWSER_VIEW_ID);
+
+// String editorArea = layout.getEditorArea();
+// String logViewId = "org.argeo.security.ui.logView";
+// IFolderLayout bottom = layout.createFolder("bottom",
+// IPageLayout.BOTTOM, 0.50f, editorArea);
+// bottom.addView(logViewId);
+ }
+
+}
--- /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.jcr.ui.explorer;
+
+import java.util.ResourceBundle;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class JcrExplorerPlugin extends AbstractUIPlugin {
+ private final static Log log = LogFactory.getLog(JcrExplorerPlugin.class);
+ private ResourceBundle messages;
+
+ // The plug-in ID
+ public static final String ID = "org.argeo.jcr.ui.explorer"; //$NON-NLS-1$
+
+ // The shared instance
+ private static JcrExplorerPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public JcrExplorerPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ messages = ResourceBundle
+ .getBundle("org.argeo.jcr.ui.explorer.messages");
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static JcrExplorerPlugin getDefault() {
+ return plugin;
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(ID, path);
+ }
+
+ /** Returns the internationalized label for the given key */
+ public static String getMessage(String key) {
+ try {
+ return getDefault().messages.getString(key);
+ } catch (NullPointerException npe) {
+ log.warn(key + " not found.");
+ return key;
+ }
+ }
+
+ /**
+ * Gives access to the internationalization message bundle. Returns null in
+ * case the ClientUiPlugin is not started (for JUnit tests, by instance)
+ */
+ public static ResourceBundle getMessagesBundle() {
+ if (getDefault() != null)
+ // To avoid NPE
+ return getDefault().messages;
+ else
+ return null;
+ }
+
+}
--- /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.jcr.ui.explorer;
+
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+
+public class JcrExplorerView extends GenericJcrBrowser {
+
+}
--- /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.jcr.ui.explorer.browser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.RepositoryRegister;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.jcr.ui.explorer.model.RepositoriesElem;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.util.security.Keyring;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Implementation of the {@code ITreeContentProvider} to display multiple
+ * repository environment in a tree like structure
+ *
+ */
+public class NodeContentProvider implements ITreeContentProvider {
+ final private RepositoryRegister repositoryRegister;
+ final private RepositoryFactory repositoryFactory;
+ /**
+ * A session of the logged in user on the default workspace of the node
+ * repository.
+ */
+ final private Session userSession;
+ final private Keyring keyring;
+ private boolean sortChildren;
+
+ // reference for cleaning
+ private SingleJcrNodeElem homeNode = null;
+ private RepositoriesElem repositoriesNode = null;
+
+ // Utils
+ private TreeBrowserComparator itemComparator = new TreeBrowserComparator();
+
+ public NodeContentProvider(Session userSession, Keyring keyring,
+ RepositoryRegister repositoryRegister,
+ RepositoryFactory repositoryFactory, Boolean sortChildren) {
+ this.userSession = userSession;
+ this.keyring = keyring;
+ this.repositoryRegister = repositoryRegister;
+ this.repositoryFactory = repositoryFactory;
+ this.sortChildren = sortChildren;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput == null)// dispose
+ return;
+
+ if (userSession != null) {
+ Node userHome = UserJcrUtils.getUserHome(userSession);
+ if (userHome != null) {
+ // TODO : find a way to dynamically get alias for the node
+ if (homeNode != null)
+ homeNode.dispose();
+ homeNode = new SingleJcrNodeElem(null, userHome,
+ userSession.getUserID(), ArgeoJcrConstants.ALIAS_NODE);
+ }
+ }
+ if (repositoryRegister != null) {
+ if (repositoriesNode != null)
+ repositoriesNode.dispose();
+ repositoriesNode = new RepositoriesElem("Repositories",
+ repositoryRegister, repositoryFactory, null, userSession,
+ keyring);
+ }
+ }
+
+ /**
+ * Sends back the first level of the Tree. Independent from inputElement
+ * that can be null
+ */
+ public Object[] getElements(Object inputElement) {
+ List<Object> objs = new ArrayList<Object>();
+ if (homeNode != null)
+ objs.add(homeNode);
+ if (repositoriesNode != null)
+ objs.add(repositoriesNode);
+ return objs.toArray();
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof TreeParent) {
+ if (sortChildren) {
+ // TreeParent[] arr = (TreeParent[]) ((TreeParent)
+ // parentElement)
+ // .getChildren();
+ Object[] tmpArr = ((TreeParent) parentElement).getChildren();
+ TreeParent[] arr = new TreeParent[tmpArr.length];
+ for (int i = 0; i < tmpArr.length; i++)
+ arr[i] = (TreeParent) tmpArr[i];
+
+ Arrays.sort(arr, itemComparator);
+ return arr;
+ } else
+ return ((TreeParent) parentElement).getChildren();
+
+ } else {
+ return new Object[0];
+ }
+ }
+
+ /**
+ * Sets whether the content provider should order the children nodes or not.
+ * It is user duty to call a full refresh of the tree after changing this
+ * parameter.
+ */
+ public void setSortChildren(boolean sortChildren) {
+ this.sortChildren = sortChildren;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).getParent();
+ } else
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof RepositoriesElem) {
+ RepositoryRegister rr = ((RepositoriesElem) element)
+ .getRepositoryRegister();
+ return rr.getRepositories().size() > 0;
+ } else if (element instanceof TreeParent) {
+ TreeParent tp = (TreeParent) element;
+ return tp.hasChildren();
+ }
+ return false;
+ }
+
+ public void dispose() {
+ if (homeNode != null)
+ homeNode.dispose();
+ if (repositoriesNode != null) {
+ // logs out open sessions
+ // see https://bugzilla.argeo.org/show_bug.cgi?id=23
+ repositoriesNode.dispose();
+ }
+ }
+
+ /**
+ * Specific comparator for this view. See spec in BUG :
+ * https://www.argeo.org/bugzilla/show_bug.cgi?id=139
+ */
+ private class TreeBrowserComparator implements Comparator<TreeParent> {
+
+ public int category(TreeParent element) {
+ if (element instanceof SingleJcrNodeElem) {
+ Node node = ((SingleJcrNodeElem) element).getNode();
+ try {
+ if (node.isNodeType(NodeType.NT_FOLDER))
+ return 5;
+ } catch (RepositoryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return 10;
+ }
+
+ public int compare(TreeParent o1, TreeParent o2) {
+ int cat1 = category(o1);
+ int cat2 = category(o2);
+
+ if (cat1 != cat2) {
+ return cat1 - cat2;
+ }
+ return o1.getName().compareTo(o2.getName());
+ }
+ }
+}
\ 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.jcr.ui.explorer.browser;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.DefaultNodeLabelProvider;
+import org.argeo.eclipse.ui.jcr.JcrImages;
+import org.argeo.jcr.ui.explorer.model.RemoteRepositoryElem;
+import org.argeo.jcr.ui.explorer.model.RepositoriesElem;
+import org.argeo.jcr.ui.explorer.model.RepositoryElem;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.eclipse.swt.graphics.Image;
+
+public class NodeLabelProvider extends DefaultNodeLabelProvider {
+ // Images
+
+ public String getText(Object element) {
+ try {
+ if (element instanceof SingleJcrNodeElem) {
+ SingleJcrNodeElem sjn = (SingleJcrNodeElem) element;
+ return getText(sjn.getNode());
+ } else
+ return super.getText(element);
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected JCR error while getting node name.");
+ }
+ }
+
+ protected String getText(Node node) throws RepositoryException {
+ String label = node.getName();
+ StringBuffer mixins = new StringBuffer("");
+ for (NodeType type : node.getMixinNodeTypes())
+ mixins.append(' ').append(type.getName());
+
+ return label + " [" + node.getPrimaryNodeType().getName() + mixins
+ + "]";
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof RemoteRepositoryElem) {
+ if (((RemoteRepositoryElem) element).isConnected())
+ return JcrImages.REMOTE_CONNECTED;
+ else
+ return JcrImages.REMOTE_DISCONNECTED;
+ } else if (element instanceof RepositoryElem) {
+ if (((RepositoryElem) element).isConnected())
+ return JcrImages.REPOSITORY_CONNECTED;
+ else
+ return JcrImages.REPOSITORY_DISCONNECTED;
+ } else if (element instanceof WorkspaceElem) {
+ if (((WorkspaceElem) element).isConnected())
+ return JcrImages.WORKSPACE_CONNECTED;
+ else
+ return JcrImages.WORKSPACE_DISCONNECTED;
+ } else if (element instanceof RepositoriesElem) {
+ return JcrImages.REPOSITORIES;
+ } else if (element instanceof SingleJcrNodeElem)
+ try {
+ return super.getImage(((SingleJcrNodeElem) element).getNode());
+ } catch (RepositoryException e) {
+ return null;
+ }
+ return super.getImage(element);
+ }
+
+}
--- /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.jcr.ui.explorer.browser;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class PropertiesContentProvider implements IStructuredContentProvider {
+ private JcrItemsComparator itemComparator = new JcrItemsComparator();
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public Object[] getElements(Object inputElement) {
+ try {
+ if (inputElement instanceof Node) {
+ Set<Property> props = new TreeSet<Property>(itemComparator);
+ PropertyIterator pit = ((Node) inputElement).getProperties();
+ while (pit.hasNext())
+ props.add(pit.nextProperty());
+ return props.toArray();
+ }
+ return new Object[] {};
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot get element for " + inputElement,
+ e);
+ }
+ }
+
+}
--- /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.jcr.ui.explorer.commands;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.eclipse.ui.dialogs.SingleValue;
+import org.argeo.eclipse.ui.jcr.JcrUiPlugin;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Adds a node of type nt:folder, only on {@link SingleJcrNodeElem} and
+ * {@link WorkspaceElem} TreeObject types.
+ *
+ *
+ * This handler assumes that a selection provider is available and picks only
+ * first selected item. It is UI's job to enable the command only when the
+ * selection contains one and only one element. Thus no parameter is passed
+ * through the command.
+ *
+ * This handler is still 'hard linked' to a GenericJcrBrowser view to enable
+ * correct tree refresh when a node is added. This must be corrected in future
+ * versions.
+ */
+public class AddFolderNode extends AbstractHandler {
+
+ public final static String ID = JcrExplorerPlugin.ID + ".addFolderNode";
+
+ // public final static String DEFAULT_LABEL = JcrExplorerPlugin
+ // .getMessage("addFolderNodeCmdLbl");
+ // public final static String DEFAULT_ICON_REL_PATH = "icons/addRepo.gif";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+
+ GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(HandlerUtil.getActivePartId(event));
+
+ if (selection != null && !selection.isEmpty()
+ && selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) selection).getFirstElement();
+ TreeParent treeParentNode = null;
+ Node jcrParentNode = null;
+
+ if (obj instanceof SingleJcrNodeElem) {
+ treeParentNode = (TreeParent) obj;
+ jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode();
+ } else if (obj instanceof WorkspaceElem) {
+ treeParentNode = (TreeParent) obj;
+ jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode();
+ } else
+ return null;
+
+ String folderName = SingleValue.ask("Folder name",
+ "Enter folder name");
+ if (folderName != null) {
+ try {
+ jcrParentNode.addNode(folderName, NodeType.NT_FOLDER);
+ jcrParentNode.getSession().save();
+ view.nodeAdded(treeParentNode);
+ } catch (RepositoryException e) {
+ ErrorFeedback.show("Cannot create folder " + folderName
+ + " under " + treeParentNode, e);
+ }
+ }
+ } else {
+ ErrorFeedback.show(JcrUiPlugin
+ .getMessage("errorUnvalidNtFolderNodeType"));
+ }
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.argeo.jcr.ui.explorer.wizards.ChangeRightsWizard;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Open a dialog to change rights on the selected node.
+ */
+
+public class AddPrivileges extends AbstractHandler {
+ public final static String ID = JcrExplorerPlugin.ID + ".addPrivileges";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+ if (selection != null && !selection.isEmpty()
+ && selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) selection).getFirstElement();
+ TreeParent treeParentNode = null;
+ Node jcrParentNode = null;
+
+ if (obj instanceof SingleJcrNodeElem) {
+ treeParentNode = (TreeParent) obj;
+ jcrParentNode = ((SingleJcrNodeElem) treeParentNode).getNode();
+ } else if (obj instanceof WorkspaceElem) {
+ treeParentNode = (TreeParent) obj;
+ jcrParentNode = ((WorkspaceElem) treeParentNode).getRootNode();
+ } else
+ return null;
+
+ try {
+ ChangeRightsWizard wizard = new ChangeRightsWizard(
+ jcrParentNode.getSession(), jcrParentNode.getPath());
+ 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);
+ }
+ } else {
+ ErrorFeedback.show("Cannot add privileges");
+ }
+ return null;
+ }
+}
\ 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.jcr.ui.explorer.commands;
+
+import java.net.URI;
+import java.util.Hashtable;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.utils.CommandUtils;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+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.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Connect to a remote repository and, if successful publish it as an OSGi
+ * service.
+ */
+public class AddRemoteRepository extends AbstractHandler implements
+ JcrExplorerConstants, ArgeoNames {
+
+ private RepositoryFactory repositoryFactory;
+ private Repository nodeRepository;
+ private Keyring keyring;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(
+ Display.getDefault().getActiveShell());
+ if (dlg.open() == Dialog.OK) {
+ CommandUtils.callCommand(Refresh.ID);
+ }
+ return null;
+ }
+
+ public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+ this.repositoryFactory = repositoryFactory;
+ }
+
+ public void setKeyring(Keyring keyring) {
+ this.keyring = keyring;
+ }
+
+ public void setNodeRepository(Repository nodeRepository) {
+ this.nodeRepository = nodeRepository;
+ }
+
+ class RemoteRepositoryLoginDialog extends TitleAreaDialog {
+ private Text name;
+ private Text uri;
+ private Text username;
+ private Text password;
+ private Button saveInKeyring;
+
+ public RemoteRepositoryLoginDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ protected Point getInitialSize() {
+ return new Point(600, 400);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ true));
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ false));
+ setMessage("Login to remote repository", IMessageProvider.NONE);
+ name = createLT(composite, "Name", "remoteRepository");
+ uri = createLT(composite, "URI",
+ "http://localhost:7070/data/jcr/node");
+ username = createLT(composite, "User", "");
+ password = createLP(composite, "Password");
+
+ saveInKeyring = createLC(composite, "Remember password", false);
+ parent.pack();
+ return composite;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+ Button test = createButton(parent, 2, "Test", false);
+ test.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent arg0) {
+ testConnection();
+ }
+ });
+ }
+
+ void testConnection() {
+ Session session = null;
+ try {
+ URI checkedUri = new URI(uri.getText());
+ String checkedUriStr = checkedUri.toString();
+
+ Hashtable<String, String> params = new Hashtable<String, String>();
+ params.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, checkedUriStr);
+ Repository repository = repositoryFactory.getRepository(params);
+ if (username.getText().trim().equals("")) {// anonymous
+ session = repository.login();
+ } else {
+ // FIXME use getTextChars() when upgrading to 3.7
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412
+ char[] pwd = password.getText().toCharArray();
+ SimpleCredentials sc = new SimpleCredentials(
+ username.getText(), pwd);
+ session = repository.login(sc);
+ MessageDialog.openInformation(getParentShell(), "Success",
+ "Connection to '" + uri.getText() + "' successful");
+ }
+ } catch (Exception e) {
+ ErrorFeedback.show(
+ "Connection test failed for " + uri.getText(), e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ }
+
+ @Override
+ protected void okPressed() {
+ Session nodeSession = null;
+ try {
+ nodeSession = nodeRepository.login();
+ Node home = UserJcrUtils.getUserHome(nodeSession);
+
+ Node remote = home.hasNode(ARGEO_REMOTE) ? home
+ .getNode(ARGEO_REMOTE) : home.addNode(ARGEO_REMOTE);
+ if (remote.hasNode(name.getText()))
+ throw new ArgeoException(
+ "There is already a remote repository named "
+ + name.getText());
+ Node remoteRepository = remote.addNode(name.getText(),
+ ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
+ remoteRepository.setProperty(ARGEO_URI, uri.getText());
+ remoteRepository.setProperty(ARGEO_USER_ID, username.getText());
+ nodeSession.save();
+ if (saveInKeyring.getSelection()) {
+ String pwdPath = remoteRepository.getPath() + '/'
+ + ARGEO_PASSWORD;
+ keyring.set(pwdPath, password.getText().toCharArray());
+ }
+ nodeSession.save();
+ MessageDialog.openInformation(
+ getParentShell(),
+ "Repository Added",
+ "Remote repository '" + username.getText() + "@"
+ + uri.getText() + "' added");
+
+ super.okPressed();
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot add remote repository", e);
+ } finally {
+ JcrUtils.logoutQuietly(nodeSession);
+ }
+ }
+
+ /** Creates label and text. */
+ protected Text createLT(Composite parent, String label, String initial) {
+ new Label(parent, SWT.NONE).setText(label);
+ Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ text.setText(initial);
+ return text;
+ }
+
+ /** Creates label and check. */
+ protected Button createLC(Composite parent, String label,
+ Boolean initial) {
+ new Label(parent, SWT.NONE).setText(label);
+ Button check = new Button(parent, SWT.CHECK);
+ check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ check.setSelection(initial);
+ return check;
+ }
+
+ protected Text createLP(Composite parent, String label) {
+ new Label(parent, SWT.NONE).setText(label);
+ Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER
+ | SWT.PASSWORD);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ return text;
+ }
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import java.util.Arrays;
+
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.dialogs.SingleValue;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.model.RepositoryElem;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Creates a new JCR workspace */
+public class CreateWorkspace extends AbstractHandler {
+
+ public final static String ID = JcrExplorerPlugin.ID + ".addFolderNode";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+
+ GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(HandlerUtil.getActivePartId(event));
+
+ if (selection != null && !selection.isEmpty()
+ && selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) selection).getFirstElement();
+ if (!(obj instanceof RepositoryElem))
+ return null;
+
+ RepositoryElem repositoryNode = (RepositoryElem) obj;
+ String workspaceName = SingleValue.ask("Workspace name",
+ "Enter workspace name");
+ if (workspaceName != null) {
+ if (Arrays.asList(repositoryNode.getAccessibleWorkspaceNames())
+ .contains(workspaceName)) {
+ ErrorFeedback.show("Workspace " + workspaceName
+ + " already exists.");
+ } else {
+ repositoryNode.createWorkspace(workspaceName);
+ view.nodeAdded(repositoryNode);
+ }
+ }
+ } else {
+ ErrorFeedback.show("Cannot create workspace");
+ }
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import java.util.Iterator;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Deletes the selected nodes: both in the JCR repository and in the UI view.
+ * Warning no check is done, except implementation dependent native checks,
+ * handle with care.
+ *
+ * This handler is still 'hard linked' to a GenericJcrBrowser view to enable
+ * correct tree refresh when a node is added. This must be corrected in future
+ * versions.
+ */
+public class DeleteNodes extends AbstractHandler {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+ if (selection == null || !(selection instanceof IStructuredSelection))
+ return null;
+
+ GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(HandlerUtil.getActivePartId(event));
+
+ // confirmation
+ StringBuffer buf = new StringBuffer("");
+ Iterator<?> lst = ((IStructuredSelection) selection).iterator();
+ while (lst.hasNext()) {
+ SingleJcrNodeElem sjn = ((SingleJcrNodeElem) lst.next());
+ buf.append(sjn.getName()).append(' ');
+ }
+ Boolean ok = MessageDialog.openConfirm(
+ HandlerUtil.getActiveShell(event), "Confirm deletion",
+ "Do you want to delete " + buf + "?");
+
+ // operation
+ if (ok) {
+ Iterator<?> it = ((IStructuredSelection) selection).iterator();
+ Object obj = null;
+ SingleJcrNodeElem ancestor = null;
+ WorkspaceElem rootAncestor = null;
+ try {
+ while (it.hasNext()) {
+ obj = it.next();
+ if (obj instanceof SingleJcrNodeElem) {
+ // Cache objects
+ SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj;
+ TreeParent tp = (TreeParent) sjn.getParent();
+ Node node = sjn.getNode();
+
+ // Jcr Remove
+ node.remove();
+ node.getSession().save();
+ // UI remove
+ tp.removeChild(sjn);
+
+ // Check if the parent is the root node
+ if (tp instanceof WorkspaceElem)
+ rootAncestor = (WorkspaceElem) tp;
+ else
+ ancestor = getOlder(ancestor, (SingleJcrNodeElem) tp);
+ }
+ }
+ if (rootAncestor != null)
+ view.nodeRemoved(rootAncestor);
+ else if (ancestor != null)
+ view.nodeRemoved(ancestor);
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot delete selected node ", e);
+ }
+ }
+ return null;
+ }
+
+ private SingleJcrNodeElem getOlder(SingleJcrNodeElem A, SingleJcrNodeElem B) {
+ try {
+ if (A == null)
+ return B == null ? null : B;
+ // Todo enhanced this method
+ else
+ return A.getNode().getDepth() <= B.getNode().getDepth() ? A : B;
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Cannot find ancestor", re);
+ }
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.specific.OpenFile;
+import org.argeo.eclipse.ui.utils.CommandUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * If the method
+ * <code> HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getSelection() </code>
+ * exits and has a SingleJcrNodeElem as first element, it canonically calls the
+ * JCR Session.exportSystemView() method on the underlying node with both
+ * skipBinary & noRecurse boolean flags set to false.
+ *
+ * Resulting stream is saved in a tmp file and opened via the "open file"
+ * single-sourced command.
+ */
+public class DumpNode extends AbstractHandler {
+ public final static String ID = JcrExplorerPlugin.ID + ".dumpNode";
+
+ private final static DateFormat df = new SimpleDateFormat(
+ "yyyy-MM-dd_HH-mm");
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+ if (selection == null || !(selection instanceof IStructuredSelection))
+ return null;
+
+ Iterator<?> lst = ((IStructuredSelection) selection).iterator();
+ if (lst.hasNext()) {
+ Object element = lst.next();
+ if (element instanceof SingleJcrNodeElem) {
+ SingleJcrNodeElem sjn = (SingleJcrNodeElem) element;
+ Node node = sjn.getNode();
+
+ // TODO add a dialog to configure the export and ask for
+ // confirmation
+ // Boolean ok = MessageDialog.openConfirm(
+ // HandlerUtil.getActiveShell(event), "Confirm deletion",
+ // "Do you want to delete " + buf + "?");
+
+ File tmpFile;
+ FileOutputStream fos;
+ try {
+ tmpFile = File.createTempFile("JcrExport", ".xml");
+ tmpFile.deleteOnExit();
+ fos = new FileOutputStream(tmpFile);
+ String dateVal = df.format(new GregorianCalendar()
+ .getTime());
+ node.getSession().exportSystemView(node.getPath(), fos,
+ true, false);
+ openGeneratedFile(tmpFile.getAbsolutePath(),
+ "Dump-" + JcrUtils.replaceInvalidChars(node.getName())+ "-" + dateVal + ".xml");
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unable to perform SystemExport on " + node, e);
+ } catch (IOException e) {
+ throw new ArgeoException("Unable to SystemExport " + node,
+ e);
+ }
+ }
+ }
+ return null;
+ }
+
+ private synchronized void openGeneratedFile(String path, String fileName) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(OpenFile.PARAM_FILE_NAME, fileName);
+ params.put(OpenFile.PARAM_FILE_URI, "file://" + path);
+ CommandUtils.callCommand("org.argeo.security.ui.specific.openFile",
+ params);
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Property;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.jcr.editors.NodeEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Generic command to open a path in an editor. */
+public class EditNode extends AbstractHandler {
+ public final static String EDITOR_PARAM = "editor";
+
+ private String defaultEditorId;
+
+ private Map<String, String> nodeTypeToEditor = new HashMap<String, String>();
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ String path = event.getParameter(Property.JCR_PATH);
+
+ String type = event.getParameter(NodeType.NT_NODE_TYPE);
+ if (type == null)
+ type = NodeType.NT_UNSTRUCTURED;
+
+ String editorId = event.getParameter(NodeType.NT_NODE_TYPE);
+ if (editorId == null)
+ editorId = nodeTypeToEditor.containsKey(type) ? nodeTypeToEditor
+ .get(type) : defaultEditorId;
+
+ NodeEditorInput nei = new NodeEditorInput(path);
+
+ try {
+ HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
+ .openEditor(nei, editorId);
+ } catch (PartInitException e) {
+ ErrorFeedback.show("Cannot open " + editorId + " with " + path
+ + " of type " + type, e);
+ }
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setDefaultEditorId(String defaultEditorId) {
+ this.defaultEditorId = defaultEditorId;
+ }
+
+}
--- /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.jcr.ui.explorer.commands;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Opens the generic node editor. */
+public class GetNodeSize extends AbstractHandler {
+ // private final static Log log = LogFactory.getLog(GetNodeSize.class);
+
+ public final static String ID = JcrExplorerPlugin.ID + ".getNodeSize";
+
+ // public final static String DEFAULT_ICON_REL_PATH = "icons/getSize.gif";
+ // public final static String DEFAULT_LABEL = JcrExplorerPlugin
+ // .getMessage("getNodeSizeCmdLbl");
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // JcrUtils.getRepositoryByAlias(repositoryRegister,
+ // ArgeoJcrConstants.ALIAS_NODE);
+
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+
+ if (selection != null && !selection.isEmpty()
+ && selection instanceof IStructuredSelection) {
+
+ // IStructuredSelection iss = (IStructuredSelection) selection;
+ // if (iss.size() > 1)
+ // ErrorFeedback.show(JcrExplorerPlugin
+ // .getMessage("warningInvalidMultipleSelection"), null);
+
+ long size = 0;
+
+ Iterator<?> it = ((IStructuredSelection) selection).iterator();
+
+ // as the size method is recursive, we keep track of nodes for which
+ // we already have computed size so that we don't count them twice.
+ // In a first approximation, we assume that the structure selection
+ // keep the nodes ordered.
+ // TODO : enhance that.
+ List<String> importedPathes = new ArrayList<String>();
+ try {
+ nodesIt: while (it.hasNext()) {
+ Object obj = it.next();
+ String curPath;
+ Node node;
+ if (obj instanceof SingleJcrNodeElem) {
+ node = ((SingleJcrNodeElem) obj).getNode();
+ curPath = node.getSession().getWorkspace().getName();
+ curPath += "/" + node.getPath();
+ } else if (obj instanceof WorkspaceElem) {
+ node = ((WorkspaceElem) obj).getRootNode();
+ curPath = node.getSession().getWorkspace().getName();
+ } else
+ // unvalid object type
+ continue nodesIt;
+
+ Iterator<String> itPath = importedPathes.iterator();
+ while (itPath.hasNext()) {
+ String refPath = itPath.next();
+ if (curPath.startsWith(refPath))
+ // Already done : skip node
+ continue nodesIt;
+ }
+ size += JcrUtils.getNodeApproxSize(node);
+ importedPathes.add(curPath);
+ }
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot Get size of selected node ", e);
+ }
+
+ String[] labels = { "OK" };
+ Shell shell = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getShell();
+ MessageDialog md = new MessageDialog(shell, "Node size", null,
+ "Node size is: " + size / 1024 + " KB",
+ MessageDialog.INFORMATION, labels, 0);
+ md.open();
+ }
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import javax.jcr.Node;
+
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.argeo.jcr.ui.explorer.wizards.ImportFileSystemWizard;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Import a local file system directory tree. */
+public class ImportFileSystem extends AbstractHandler {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+ GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(HandlerUtil.getActivePartId(event));
+ if (selection != null && !selection.isEmpty()
+ && selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) selection).getFirstElement();
+ try {
+ Node folder = null;
+ if (obj instanceof SingleJcrNodeElem) {
+ folder = ((SingleJcrNodeElem) obj).getNode();
+ } else if (obj instanceof WorkspaceElem) {
+ folder = ((WorkspaceElem) obj).getRootNode();
+ } else {
+ ErrorFeedback.show(JcrExplorerPlugin
+ .getMessage("warningInvalidNodeToImport"));
+ }
+ if (folder != null) {
+ ImportFileSystemWizard wizard = new ImportFileSystemWizard(
+ folder);
+ WizardDialog dialog = new WizardDialog(
+ HandlerUtil.getActiveShell(event), wizard);
+ dialog.open();
+ view.nodeAdded((TreeParent) obj);
+ }
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot import files to " + obj, e);
+ }
+ }
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.editors.NodeEditorInput;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.editors.GenericNodeEditor;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Opens the generic node editor. */
+public class OpenGenericNodeEditor extends AbstractHandler {
+ public final static String ID = JcrExplorerPlugin.ID + ".openGenericNodeEditor";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ String path = event.getParameter(JcrExplorerConstants.PARAM_PATH);
+ try {
+ NodeEditorInput nei = new NodeEditorInput(path);
+ HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
+ .openEditor(nei, GenericNodeEditor.ID);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot open editor", e);
+ }
+ return null;
+ }
+
+}
--- /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.jcr.ui.explorer.commands;
+
+import java.util.Iterator;
+
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.utils.JcrUiUtils;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+/**
+ * Force the selected objects of the active view to be refreshed doing the
+ * following:
+ * <ol>
+ * <li>The model objects are recomputed</li>
+ * <li>the view is refreshed</li>
+ * </ol>
+ */
+public class Refresh extends AbstractHandler {
+
+ public final static String ID = JcrExplorerPlugin.ID + ".refresh";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ AbstractJcrBrowser view = (AbstractJcrBrowser) JcrExplorerPlugin
+ .getDefault().getWorkbench().getActiveWorkbenchWindow()
+ .getActivePage().getActivePart();//
+
+ ISelection selection = JcrExplorerPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage().getSelection();
+
+ if (selection != null && selection instanceof IStructuredSelection
+ && !selection.isEmpty()) {
+ Iterator<?> it = ((IStructuredSelection) selection).iterator();
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (obj instanceof TreeParent) {
+ TreeParent tp = (TreeParent) obj;
+ JcrUiUtils.forceRefreshIfNeeded(tp);
+ view.refresh(obj);
+ }
+ }
+ } else if (view instanceof GenericJcrBrowser)
+ ((GenericJcrBrowser) view).refresh(null); // force full refresh
+
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.commands;
+
+import org.argeo.jcr.ui.explorer.model.RemoteRepositoryElem;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Remove a registered remote repository */
+public class RemoveRemoteRepository extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getSelection();
+
+ GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(HandlerUtil.getActivePartId(event));
+
+ if (selection != null && !selection.isEmpty()
+ && selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection) selection).getFirstElement();
+
+ if (obj instanceof RemoteRepositoryElem) {
+ ((RemoteRepositoryElem) obj).remove();
+ view.refresh(null);
+ }
+ }
+ return null;
+ }
+
+}
--- /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.jcr.ui.explorer.commands;
+
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.views.GenericJcrBrowser;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.State;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Change isSorted state of the JcrExplorer Browser
+ */
+public class SortChildNodes extends AbstractHandler {
+ public final static String ID = JcrExplorerPlugin.ID + ".sortChildNodes";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ GenericJcrBrowser view = (GenericJcrBrowser) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(GenericJcrBrowser.ID);
+
+ ICommandService service = (ICommandService) PlatformUI.getWorkbench()
+ .getService(ICommandService.class);
+ Command command = service.getCommand(ID);
+ State state = command.getState(ID + ".toggleState");
+
+ boolean wasSorted = (Boolean) state.getValue();
+ view.setSortChildNodes(!wasSorted);
+ state.setValue(!wasSorted);
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.dialogs;
+
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/** Dialog to change the current user password */
+public class ChooseNameDialog extends TitleAreaDialog {
+ private Text nameT;
+
+ public ChooseNameDialog(Shell parentShell) {
+ super(parentShell);
+ setTitle("Choose name");
+ }
+
+ protected Point getInitialSize() {
+ return new Point(300, 250);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ nameT = createLT(composite, "Name");
+
+ setMessage("Choose name", IMessageProvider.INFORMATION);
+ parent.pack();
+ return composite;
+ }
+
+ /** Creates label and text. */
+ protected Text createLT(Composite parent, String label) {
+ new Label(parent, SWT.NONE).setText(label);
+ Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ return text;
+ }
+
+ public String getName() {
+ return nameT.getText();
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import javax.jcr.Node;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
+import org.argeo.jcr.ui.explorer.providers.SingleNodeAsTreeContentProvider;
+import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+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;
+
+/**
+ * List all childs of the current node and brings some browsing capabilities
+ * accross the repository
+ */
+public class ChildNodesPage extends FormPage {
+ // private final static Log log = LogFactory.getLog(ChildNodesPage.class);
+
+ // business objects
+ private Node currentNode;
+
+ // this page UI components
+ private SingleNodeAsTreeContentProvider nodeContentProvider;
+ private TreeViewer nodesViewer;
+
+ public ChildNodesPage(FormEditor editor, String title, Node currentNode) {
+ super(editor, "ChildNodesPage", title);
+ this.currentNode = currentNode;
+ }
+
+ protected void createFormContent(IManagedForm managedForm) {
+ try {
+ ScrolledForm form = managedForm.getForm();
+ form.setText(JcrExplorerPlugin.getMessage("childNodesPageTitle"));
+ Composite body = form.getBody();
+ GridLayout twt = new GridLayout(1, false);
+ twt.marginWidth = twt.marginHeight = 5;
+ body.setLayout(twt);
+ if (!currentNode.hasNodes()) {
+ managedForm.getToolkit().createLabel(body,
+ JcrExplorerPlugin.getMessage("warningNoChildNode"));
+ } else {
+
+ nodeContentProvider = new SingleNodeAsTreeContentProvider();
+ nodesViewer = createNodeViewer(body, nodeContentProvider);
+ nodesViewer.setInput(currentNode);
+ }
+ } catch (Exception e) {
+ throw new ArgeoException(
+ "Unexpected error while creating child node page", e);
+ }
+ }
+
+ protected TreeViewer createNodeViewer(Composite parent,
+ final ITreeContentProvider nodeContentProvider) {
+
+ final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
+
+ tmpNodeViewer.getTree().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ tmpNodeViewer.setContentProvider(nodeContentProvider);
+ tmpNodeViewer.setLabelProvider(new NodeLabelProvider());
+ tmpNodeViewer
+ .addDoubleClickListener(new GenericNodeDoubleClickListener(
+ tmpNodeViewer));
+ return tmpNodeViewer;
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Label;
+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;
+
+/**
+ * This page is only used at editor's creation time when current node has not
+ * yet been set
+ */
+public class EmptyNodePage extends FormPage {
+ // private final static Log log = LogFactory.getLog(EmptyNodePage.class);
+
+ public EmptyNodePage(FormEditor editor, String title) {
+ super(editor, "Empty Page", title);
+ }
+
+ protected void createFormContent(IManagedForm managedForm) {
+ try {
+ ScrolledForm form = managedForm.getForm();
+ GridLayout twt = new GridLayout(1, false);
+ twt.marginWidth = twt.marginHeight = 0;
+ form.getBody().setLayout(twt);
+ Label lbl = new Label(form.getBody(), SWT.NONE);
+ lbl.setText("Empty page");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import org.argeo.eclipse.ui.jcr.editors.AbstractJcrQueryEditor;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/** Enables end user to type and execute any JCR query. */
+public class GenericJcrQueryEditor extends AbstractJcrQueryEditor {
+ public final static String ID = JcrExplorerPlugin.ID + ".genericJcrQueryEditor";
+
+ private Text queryField;
+
+ @Override
+ public void createQueryForm(Composite parent) {
+ parent.setLayout(new GridLayout(1, false));
+
+ queryField = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP);
+ queryField.setText(initialQuery);
+ queryField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Button execute = new Button(parent, SWT.PUSH);
+ execute.setText("Execute");
+
+ Listener executeListener = new Listener() {
+ public void handleEvent(Event event) {
+ executeQuery(queryField.getText());
+ }
+ };
+
+ execute.addListener(SWT.Selection, executeListener);
+ // queryField.addListener(SWT.DefaultSelection, executeListener);
+ }
+
+ @Override
+ public void setFocus() {
+ queryField.setFocus();
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import javax.jcr.Node;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.forms.editor.FormEditor;
+
+/**
+ * Container for the node editor page. At creation time, it takes a JCR Node
+ * that cannot be changed afterwards.
+ */
+public class GenericNodeEditor extends FormEditor {
+
+ // private final static Log log =
+ // LogFactory.getLog(GenericNodeEditor.class);
+ public final static String ID = JcrExplorerPlugin.ID + ".genericNodeEditor";
+
+ private Node currentNode;
+
+ private GenericPropertyPage genericPropertyPage;
+ private ChildNodesPage childNodesPage;
+ private NodeRightsManagementPage nodeRightsManagementPage;
+ private NodeVersionHistoryPage nodeVersionHistoryPage;
+
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ super.init(site, input);
+ GenericNodeEditorInput nei = (GenericNodeEditorInput) getEditorInput();
+ currentNode = nei.getCurrentNode();
+ this.setPartName(JcrUtils.lastPathElement(nei.getPath()));
+ }
+
+ @Override
+ protected void addPages() {
+ try {
+ // genericNodePage = new GenericNodePage(this,
+ // JcrExplorerPlugin.getMessage("genericNodePageTitle"),
+ // currentNode);
+ // addPage(genericNodePage);
+
+ genericPropertyPage = new GenericPropertyPage(this,
+ JcrExplorerPlugin.getMessage("genericNodePageTitle"),
+ currentNode);
+ addPage(genericPropertyPage);
+
+ childNodesPage = new ChildNodesPage(this,
+ JcrExplorerPlugin.getMessage("childNodesPageTitle"),
+ currentNode);
+ addPage(childNodesPage);
+
+ nodeRightsManagementPage = new NodeRightsManagementPage(this,
+ JcrExplorerPlugin
+ .getMessage("nodeRightsManagementPageTitle"),
+ currentNode);
+ addPage(nodeRightsManagementPage);
+
+ nodeVersionHistoryPage = new NodeVersionHistoryPage(
+ this,
+ JcrExplorerPlugin.getMessage("nodeVersionHistoryPageTitle"),
+ currentNode);
+ addPage(nodeVersionHistoryPage);
+ } catch (PartInitException e) {
+ throw new ArgeoException("Not able to add an empty page ", e);
+ }
+ }
+
+ @Override
+ public void doSaveAs() {
+ // unused compulsory method
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ try {
+ // Automatically commit all pages of the editor
+ commitPages(true);
+ firePropertyChange(PROP_DIRTY);
+ } catch (Exception e) {
+ throw new ArgeoException("Error while saving node", e);
+ }
+
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+
+ Node getCurrentNode() {
+ return currentNode;
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * An editor input based the JCR node object.
+ * */
+
+public class GenericNodeEditorInput implements IEditorInput {
+ private final Node currentNode;
+
+ // cache key properties at creation time to avoid Exception at recoring time
+ // when the session has been closed
+ private String path;
+ private String uid;
+ private String name;
+
+ public GenericNodeEditorInput(Node currentNode) {
+ this.currentNode = currentNode;
+ try {
+ name = currentNode.getName();
+ uid = currentNode.getIdentifier();
+ path = currentNode.getPath();
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "unexpected error while getting node key values at creation time",
+ re);
+ }
+ }
+
+ public Node getCurrentNode() {
+ return currentNode;
+ }
+
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return null;
+ }
+
+ public boolean exists() {
+ return true;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getUid() {
+ return uid;
+ }
+
+ public String getToolTipText() {
+ return path;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ /**
+ * equals method based on UID that is unique within a workspace and path of
+ * the node, thus 2 shared node that have same UID as defined in the spec
+ * but 2 different pathes will open two distinct editors.
+ *
+ * TODO enhance this method to support multirepository and multiworkspace
+ * environments
+ */
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+
+ GenericNodeEditorInput other = (GenericNodeEditorInput) obj;
+ if (!getUid().equals(other.getUid()))
+ return false;
+ if (!getPath().equals(other.getPath()))
+ return false;
+ return true;
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+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.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
+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.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+/**
+ * Main node editor page. Lists all properties of the current node and enable
+ * access and editing for some of them.
+ */
+
+public class GenericNodePage extends FormPage implements JcrExplorerConstants {
+ // private final static Log log = LogFactory.getLog(GenericNodePage.class);
+
+ // local constants
+ private final static String JCR_PROPERTY_NAME = "jcr:name";
+
+ // Utils
+ protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
+
+ // Main business Objects
+ private Node currentNode;
+
+ // This page widgets
+ private FormToolkit tk;
+ private List<Control> modifyableProperties = new ArrayList<Control>();
+
+ public GenericNodePage(FormEditor editor, String title, Node currentNode) {
+ super(editor, "id", title);
+ this.currentNode = currentNode;
+ }
+
+ protected void createFormContent(IManagedForm managedForm) {
+ tk = managedForm.getToolkit();
+ ScrolledForm form = managedForm.getForm();
+ GridLayout twt = new GridLayout(3, false);
+ twt.marginWidth = twt.marginHeight = 5;
+
+ form.getBody().setLayout(twt);
+ createPropertiesPart(form.getBody());
+ }
+
+ private void createPropertiesPart(Composite parent) {
+ try {
+
+ PropertyIterator pi = currentNode.getProperties();
+
+ // Initializes form part
+ AbstractFormPart part = new AbstractFormPart() {
+ public void commit(boolean onSave) {
+ try {
+ if (onSave) {
+ ListIterator<Control> it = modifyableProperties
+ .listIterator();
+ while (it.hasNext()) {
+ // we only support Text controls for the time
+ // being
+ Text curControl = (Text) it.next();
+ String value = curControl.getText();
+ currentNode.setProperty((String) curControl
+ .getData(JCR_PROPERTY_NAME), value);
+ }
+
+ // We only commit when onSave = true,
+ // thus it is still possible to save after a tab
+ // change.
+ super.commit(onSave);
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while saving properties", re);
+ }
+ }
+ };
+
+ while (pi.hasNext()) {
+ Property prop = pi.nextProperty();
+ addPropertyLine(parent, part, prop);
+ }
+
+ getManagedForm().addPart(part);
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Error during creation of network details section", re);
+ }
+
+ }
+
+ private void addPropertyLine(Composite parent, AbstractFormPart part,
+ Property prop) {
+ try {
+ tk.createLabel(parent, prop.getName());
+ tk.createLabel(parent,
+ "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]");
+
+ if (prop.getDefinition().isProtected()) {
+ tk.createLabel(parent, formatReadOnlyPropertyValue(prop));
+ } else
+ addModifyableValueWidget(parent, part, prop);
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Cannot get property " + prop, re);
+ }
+ }
+
+ private String formatReadOnlyPropertyValue(Property prop) {
+ try {
+ String strValue;
+
+ if (prop.getType() == PropertyType.BINARY)
+ strValue = "<binary>";
+ else if (prop.isMultiple())
+ strValue = Arrays.asList(prop.getValues()).toString();
+ else if (prop.getType() == PropertyType.DATE)
+ strValue = timeFormatter.format(prop.getValue().getDate()
+ .getTime());
+ else
+ strValue = prop.getValue().getString();
+
+ return strValue;
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while formatting read only property value",
+ re);
+ }
+ }
+
+ private Control addModifyableValueWidget(Composite parent,
+ AbstractFormPart part, Property prop) {
+ GridData gd;
+ try {
+ if (prop.getType() == PropertyType.STRING) {
+ Text txt = tk.createText(parent, prop.getString());
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ txt.setLayoutData(gd);
+ txt.addModifyListener(new ModifiedFieldListener(part));
+ txt.setData(JCR_PROPERTY_NAME, prop.getName());
+ modifyableProperties.add(txt);
+ } else {
+ // unsupported property type for editing, we create a read only
+ // label.
+ return tk
+ .createLabel(parent, formatReadOnlyPropertyValue(prop));
+ }
+ return null;
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while formatting read only property value",
+ re);
+ }
+
+ }
+
+ //
+ // LISTENERS
+ //
+
+ private class ModifiedFieldListener implements ModifyListener {
+
+ private AbstractFormPart formPart;
+
+ public ModifiedFieldListener(AbstractFormPart generalPart) {
+ this.formPart = generalPart;
+ }
+
+ public void modifyText(ModifyEvent e) {
+ formPart.markDirty();
+ }
+ }
+
+}
--- /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.jcr.ui.explorer.editors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.providers.PropertyLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+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;
+
+/**
+ * Generic editor property page. Lists all properties of current node as a
+ * complex tree. TODO: enable editing
+ */
+
+public class GenericPropertyPage extends FormPage implements
+ JcrExplorerConstants {
+ // private final static Log log =
+ // LogFactory.getLog(GenericPropertyPage.class);
+
+ // Main business Objects
+ private Node currentNode;
+
+ public GenericPropertyPage(FormEditor editor, String title, Node currentNode) {
+ super(editor, "id", title);
+ this.currentNode = currentNode;
+ }
+
+ protected void createFormContent(IManagedForm managedForm) {
+ ScrolledForm form = managedForm.getForm();
+ form.setText(JcrExplorerPlugin.getMessage("genericNodePageTitle"));
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 5;
+ layout.marginWidth = 5;
+ form.getBody().setLayout(layout);
+
+ createComplexTree(form.getBody());
+
+ // TODO remove following
+ // createPropertiesPart(form.getBody());
+ }
+
+ private TreeViewer createComplexTree(Composite parent) {
+ int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION;
+ Tree tree = new Tree(parent, style);
+ createColumn(tree, "Property", SWT.LEFT, 200);
+ createColumn(tree, "Value(s)", SWT.LEFT, 300);
+ createColumn(tree, "Attributes", SWT.LEFT, 65);
+ tree.setLinesVisible(true);
+ tree.setHeaderVisible(true);
+
+ TreeViewer result = new TreeViewer(tree);
+ result.setContentProvider(new TreeContentProvider());
+ result.setLabelProvider(new PropertyLabelProvider());
+ result.setInput(currentNode);
+ result.expandAll();
+ return result;
+ }
+
+ private static TreeColumn createColumn(Tree parent, String name, int style,
+ int width) {
+ TreeColumn result = new TreeColumn(parent, style);
+ result.setText(name);
+ result.setWidth(width);
+ result.setMoveable(true);
+ result.setResizable(true);
+ return result;
+ }
+
+ //
+ // private void createPropertiesPart(Composite parent) {
+ // try {
+ //
+ // PropertyIterator pi = currentNode.getProperties();
+ //
+ // // Initializes form part
+ // AbstractFormPart part = new AbstractFormPart() {
+ // public void commit(boolean onSave) {
+ // try {
+ // if (onSave) {
+ // ListIterator<Control> it = modifyableProperties
+ // .listIterator();
+ // while (it.hasNext()) {
+ // // we only support Text controls for the time
+ // // being
+ // Text curControl = (Text) it.next();
+ // String value = curControl.getText();
+ // currentNode.setProperty((String) curControl
+ // .getData(JCR_PROPERTY_NAME), value);
+ // }
+ //
+ // // We only commit when onSave = true,
+ // // thus it is still possible to save after a tab
+ // // change.
+ // super.commit(onSave);
+ // }
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Unexpected error while saving properties", re);
+ // }
+ // }
+ // };
+ //
+ // while (pi.hasNext()) {
+ // Property prop = pi.nextProperty();
+ // addPropertyLine(parent, part, prop);
+ // }
+ //
+ // getManagedForm().addPart(part);
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Error during creation of network details section", re);
+ // }
+ //
+ // }
+ //
+ // private void addPropertyLine(Composite parent, AbstractFormPart part,
+ // Property prop) {
+ // try {
+ // tk.createLabel(parent, prop.getName());
+ // tk.createLabel(parent,
+ // "[" + JcrUtils.getPropertyDefinitionAsString(prop) + "]");
+ //
+ // if (prop.getDefinition().isProtected()) {
+ // tk.createLabel(parent, formatReadOnlyPropertyValue(prop));
+ // } else
+ // addModifyableValueWidget(parent, part, prop);
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException("Cannot get property " + prop, re);
+ // }
+ // }
+ //
+ // private String formatReadOnlyPropertyValue(Property prop) {
+ // try {
+ // String strValue;
+ //
+ // if (prop.getType() == PropertyType.BINARY)
+ // strValue = "<binary>";
+ // else if (prop.isMultiple())
+ // strValue = Arrays.asList(prop.getValues()).toString();
+ // else if (prop.getType() == PropertyType.DATE)
+ // strValue = timeFormatter.format(prop.getValue().getDate()
+ // .getTime());
+ // else
+ // strValue = prop.getValue().getString();
+ //
+ // return strValue;
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Unexpected error while formatting read only property value",
+ // re);
+ // }
+ // }
+ //
+ // private Control addModifyableValueWidget(Composite parent,
+ // AbstractFormPart part, Property prop) {
+ // GridData gd;
+ // try {
+ // if (prop.getType() == PropertyType.STRING) {
+ // Text txt = tk.createText(parent, prop.getString());
+ // gd = new GridData(GridData.FILL_HORIZONTAL);
+ // txt.setLayoutData(gd);
+ // txt.addModifyListener(new ModifiedFieldListener(part));
+ // txt.setData(JCR_PROPERTY_NAME, prop.getName());
+ // modifyableProperties.add(txt);
+ // } else {
+ // // unsupported property type for editing, we create a read only
+ // // label.
+ // return tk
+ // .createLabel(parent, formatReadOnlyPropertyValue(prop));
+ // }
+ // return null;
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Unexpected error while formatting read only property value",
+ // re);
+ // }
+ //
+ // }
+
+ // Multiple Value Model
+ // protected class MultipleValueItem {
+ // private int index;
+ // private Value value;
+ //
+ // public MultipleValueItem(int index, Value value) {
+ // this.index = index;
+ // this.value = value;
+ // }
+ //
+ // public int getIndex() {
+ // return index;
+ // }
+ //
+ // public Object getValue() {
+ // return value;
+ // }
+ // }
+
+ private class TreeContentProvider implements ITreeContentProvider {
+ public Object[] getElements(Object parent) {
+ Object[] props = null;
+ try {
+
+ if (parent instanceof Node) {
+ Node node = (Node) parent;
+ PropertyIterator pi;
+ pi = node.getProperties();
+ List<Property> propList = new ArrayList<Property>();
+ while (pi.hasNext()) {
+ propList.add(pi.nextProperty());
+ }
+ props = propList.toArray();
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected exception while listing node properties", e);
+ }
+ return props;
+ }
+
+ public Object getParent(Object child) {
+ return null;
+ }
+
+ public Object[] getChildren(Object parent) {
+ Object[] result = null;
+ if (parent instanceof Property) {
+ Property prop = (Property) parent;
+ try {
+
+ if (prop.isMultiple()) {
+ Value[] values = prop.getValues();
+ // List<MultipleValueItem> list = new
+ // ArrayList<MultipleValueItem>();
+ // for (int i = 0; i < values.length; i++) {
+ // MultipleValueItem mvi = new MultipleValueItem(i,
+ // values[i]);
+ // list.add(mvi);
+ // }
+
+ return values;
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected error getting multiple values property.",
+ e);
+ }
+ }
+ return result;
+ }
+
+ public boolean hasChildren(Object parent) {
+ try {
+ if (parent instanceof Property
+ && ((Property) parent).isMultiple()) {
+ return true;
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected exception while checking if property is multiple",
+ e);
+ }
+ return false;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public void dispose() {
+ }
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import javax.jcr.Node;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+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.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+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;
+
+/**
+ * This comments will be nicely fill by mbaudier in.
+ */
+public class NodeRightsManagementPage extends FormPage {
+ // private final static Log log =
+ // LogFactory.getLog(NodeRightsManagementPage.class);
+
+ private Node currentNode;
+
+ private TableViewer viewer;
+
+ public NodeRightsManagementPage(FormEditor editor, String title,
+ Node currentNode) {
+ super(editor, "NodeRightsManagementPage", title);
+ this.currentNode = currentNode;
+ }
+
+ protected void createFormContent(IManagedForm managedForm) {
+ ScrolledForm form = managedForm.getForm();
+ form.setText(JcrExplorerPlugin
+ .getMessage("nodeRightsManagementPageTitle"));
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 5;
+ layout.marginWidth = 5;
+ form.getBody().setLayout(layout);
+ createRightsPart(form.getBody());
+ }
+
+ /** Creates the rights part */
+ protected void createRightsPart(Composite parent) {
+ Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+ viewer = new TableViewer(table);
+
+ // check column
+ TableViewerColumn column = createTableViewerColumn(viewer, "checked",
+ 20);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return null;
+ }
+
+ public Image getImage(Object element) {
+ return null;
+ }
+ });
+ // column.setEditingSupport(new RoleEditingSupport(rolesViewer, part));
+
+ // role column
+ column = createTableViewerColumn(viewer, "Role", 200);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ Privilege p = (Privilege) element;
+ return p.getName();
+ }
+
+ public Image getImage(Object element) {
+ return null;
+ }
+ });
+ viewer.setContentProvider(new RightsContentProvider());
+ viewer.setInput(getEditorSite());
+ }
+
+ protected TableViewerColumn createTableViewerColumn(TableViewer viewer,
+ String title, int bound) {
+ final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
+ SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+ column.setText(title);
+ column.setWidth(bound);
+ column.setResizable(true);
+ column.setMoveable(true);
+ return viewerColumn;
+ }
+
+ private class RightsContentProvider implements IStructuredContentProvider {
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public Object[] getElements(Object inputElement) {
+ try {
+ AccessControlManager accessControlManager = currentNode
+ .getSession().getAccessControlManager();
+ Privilege[] privileges = accessControlManager
+ .getPrivileges(currentNode.getPath());
+ return privileges;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot retrieve rights", e);
+ }
+ }
+
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.PropertyDiff;
+import org.argeo.jcr.VersionDiff;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.providers.FullVersioningTreeContentProvider;
+import org.argeo.jcr.ui.explorer.providers.VersionLabelProvider;
+import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
+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.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TableWrapData;
+import org.eclipse.ui.forms.widgets.TableWrapLayout;
+
+/**
+ * Offers two main sections : one to display a text area with a summary of all
+ * variations between a version and its predecessor and one tree view that
+ * enable browsing
+ * */
+public class NodeVersionHistoryPage extends FormPage implements
+ JcrExplorerConstants {
+ // private final static Log log = LogFactory
+ // .getLog(NodeVersionHistoryPage.class);
+
+ // Utils
+ protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
+
+ // business objects
+ private Node currentNode;
+
+ // this page UI components
+ private FullVersioningTreeContentProvider nodeContentProvider;
+ private TreeViewer nodesViewer;
+ private FormToolkit tk;
+
+ public NodeVersionHistoryPage(FormEditor editor, String title,
+ Node currentNode) {
+ super(editor, "NodeVersionHistoryPage", title);
+ this.currentNode = currentNode;
+ }
+
+ protected void createFormContent(IManagedForm managedForm) {
+ ScrolledForm form = managedForm.getForm();
+ form.setText(JcrExplorerPlugin
+ .getMessage("nodeVersionHistoryPageTitle"));
+ tk = managedForm.getToolkit();
+ GridLayout twt = new GridLayout(1, false);
+ twt.marginWidth = twt.marginHeight = 5;
+ Composite body = form.getBody();
+ body.setLayout(twt);
+
+ try {
+ if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) {
+ tk.createLabel(body, JcrExplorerPlugin
+ .getMessage("warningUnversionableNode"));
+ } else {
+ createHistorySection(form.getBody());
+ createTreeSection(form.getBody());
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected error while checking if node is versionable", e);
+ }
+ }
+
+ protected void createTreeSection(Composite parent) {
+ // Section Layout & MetaData
+ Section section = tk.createSection(parent, Section.TWISTIE);
+ section.setLayoutData(new GridData(GridData.FILL_BOTH));
+ section.setText(JcrExplorerPlugin.getMessage("versionTreeSectionTitle"));
+
+ // Section Body
+ Composite body = tk.createComposite(section, SWT.FILL);
+ // WARNING : 2 following lines are compulsory or body won't be
+ // displayed.
+ body.setLayout(new GridLayout());
+ section.setClient(body);
+
+ body.setLayoutData(new GridData(GridData.FILL_BOTH));
+ section.setExpanded(true);
+
+ nodeContentProvider = new FullVersioningTreeContentProvider();
+ nodesViewer = createNodeViewer(body, nodeContentProvider);
+ nodesViewer.setInput(currentNode);
+ }
+
+ protected TreeViewer createNodeViewer(Composite parent,
+ final ITreeContentProvider nodeContentProvider) {
+
+ final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
+
+ tmpNodeViewer.getTree().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ tmpNodeViewer.setContentProvider(nodeContentProvider);
+ tmpNodeViewer.setLabelProvider(new VersionLabelProvider());
+ tmpNodeViewer
+ .addDoubleClickListener(new GenericNodeDoubleClickListener(
+ tmpNodeViewer));
+ return tmpNodeViewer;
+ }
+
+ protected void createHistorySection(Composite parent) {
+
+ // Section Layout
+ Section section = tk.createSection(parent, Section.TWISTIE);
+ section.setLayoutData(new GridData(TableWrapData.FILL_GRAB));
+ TableWrapLayout twt = new TableWrapLayout();
+ section.setLayout(twt);
+
+ // Set title of the section
+ section.setText(JcrExplorerPlugin
+ .getMessage("versionHistorySectionTitle"));
+
+ final Text styledText = tk.createText(section, "", SWT.FULL_SELECTION
+ | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
+ styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ section.setClient(styledText);
+ refreshHistory(styledText);
+ styledText.setEditable(false);
+ section.setExpanded(false);
+
+ AbstractFormPart part = new AbstractFormPart() {
+ public void commit(boolean onSave) {
+ }
+
+ public void refresh() {
+ super.refresh();
+ refreshHistory(styledText);
+ }
+ };
+ getManagedForm().addPart(part);
+ }
+
+ protected void refreshHistory(Text styledText) {
+ try {
+ List<VersionDiff> lst = listHistoryDiff();
+ StringBuffer main = new StringBuffer("");
+
+ for (int i = lst.size() - 1; i >= 0; i--) {
+ if (i == 0)
+ main.append("Creation (");
+ else
+ main.append("Update " + i + " (");
+
+ if (lst.get(i).getUserId() != null)
+ main.append("UserId : " + lst.get(i).getUserId());
+
+ if (lst.get(i).getUserId() != null
+ && lst.get(i).getUpdateTime() != null)
+ main.append(", ");
+
+ if (lst.get(i).getUpdateTime() != null)
+ main.append("Date : "
+ + timeFormatter.format(lst.get(i).getUpdateTime()
+ .getTime()) + ")\n");
+
+ StringBuffer buf = new StringBuffer("");
+ Map<String, PropertyDiff> diffs = lst.get(i).getDiffs();
+ for (String prop : diffs.keySet()) {
+ PropertyDiff pd = diffs.get(prop);
+ // String propName = pd.getRelPath();
+ Value refValue = pd.getReferenceValue();
+ Value newValue = pd.getNewValue();
+ String refValueStr = "";
+ String newValueStr = "";
+
+ if (refValue != null) {
+ if (refValue.getType() == PropertyType.DATE) {
+ refValueStr = timeFormatter.format(refValue
+ .getDate().getTime());
+ } else
+ refValueStr = refValue.getString();
+ }
+ if (newValue != null) {
+ if (newValue.getType() == PropertyType.DATE) {
+ newValueStr = timeFormatter.format(newValue
+ .getDate().getTime());
+ } else
+ newValueStr = newValue.getString();
+ }
+
+ if (pd.getType() == PropertyDiff.MODIFIED) {
+ buf.append(prop).append(": ");
+ buf.append(refValueStr);
+ buf.append(" > ");
+ buf.append(newValueStr);
+ buf.append("\n");
+ } else if (pd.getType() == PropertyDiff.ADDED
+ && !"".equals(newValueStr)) {
+ // we don't list property that have been added with an
+ // empty string as value
+ buf.append(prop).append(": ");
+ buf.append(" + ");
+ buf.append(newValueStr);
+ buf.append("\n");
+ } else if (pd.getType() == PropertyDiff.REMOVED) {
+ buf.append(prop).append(": ");
+ buf.append(" - ");
+ buf.append(refValueStr);
+ buf.append("\n");
+ }
+ }
+ buf.append("\n");
+ main.append(buf);
+ }
+ styledText.setText(main.toString());
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot generate history for node", e);
+ }
+
+ }
+
+ public List<VersionDiff> listHistoryDiff() {
+ try {
+ List<VersionDiff> res = new ArrayList<VersionDiff>();
+ VersionManager versionManager = currentNode.getSession()
+ .getWorkspace().getVersionManager();
+ VersionHistory versionHistory = versionManager
+ .getVersionHistory(currentNode.getPath());
+
+ VersionIterator vit = versionHistory.getAllLinearVersions();
+ while (vit.hasNext()) {
+ Version version = vit.nextVersion();
+ Node node = version.getFrozenNode();
+ Version predecessor = null;
+ try {
+ predecessor = version.getLinearPredecessor();
+ } catch (Exception e) {
+ // no predecessor seems to throw an exception even if it
+ // shouldn't...
+ }
+ if (predecessor == null) {// original
+ } else {
+ Map<String, PropertyDiff> diffs = JcrUtils.diffProperties(
+ predecessor.getFrozenNode(), node);
+ if (!diffs.isEmpty()) {
+ String lastUserName = null;
+ Calendar lastUpdate = null;
+ try {
+ if (currentNode
+ .isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+ lastUserName = node.getProperty(
+ Property.JCR_LAST_MODIFIED_BY)
+ .getString();
+ lastUpdate = node.getProperty(
+ Property.JCR_LAST_MODIFIED).getDate();
+ } else
+ lastUpdate = version.getProperty(
+ Property.JCR_CREATED).getDate();
+
+ } catch (Exception e) {
+ // Silent that info is optional
+ }
+ VersionDiff vd = new VersionDiff(lastUserName,
+ lastUpdate, diffs);
+ res.add(vd);
+ }
+ }
+ }
+ return res;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot generate history for node ");
+ }
+
+ }
+
+ @Override
+ public void setActive(boolean active) {
+ super.setActive(active);
+ }
+}
--- /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.jcr.ui.explorer.editors;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * An editor input based on three strings define a node :
+ * <ul>
+ * <li>complete path to the node</li>
+ * <li>the workspace name</li>
+ * <li>the repository alias</li>
+ * </ul>
+ * In a single workspace and/or repository environment, name and alias can be
+ * null.
+ *
+ * Note : unused for the time being.
+ */
+
+public class StringNodeEditorInput implements IEditorInput {
+ private final String path;
+ private final String repositoryAlias;
+ private final String workspaceName;
+
+ /**
+ * In order to implement a generic explorer that supports remote and multi
+ * workspaces repositories, node path can be detailed by these strings.
+ *
+ * @param repositoryAlias
+ * : can be null
+ * @param workspaceName
+ * : can be null
+ * @param path
+ */
+ public StringNodeEditorInput(String repositoryAlias, String workspaceName,
+ String path) {
+ this.path = path;
+ this.repositoryAlias = repositoryAlias;
+ this.workspaceName = workspaceName;
+ }
+
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return null;
+ }
+
+ public boolean exists() {
+ return true;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ public String getName() {
+ return path;
+ }
+
+ public String getRepositoryAlias() {
+ return repositoryAlias;
+ }
+
+ public String getWorkspaceName() {
+ return workspaceName;
+ }
+
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ public String getToolTipText() {
+ return path;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+
+ StringNodeEditorInput other = (StringNodeEditorInput) obj;
+
+ if (!path.equals(other.getPath()))
+ return false;
+
+ String own = other.getWorkspaceName();
+ if ((workspaceName == null && own != null)
+ || (workspaceName != null && (own == null || !workspaceName
+ .equals(own))))
+ return false;
+
+ String ora = other.getRepositoryAlias();
+ if ((repositoryAlias == null && ora != null)
+ || (repositoryAlias != null && (ora == null || !repositoryAlias
+ .equals(ora))))
+ return false;
+
+ return true;
+ }
+}
--- /dev/null
+## English labels for Agreo JCR UI application
+
+## Generic labels
+
+## Errors & warnings
+errorUnvalidNtFolderNodeType= Error: folder can only be created on a Jcr Node
+warningInvalidNodeToImport=Can only import to a node
+warningInvalidMultipleSelection=This functionality is implemented only on a single node for the time being.
+warningUnversionableNode= Current node is not versionable.
+warningNoChildNode= Current node has no child.
+
+## Commands
+getNodeSizeCmdLbl= Get approx. size
+addFolderNodeCmdLbl= Add Folder
+
+## GenericNodeEditor
+nodeEditorLbl=Generic node editor
+genericNodePageTitle=Properties
+childNodesPageTitle=Children
+nodeRightsManagementPageTitle=Rights
+nodeVersionHistoryPageTitle=History
+
+# History
+versionTreeSectionTitle=Version list
+versionHistorySectionTitle=History
+
+## Dummy ones
+testLbl=Internationalizations of messages seems to work properly.
--- /dev/null
+package org.argeo.jcr.ui.explorer.model;
+
+import javax.jcr.Repository;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.MaintainedRepository;
+
+/** Wraps a {@link MaintainedRepository} */
+public class MaintainedRepositoryElem extends RepositoryElem {
+
+ public MaintainedRepositoryElem(String alias, Repository repository,
+ TreeParent parent) {
+ super(alias, repository, parent);
+ if (!(repository instanceof MaintainedRepository)) {
+ throw new ArgeoException("Repository " + alias
+ + " is not amiantained repository");
+ }
+ }
+
+ protected MaintainedRepository getMaintainedRepository() {
+ return (MaintainedRepository) getRepository();
+ }
+}
--- /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.jcr.ui.explorer.model;
+
+import java.util.Arrays;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ArgeoJcrUtils;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.util.security.Keyring;
+
+/** Root of a remote repository */
+public class RemoteRepositoryElem extends RepositoryElem {
+ private final Keyring keyring;
+ /**
+ * A session of the logged in user on the default workspace of the node
+ * repository.
+ */
+ private final Session userSession;
+ private final String remoteNodePath;
+
+ private final RepositoryFactory repositoryFactory;
+ private final String uri;
+
+ public RemoteRepositoryElem(String alias,
+ RepositoryFactory repositoryFactory, String uri, TreeParent parent,
+ Session userSession, Keyring keyring, String remoteNodePath) {
+ super(alias, null, parent);
+ this.repositoryFactory = repositoryFactory;
+ this.uri = uri;
+ this.keyring = keyring;
+ this.userSession = userSession;
+ this.remoteNodePath = remoteNodePath;
+ }
+
+ @Override
+ protected Session repositoryLogin(String workspaceName)
+ throws RepositoryException {
+ Node remoteRepository = userSession.getNode(remoteNodePath);
+ String userID = remoteRepository.getProperty(ArgeoNames.ARGEO_USER_ID)
+ .getString();
+ String pwdPath = remoteRepository.getPath() + '/'
+ + ArgeoNames.ARGEO_PASSWORD;
+ char[] password = keyring.getAsChars(pwdPath);
+
+ try {
+ SimpleCredentials credentials = new SimpleCredentials(userID,
+ password);
+ return getRepository().login(credentials, workspaceName);
+ } finally {
+ Arrays.fill(password, 0, password.length, ' ');
+ }
+ }
+
+ @Override
+ public Repository getRepository() {
+ if (repository == null)
+ repository = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory,
+ uri);
+ return super.getRepository();
+ }
+
+ public void remove() {
+ try {
+ Node remoteNode = userSession.getNode(remoteNodePath);
+ remoteNode.remove();
+ remoteNode.getSession().save();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot remove " + remoteNodePath, e);
+ }
+ }
+
+}
--- /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.jcr.ui.explorer.model;
+
+import java.util.Map;
+
+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.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.MaintainedRepository;
+import org.argeo.jcr.RepositoryRegister;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.util.security.Keyring;
+
+/**
+ * UI Tree component. Implements the Argeo abstraction of a
+ * {@link RepositoryFactory} that enable a user to "mount" various repositories
+ * in a single Tree like View. It is usually meant to be at the root of the UI
+ * Tree and thus {@link getParent()} method will return null.
+ *
+ * The {@link RepositoryFactory} is injected at instantiation time and must be
+ * use get or register new {@link Repository} objects upon which a reference is
+ * kept here.
+ */
+
+public class RepositoriesElem extends TreeParent implements ArgeoNames {
+ private final RepositoryRegister repositoryRegister;
+ private final RepositoryFactory repositoryFactory;
+
+ /**
+ * A session of the logged in user on the default workspace of the node
+ * repository.
+ */
+ private final Session userSession;
+ private final Keyring keyring;
+
+ public RepositoriesElem(String name, RepositoryRegister repositoryRegister,
+ RepositoryFactory repositoryFactory, TreeParent parent,
+ Session userSession, Keyring keyring) {
+ super(name);
+ this.repositoryRegister = repositoryRegister;
+ this.repositoryFactory = repositoryFactory;
+ this.userSession = userSession;
+ this.keyring = keyring;
+ }
+
+ /**
+ * Override normal behavior to initialize the various repositories only at
+ * request time
+ */
+ @Override
+ public synchronized Object[] getChildren() {
+ if (isLoaded()) {
+ return super.getChildren();
+ } else {
+ // initialize current object
+ Map<String, Repository> refRepos = repositoryRegister
+ .getRepositories();
+ for (String name : refRepos.keySet()) {
+ Repository repository = refRepos.get(name);
+ if (repository instanceof MaintainedRepository)
+ super.addChild(new MaintainedRepositoryElem(name,
+ repository, this));
+ else
+ super.addChild(new RepositoryElem(name, repository, this));
+ }
+
+ // remote
+ if (keyring != null) {
+ try {
+ addRemoteRepositories(keyring);
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Cannot browse remote repositories", e);
+ }
+ }
+ return super.getChildren();
+ }
+ }
+
+ protected void addRemoteRepositories(Keyring jcrKeyring)
+ throws RepositoryException {
+ Node userHome = UserJcrUtils.getUserHome(userSession);
+ if (userHome != null && userHome.hasNode(ARGEO_REMOTE)) {
+ NodeIterator it = userHome.getNode(ARGEO_REMOTE).getNodes();
+ while (it.hasNext()) {
+ Node remoteNode = it.nextNode();
+ String uri = remoteNode.getProperty(ARGEO_URI).getString();
+ try {
+ RemoteRepositoryElem remoteRepositoryNode = new RemoteRepositoryElem(
+ remoteNode.getName(), repositoryFactory, uri, this,
+ userSession, jcrKeyring, remoteNode.getPath());
+ super.addChild(remoteRepositoryNode);
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot add remote repository "
+ + remoteNode, e);
+ }
+ }
+ }
+ }
+
+ public void registerNewRepository(String alias, Repository repository) {
+ // TODO: implement this
+ // Create a new RepositoryNode Object
+ // add it
+ // super.addChild(new RepositoriesNode(...));
+ }
+
+ /** Returns the {@link RepositoryRegister} wrapped by this object. */
+ public RepositoryRegister getRepositoryRegister() {
+ return repositoryRegister;
+ }
+}
--- /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.jcr.ui.explorer.model;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+
+/**
+ * UI Tree component. Wraps a JCR {@link Repository}. It also keeps a reference
+ * to its parent Tree Ui component; typically the unique {@link Repositories}
+ * object of the current view to enable bi-directionnal browsing in the tree.
+ */
+
+public class RepositoryElem extends TreeParent {
+ private String alias;
+ protected Repository repository;
+ private Session defaultSession = null;
+
+ /** Create a new repository with distinct name & alias */
+ public RepositoryElem(String alias, Repository repository, TreeParent parent) {
+ super(alias);
+ this.repository = repository;
+ setParent(parent);
+ this.alias = alias;
+ }
+
+ public void login() {
+ try {
+ defaultSession = repositoryLogin(null);
+ String[] wkpNames = defaultSession.getWorkspace()
+ .getAccessibleWorkspaceNames();
+ for (String wkpName : wkpNames) {
+ if (wkpName.equals(defaultSession.getWorkspace().getName()))
+ addChild(new WorkspaceElem(this, wkpName, defaultSession));
+ else
+ addChild(new WorkspaceElem(this, wkpName));
+ }
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot connect to repository " + alias, e);
+ }
+ }
+
+ /**
+ * Actual call to the
+ * {@link Repository#login(javax.jcr.Credentials, String)} method. To be
+ * overridden.
+ */
+ protected Session repositoryLogin(String workspaceName)
+ throws RepositoryException {
+ return repository.login(workspaceName);
+ }
+
+ public String[] getAccessibleWorkspaceNames() {
+ try {
+ return defaultSession.getWorkspace().getAccessibleWorkspaceNames();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot retrieve workspace names", e);
+ }
+ }
+
+ public void createWorkspace(String workspaceName) {
+ if (!isConnected())
+ login();
+ try {
+ defaultSession.getWorkspace().createWorkspace(workspaceName);
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot create workspace", e);
+ }
+ }
+
+ /** returns the {@link Repository} referenced by the current UI Node */
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public Boolean isConnected() {
+ if (defaultSession != null && defaultSession.isLive())
+ return true;
+ else
+ return false;
+ }
+}
--- /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.jcr.ui.explorer.model;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Workspace;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+
+/**
+ * UI Tree component. Wraps a node of a JCR {@link Workspace}. It also keeps a
+ * reference to its parent node that can either be a {@link WorkspaceElem}, a
+ * {@link SingleJcrNodeElem} or null if the node is "mounted" as the root of the UI
+ * tree.
+ */
+
+public class SingleJcrNodeElem extends TreeParent {
+
+ private final Node node;
+ private String alias = null;
+
+ // keeps a local reference to the node's name to avoid exception when the
+ // session is lost
+ // private final String name;
+
+ /** Creates a new UiNode in the UI Tree */
+ public SingleJcrNodeElem(TreeParent parent, Node node, String name) {
+ super(name);
+ setParent(parent);
+ this.node = node;
+ }
+
+ /**
+ * Creates a new UiNode in the UI Tree, keeping a reference to the alias of
+ * the corresponding repository in the current UI environment. It is useful
+ * to be able to mount nodes as roots of the UI tree.
+ */
+ public SingleJcrNodeElem(TreeParent parent, Node node, String name, String alias) {
+ super(name);
+ setParent(parent);
+ this.node = node;
+ this.alias = alias;
+ }
+
+ /** returns the node wrapped by the current Ui object */
+ public Node getNode() {
+ return node;
+ }
+
+ protected String getRepositoryAlias() {
+ return alias;
+ }
+
+ /**
+ * Override normal behavior to initialize children only when first requested
+ */
+ @Override
+ public synchronized Object[] getChildren() {
+ if (isLoaded()) {
+ return super.getChildren();
+ } else {
+ // initialize current object
+ try {
+ NodeIterator ni = node.getNodes();
+ while (ni.hasNext()) {
+ Node curNode = ni.nextNode();
+ addChild(new SingleJcrNodeElem(this, curNode, curNode.getName()));
+ }
+ return super.getChildren();
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexcpected error while initializing children SingleJcrNode",
+ re);
+ }
+ }
+ }
+
+ @Override
+ public boolean hasChildren() {
+ try {
+ if (node.getSession().isLive())
+ return node.hasNodes();
+ else
+ return false;
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while checking children node existence",
+ re);
+ }
+ }
+
+}
--- /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.jcr.ui.explorer.model;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Workspace;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.JcrUtils;
+
+/**
+ * UI Tree component. Wraps the root node of a JCR {@link Workspace}. It also
+ * keeps a reference to its parent {@link RepositoryElem}, to be able to
+ * retrieve alias of the current used repository
+ */
+public class WorkspaceElem extends TreeParent {
+ private Session session = null;
+
+ public WorkspaceElem(RepositoryElem parent, String name) {
+ this(parent, name, null);
+ }
+
+ public WorkspaceElem(RepositoryElem parent, String name, Session session) {
+ super(name);
+ this.session = session;
+ setParent(parent);
+ }
+
+ public Session getSession() {
+ return session;
+ }
+
+ public Node getRootNode() {
+ try {
+ if (session != null)
+ return session.getRootNode();
+ else
+ return null;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot get root node of workspace "
+ + getName(), e);
+ }
+ }
+
+ public void login() {
+ try {
+ session = ((RepositoryElem) getParent()).repositoryLogin(getName());
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot connect to repository "
+ + getName(), e);
+ }
+ }
+
+ public Boolean isConnected() {
+ if (session != null && session.isLive())
+ return true;
+ else
+ return false;
+ }
+
+ @Override
+ public synchronized void dispose() {
+ logout();
+ super.dispose();
+ }
+
+ /** Logouts the session, does not nothing if there is no live session. */
+ public void logout() {
+ clearChildren();
+ JcrUtils.logoutQuietly(session);
+ }
+
+ @Override
+ public boolean hasChildren() {
+ try {
+ if (isConnected())
+ return session.getRootNode().hasNodes();
+ else
+ return false;
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while checking children node existence",
+ re);
+ }
+ }
+
+ /** Override normal behaviour to initialize display of the workspace */
+ @Override
+ public synchronized Object[] getChildren() {
+ if (isLoaded()) {
+ return super.getChildren();
+ } else {
+ // initialize current object
+ try {
+ Node rootNode;
+ if (session == null)
+ return null;
+ else
+ rootNode = session.getRootNode();
+ NodeIterator ni = rootNode.getNodes();
+ while (ni.hasNext()) {
+ Node node = ni.nextNode();
+ addChild(new SingleJcrNodeElem(this, node, node.getName()));
+ }
+ return super.getChildren();
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Cannot initialize WorkspaceNode UI object."
+ + getName(), e);
+ }
+ }
+ }
+}
--- /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.jcr.ui.explorer.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Implementation of the {@code ITreeContentProvider} in order to display some
+ * version informations of a JCR full versionable node in a tree like structure
+ *
+ */
+public class FullVersioningTreeContentProvider implements ITreeContentProvider {
+ // private Node rootNode;
+ // private ItemComparator itemComparator = new ItemComparator();
+
+ /**
+ * Sends back the first level of the Tree. input element must be a single
+ * node object
+ */
+ public Object[] getElements(Object inputElement) {
+ try {
+ Node rootNode = (Node) inputElement;
+ String curPath = rootNode.getPath();
+ VersionManager vm = rootNode.getSession().getWorkspace()
+ .getVersionManager();
+
+ VersionHistory vh = vm.getVersionHistory(curPath);
+ List<Version> result = new ArrayList<Version>();
+ VersionIterator vi = vh.getAllLinearVersions();
+
+ while (vi.hasNext()) {
+ result.add(vi.nextVersion());
+ }
+ return result.toArray();
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while getting version elements", re);
+ }
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ try {
+ if (parentElement instanceof Version) {
+ List<Node> tmp = new ArrayList<Node>();
+ tmp.add(((Version) parentElement).getFrozenNode());
+ return tmp.toArray();
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unexpected error while getting child "
+ + "node for version element", re);
+ }
+ return null;
+ }
+
+ public Object getParent(Object element) {
+ try {
+ // this will not work in a simpleVersionning environment, parent is
+ // not a node.
+ if (element instanceof Node
+ && ((Node) element).isNodeType(NodeType.NT_FROZEN_NODE)) {
+ Node node = (Node) element;
+ return node.getParent();
+ } else
+ return null;
+ } catch (RepositoryException e) {
+ return null;
+ }
+ }
+
+ public boolean hasChildren(Object element) {
+ try {
+ if (element instanceof Version)
+ return true;
+ else if (element instanceof Node)
+ return ((Node) element).hasNodes();
+ else
+ return false;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot check children of " + element, e);
+ }
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+}
--- /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.jcr.ui.explorer.providers;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.ui.explorer.JcrExplorerConstants;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ViewerCell;
+
+public class PropertyLabelProvider extends ColumnLabelProvider implements
+ JcrExplorerConstants {
+
+ // To be able to change column order easily
+ public static final int COLUMN_PROPERTY = 0;
+ public static final int COLUMN_VALUE = 1;
+ public static final int COLUMN_ATTRIBUTES = 2;
+
+ // Utils
+ protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
+
+ public void update(ViewerCell cell) {
+ Object element = cell.getElement();
+ cell.setText(getColumnText(element, cell.getColumnIndex()));
+ // Image image = getImage(element);
+ // cell.setImage(image);
+ // cell.setBackground(getBackground(element));
+ // cell.setForeground(getForeground(element));
+ // cell.setFont(getFont(element));
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ try {
+ if (element instanceof Property) {
+ Property prop = (Property) element;
+ if (prop.isMultiple()) {
+ switch (columnIndex) {
+ case COLUMN_PROPERTY:
+ return prop.getName();
+ case COLUMN_VALUE:
+ // Corresponding values are listed on children
+ return "";
+ case COLUMN_ATTRIBUTES:
+ return JcrUtils.getPropertyDefinitionAsString(prop);
+ }
+ } else {
+ switch (columnIndex) {
+ case COLUMN_PROPERTY:
+ return prop.getName();
+ case COLUMN_VALUE:
+ return formatValueAsString(prop.getValue());
+ case COLUMN_ATTRIBUTES:
+ return JcrUtils.getPropertyDefinitionAsString(prop);
+ }
+ }
+ } else if (element instanceof Value) {
+ Value val = (Value) element;
+
+ switch (columnIndex) {
+ case COLUMN_PROPERTY:
+ // Nothing to show
+ return "";
+ case COLUMN_VALUE:
+ return formatValueAsString(val);
+ case COLUMN_ATTRIBUTES:
+ // Corresponding attributes are listed on the parent
+ return "";
+ }
+ }
+
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexepected error while getting property values", re);
+ }
+ return null;
+ }
+
+ private String formatValueAsString(Value value) {
+ // TODO enhance this method
+ try {
+ String strValue;
+
+ if (value.getType() == PropertyType.BINARY)
+ strValue = "<binary>";
+ else if (value.getType() == PropertyType.DATE)
+ strValue = timeFormatter.format(value.getDate().getTime());
+ else
+ strValue = value.getString();
+ return strValue;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("unexpected error while formatting value",
+ e);
+ }
+ }
+}
--- /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.jcr.ui.explorer.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Implementation of the {@code ITreeContentProvider} in order to display a
+ * single JCR node and its children in a tree like structure
+ *
+ */
+public class SingleNodeAsTreeContentProvider implements ITreeContentProvider {
+ // private Node rootNode;
+ private JcrItemsComparator itemComparator = new JcrItemsComparator();
+
+ /**
+ * Sends back the first level of the Tree. input element must be a single
+ * node object
+ */
+ public Object[] getElements(Object inputElement) {
+ try {
+ Node rootNode = (Node) inputElement;
+ List<Node> result = new ArrayList<Node>();
+ NodeIterator ni = rootNode.getNodes();
+ while (ni.hasNext()) {
+ result.add(ni.nextNode());
+ }
+
+ return result.toArray();
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while getting child nodes for children editor page ",
+ re);
+ }
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ return childrenNodes((Node) parentElement);
+ }
+
+ public Object getParent(Object element) {
+ try {
+ Node node = (Node) element;
+ if (!node.getPath().equals("/"))
+ return node.getParent();
+ else
+ return null;
+ } catch (RepositoryException e) {
+ return null;
+ }
+ }
+
+ public boolean hasChildren(Object element) {
+ try {
+ return ((Node) element).hasNodes();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot check children of " + element, e);
+ }
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ protected Object[] childrenNodes(Node parentNode) {
+ try {
+ List<Node> children = new ArrayList<Node>();
+ NodeIterator nit = parentNode.getNodes();
+ while (nit.hasNext()) {
+ Node node = nit.nextNode();
+ children.add(node);
+ }
+ Node[] arr = children.toArray(new Node[children.size()]);
+ Arrays.sort(arr, itemComparator);
+ return arr;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot list children of " + parentNode, e);
+ }
+ }
+}
--- /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.jcr.ui.explorer.providers;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.Version;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+/**
+ * simple wrapping of the ColumnLabelProvider class to provide text display in
+ * order to build a tree for version. The Get text method does not assume that
+ * Version extends Node class to respect JCR 2.0 specification
+ *
+ */
+public class VersionLabelProvider extends ColumnLabelProvider {
+
+ public String getText(Object element) {
+ try {
+ if (element instanceof Version) {
+ Version version = (Version) element;
+ return version.getName();
+ } else if (element instanceof Node) {
+ return ((Node) element).getName();
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while getting element name", re);
+ }
+ return super.getText(element);
+ }
+}
--- /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.jcr.ui.explorer.utils;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.utils.JcrFileProvider;
+import org.argeo.eclipse.ui.specific.FileHandler;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.editors.GenericNodeEditor;
+import org.argeo.jcr.ui.explorer.editors.GenericNodeEditorInput;
+import org.argeo.jcr.ui.explorer.model.RepositoryElem;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.ui.PartInitException;
+
+/**
+ * Centralizes the management of double click on a NodeTreeViewer
+ */
+public class GenericNodeDoubleClickListener implements IDoubleClickListener {
+
+ // private final static Log log = LogFactory
+ // .getLog(GenericNodeDoubleClickListener.class);
+
+ private TreeViewer nodeViewer;
+ private JcrFileProvider jfp;
+ private FileHandler fileHandler;
+
+ public GenericNodeDoubleClickListener(TreeViewer nodeViewer) {
+ this.nodeViewer = nodeViewer;
+ jfp = new JcrFileProvider();
+ // Commented out. see https://www.argeo.org/bugzilla/show_bug.cgi?id=188
+ fileHandler = null;
+ // fileHandler = new FileHandler(jfp);
+ }
+
+ public void doubleClick(DoubleClickEvent event) {
+ if (event.getSelection() == null || event.getSelection().isEmpty())
+ return;
+ Object obj = ((IStructuredSelection) event.getSelection())
+ .getFirstElement();
+ if (obj instanceof RepositoryElem) {
+ RepositoryElem rpNode = (RepositoryElem) obj;
+ if (!rpNode.isConnected()) {
+ rpNode.login();
+ nodeViewer.refresh(obj);
+ }
+ // else do nothing
+ } else if (obj instanceof WorkspaceElem) {
+ WorkspaceElem wn = (WorkspaceElem) obj;
+ if (wn.isConnected())
+ wn.logout();
+ else
+ wn.login();
+ nodeViewer.refresh(obj);
+ } else if (obj instanceof SingleJcrNodeElem) {
+ SingleJcrNodeElem sjn = (SingleJcrNodeElem) obj;
+ Node node = sjn.getNode();
+ try {
+ if (node.isNodeType(NodeType.NT_FILE)) {
+ // double click on a file node triggers its opening
+ String name = node.getName();
+ String id = node.getIdentifier();
+
+ // For the file provider to be able to browse the
+ // various
+ // repository.
+ // TODO : enhanced that.
+ // ITreeContentProvider itcp = (ITreeContentProvider)
+ // nodeViewer
+ // .getContentProvider();
+ jfp.setReferenceNode(node);
+ if (fileHandler != null)
+ fileHandler.openFile(name, id);
+ }
+ GenericNodeEditorInput gnei = new GenericNodeEditorInput(node);
+ JcrExplorerPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage()
+ .openEditor(gnei, GenericNodeEditor.ID);
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Repository error while getting node info", re);
+ } catch (PartInitException pie) {
+ throw new ArgeoException(
+ "Unexepected exception while opening node editor", pie);
+ }
+ }
+ }
+}
--- /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.jcr.ui.explorer.utils;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.ui.explorer.model.RepositoriesElem;
+import org.argeo.jcr.ui.explorer.model.RepositoryElem;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.model.WorkspaceElem;
+
+/** Centralizes some useful methods to build UIs with JCR */
+public class JcrUiUtils {
+
+ /** Insure that the UI component is not stale, refresh if needed */
+ public static void forceRefreshIfNeeded(TreeParent element) {
+ Node curNode = null;
+
+ boolean doRefresh = false;
+
+ try {
+ if (element instanceof SingleJcrNodeElem) {
+ curNode = ((SingleJcrNodeElem) element).getNode();
+ } else if (element instanceof WorkspaceElem) {
+ curNode = ((WorkspaceElem) element).getRootNode();
+ }
+
+ if (curNode != null
+ && element.getChildren().length != curNode.getNodes()
+ .getSize())
+ doRefresh = true;
+ else if (element instanceof RepositoryElem) {
+ RepositoryElem rn = (RepositoryElem) element;
+ if (rn.isConnected()) {
+ String[] wkpNames = rn.getAccessibleWorkspaceNames();
+ if (element.getChildren().length != wkpNames.length)
+ doRefresh = true;
+ }
+ } else if (element instanceof RepositoriesElem) {
+ doRefresh = true;
+ // Always force refresh for RepositoriesElem : the condition
+ // below does not take remote repository into account and it is
+ // not trivial to do so.
+
+ // RepositoriesElem rn = (RepositoriesElem) element;
+ // if (element.getChildren().length !=
+ // rn.getRepositoryRegister()
+ // .getRepositories().size())
+ // doRefresh = true;
+ }
+ if (doRefresh) {
+ element.clearChildren();
+ element.getChildren();
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while synchronising the UI with the JCR repository",
+ re);
+ }
+ }
+
+ /**
+ * Insure that a model element is inline with the underlying data by
+ * cleaning the corresponding subtree and building it again.
+ */
+ public static void forceRebuild(TreeParent element) {
+ // TODO implement this method if needed.
+ }
+ /**
+ * Workaround to get the alias of the repository that contains the given
+ * element. As we cannot browse the UI tree upward we recursively browse it
+ * downward until we find the given element
+ * */
+ // public static String getRepositoryAliasFromITreeElement(
+ // NodeContentProvider ncp, Object element) {
+ // RepositoryNode repositoryNode = null;
+ // if (element instanceof RepositoryNode)
+ // return ((RepositoryNode) element).getName();
+ // else if (element instanceof RepositoryRegister)
+ // throw new ArgeoException(
+ // "Cannot get alias for a repository register");
+ //
+ // // Get root elements
+ // Object[] elements = ncp.getElements(null);
+ //
+ // try {
+ // for (int i = 0; i < elements.length; i++) {
+ // if (elements[i] instanceof Node) {
+ // Node curNode = (Node) elements[i];
+ // if (curNode.isNodeType(ArgeoTypes.ARGEO_USER_HOME)) {
+ // // Do nothing, we'll find the node in the "normal" tree
+ // // and
+ // // get corresponding alias this way round
+ // } else
+ // throw new ArgeoException(
+ // "Normal nodes should not be at the root of NodeTreeViewer");
+ // } else if (elements[i] instanceof RepositoryRegister) {
+ // RepositoryRegister repositoryRegister = (RepositoryRegister) elements[i];
+ // Map<String, Repository> repositories = repositoryRegister
+ // .getRepositories();
+ //
+ // for (String name : repositories.keySet()) {
+ // boolean found = isElementInCurrentTreePart(
+ // ncp,
+ // new RepositoryNode(name, repositories.get(name)),
+ // (Node) element);
+ // if (found)
+ // return name;
+ // }
+ // } else
+ // throw new ArgeoException(
+ // "Unexpected object class at the root of NodeTreeViewer");
+ // }
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Unexpected error while retrieving Alias name", re);
+ // }
+ // return null;
+ // }
+ //
+ // /** implements the recursivity */
+ // private static boolean isElementInCurrentTreePart(NodeContentProvider
+ // ncp,
+ // Object parentElement, NodParente searchedElement) {
+ // boolean found = false;
+ // if (parentElement instanceof WorkspaceNode) {
+ // WorkspaceNode wn = (WorkspaceNode) parentElement;
+ // Object[] children = wn.getChildren();
+ // int i = children.length - 1;
+ // while (!found && i >= 0) {
+ // found = isElementInCurrentTreePart(ncp, children[i],
+ // searchedElement);
+ // }
+ // return found;
+ // } else if (parentElement instanceof RepositoryNode) {
+ // RepositoryNode rn = (RepositoryNode) parentElement;
+ // Object[] children = rn.getChildren();
+ // int i = children.length - 1;
+ // while (!found && i >= 0) {
+ // found = isElementInCurrentTreePart(ncp, children[i],
+ // searchedElement);
+ // }
+ // return found;
+ // } else {
+ // Node node = (Node) parentElement;
+ // if (node.equals(searchedElement))
+ // return true;
+ // NodeIterator ni;
+ // try {
+ // ni = node.getNodes();
+ // while (!found && ni.hasNext()) {
+ // found = isElementInCurrentTreePart(ncp, ni.nextNode(),
+ // searchedElement);
+ // }
+ // } catch (RepositoryException e) {
+ // throw new ArgeoException("unexpected erreur while recursively"
+ // + " recovering RepositoryNode for selected object", e);
+ // }
+ //
+ // return found;
+ // }
+ // }
+}
--- /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.jcr.ui.explorer.utils;
+
+import java.util.Comparator;
+
+import org.argeo.eclipse.ui.TreeParent;
+
+public class TreeObjectsComparator implements Comparator<TreeParent> {
+ public int compare(TreeParent o1, TreeParent o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+}
\ 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.jcr.ui.explorer.views;
+
+import java.util.List;
+
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.ObservationManager;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;
+import org.argeo.eclipse.ui.jcr.utils.NodeViewerComparer;
+import org.argeo.eclipse.ui.jcr.views.AbstractJcrBrowser;
+import org.argeo.jcr.RepositoryRegister;
+import org.argeo.jcr.ui.explorer.JcrExplorerPlugin;
+import org.argeo.jcr.ui.explorer.browser.NodeContentProvider;
+import org.argeo.jcr.ui.explorer.browser.NodeLabelProvider;
+import org.argeo.jcr.ui.explorer.browser.PropertiesContentProvider;
+import org.argeo.jcr.ui.explorer.model.SingleJcrNodeElem;
+import org.argeo.jcr.ui.explorer.utils.GenericNodeDoubleClickListener;
+import org.argeo.jcr.ui.explorer.utils.JcrUiUtils;
+import org.argeo.util.security.Keyring;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+
+/**
+ * Basic View to display a sash form to browse a JCR compliant multirepository
+ * environment
+ */
+public class GenericJcrBrowser extends AbstractJcrBrowser {
+ public final static String ID = JcrExplorerPlugin.ID + ".browserView";
+ private boolean sortChildNodes = true;
+
+ /* DEPENDENCY INJECTION */
+ private Keyring keyring;
+ private RepositoryRegister repositoryRegister;
+ private RepositoryFactory repositoryFactory;
+ private Repository nodeRepository;
+ /**
+ * A session of the logged in user on the default workspace of the node
+ * repository.
+ */
+ private Session userSession;
+
+ // This page widgets
+ private TreeViewer nodesViewer;
+ private NodeContentProvider nodeContentProvider;
+ private TableViewer propertiesViewer;
+ private EventListener resultsObserver;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new FillLayout());
+ SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
+ sashForm.setSashWidth(4);
+ sashForm.setLayout(new FillLayout());
+
+ // Create the tree on top of the view
+ Composite top = new Composite(sashForm, SWT.NONE);
+ GridLayout gl = new GridLayout(1, false);
+ top.setLayout(gl);
+
+ try {
+ this.userSession = this.nodeRepository.login();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot open user session", e);
+ }
+
+ nodeContentProvider = new NodeContentProvider(userSession, keyring,
+ repositoryRegister, repositoryFactory, sortChildNodes);
+
+ // nodes viewer
+ nodesViewer = createNodeViewer(top, nodeContentProvider);
+
+ // context menu : it is completely defined in the plugin.xml file.
+ MenuManager menuManager = new MenuManager();
+ Menu menu = menuManager.createContextMenu(nodesViewer.getTree());
+
+ nodesViewer.getTree().setMenu(menu);
+ getSite().registerContextMenu(menuManager, nodesViewer);
+ getSite().setSelectionProvider(nodesViewer);
+
+ nodesViewer.setInput(getViewSite());
+
+ // Create the property viewer on the bottom
+ Composite bottom = new Composite(sashForm, SWT.NONE);
+ bottom.setLayout(new GridLayout(1, false));
+ propertiesViewer = createPropertiesViewer(bottom);
+
+ sashForm.setWeights(getWeights());
+ nodesViewer.setComparer(new NodeViewerComparer());
+ }
+
+ @Override
+ public void refresh(Object obj) {
+ // Enable full refresh from a command when no element of the tree is
+ // selected
+ if (obj == null) {
+ Object[] elements = nodeContentProvider.getElements(null);
+ for (Object el : elements) {
+ if (el instanceof TreeParent)
+ JcrUiUtils.forceRefreshIfNeeded((TreeParent) el);
+ getNodeViewer().refresh(el);
+ }
+ }
+ super.refresh(obj);
+ }
+
+ /**
+ * To be overridden to adapt size of form and result frames.
+ */
+ protected int[] getWeights() {
+ return new int[] { 70, 30 };
+ }
+
+ protected TreeViewer createNodeViewer(Composite parent,
+ final ITreeContentProvider nodeContentProvider) {
+
+ final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
+
+ tmpNodeViewer.getTree().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ tmpNodeViewer.setContentProvider(nodeContentProvider);
+ tmpNodeViewer.setLabelProvider(new NodeLabelProvider());
+ tmpNodeViewer
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (!event.getSelection().isEmpty()) {
+ IStructuredSelection sel = (IStructuredSelection) event
+ .getSelection();
+ Object firstItem = sel.getFirstElement();
+ if (firstItem instanceof SingleJcrNodeElem)
+ propertiesViewer
+ .setInput(((SingleJcrNodeElem) firstItem)
+ .getNode());
+ } else {
+ propertiesViewer.setInput(getViewSite());
+ }
+ }
+ });
+
+ resultsObserver = new TreeObserver(tmpNodeViewer.getTree().getDisplay());
+ if (keyring != null)
+ try {
+ ObservationManager observationManager = userSession
+ .getWorkspace().getObservationManager();
+ observationManager.addEventListener(resultsObserver,
+ Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED, "/",
+ true, null, null, false);
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot register listeners", e);
+ }
+
+ tmpNodeViewer
+ .addDoubleClickListener(new GenericNodeDoubleClickListener(
+ tmpNodeViewer));
+ return tmpNodeViewer;
+ }
+
+ protected TableViewer createPropertiesViewer(Composite parent) {
+ propertiesViewer = new TableViewer(parent);
+ propertiesViewer.getTable().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, true, true));
+ propertiesViewer.getTable().setHeaderVisible(true);
+ propertiesViewer.setContentProvider(new PropertiesContentProvider());
+ TableViewerColumn col = new TableViewerColumn(propertiesViewer,
+ SWT.NONE);
+ col.getColumn().setText("Name");
+ col.getColumn().setWidth(200);
+ col.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ try {
+ return ((Property) element).getName();
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected exception in label provider", e);
+ }
+ }
+ });
+ col = new TableViewerColumn(propertiesViewer, SWT.NONE);
+ col.getColumn().setText("Value");
+ col.getColumn().setWidth(400);
+ col.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ try {
+ Property property = (Property) element;
+ if (property.getType() == PropertyType.BINARY)
+ return "<binary>";
+ else if (property.isMultiple()) {
+ StringBuffer buf = new StringBuffer("[");
+ Value[] values = property.getValues();
+ for (int i = 0; i < values.length; i++) {
+ if (i != 0)
+ buf.append(", ");
+ buf.append(values[i].getString());
+ }
+ buf.append(']');
+ return buf.toString();
+ } else
+ return property.getValue().getString();
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected exception in label provider", e);
+ }
+ }
+ });
+ col = new TableViewerColumn(propertiesViewer, SWT.NONE);
+ col.getColumn().setText("Type");
+ col.getColumn().setWidth(200);
+ col.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ try {
+ return PropertyType.nameFromValue(((Property) element)
+ .getType());
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Unexpected exception in label provider", e);
+ }
+ }
+ });
+ propertiesViewer.setInput(getViewSite());
+ return propertiesViewer;
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ }
+
+ @Override
+ protected TreeViewer getNodeViewer() {
+ return nodesViewer;
+ }
+
+ /**
+ * Resets the tree content provider
+ *
+ * @param sortChildNodes
+ * if true the content provider will use a comparer to sort nodes
+ * that might slow down the display
+ * */
+ public void setSortChildNodes(boolean sortChildNodes) {
+ this.sortChildNodes = sortChildNodes;
+ ((NodeContentProvider) nodesViewer.getContentProvider())
+ .setSortChildren(sortChildNodes);
+ nodesViewer.setInput(getViewSite());
+ }
+
+ /** Notifies the current view that a node has been added */
+ public void nodeAdded(TreeParent parentNode) {
+ // insure that Ui objects have been correctly created:
+ JcrUiUtils.forceRefreshIfNeeded(parentNode);
+ getNodeViewer().refresh(parentNode);
+ getNodeViewer().expandToLevel(parentNode, 1);
+ }
+
+ /** Notifies the current view that a node has been removed */
+ public void nodeRemoved(TreeParent parentNode) {
+ IStructuredSelection newSel = new StructuredSelection(parentNode);
+ getNodeViewer().setSelection(newSel, true);
+ // Force refresh
+ IStructuredSelection tmpSel = (IStructuredSelection) getNodeViewer()
+ .getSelection();
+ getNodeViewer().refresh(tmpSel.getFirstElement());
+ }
+
+ class TreeObserver extends AsyncUiEventListener {
+
+ public TreeObserver(Display display) {
+ super(display);
+ }
+
+ @Override
+ protected Boolean willProcessInUiThread(List<Event> events)
+ throws RepositoryException {
+ for (Event event : events) {
+ if (getLog().isTraceEnabled())
+ getLog().debug("Received event " + event);
+ String path = event.getPath();
+ int index = path.lastIndexOf('/');
+ String propertyName = path.substring(index + 1);
+ if (getLog().isTraceEnabled())
+ getLog().debug("Concerned property " + propertyName);
+ }
+ return false;
+ }
+
+ protected void onEventInUiThread(List<Event> events)
+ throws RepositoryException {
+ if (getLog().isTraceEnabled())
+ getLog().trace("Refresh result list");
+ nodesViewer.refresh();
+ }
+
+ }
+
+ public boolean getSortChildNodes() {
+ return sortChildNodes;
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
+ this.repositoryRegister = repositoryRegister;
+ }
+
+ public void setKeyring(Keyring keyring) {
+ this.keyring = keyring;
+ }
+
+ public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+ this.repositoryFactory = repositoryFactory;
+ }
+
+ public void setNodeRepository(Repository nodeRepository) {
+ this.nodeRepository = nodeRepository;
+ }
+
+}
--- /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.jcr.ui.explorer.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;
+ private String path;
+
+ // This page widget
+ private ChooseRightsPage page;
+
+ public ChangeRightsWizard(Session currentSession, String path) {
+ super();
+ this.currentSession = currentSession;
+ this.path = path;
+ }
+
+ @Override
+ public void addPages() {
+ try {
+ page = new ChooseRightsPage(path);
+ 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, path, page.getGroupName(),
+ page.getAuthTypeStr());
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unexpected error while setting privileges", re);
+ }
+ return true;
+ }
+}
--- /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.jcr.ui.explorer.wizards;
+
+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;
+
+ // USABLE SHORTCUTS
+ protected final static String[] validAuthType = { Privilege.JCR_READ,
+ Privilege.JCR_WRITE, Privilege.JCR_ALL };
+
+ public ChooseRightsPage(String path) {
+ super("Main");
+ setTitle("Add privilege to " + path);
+ }
+
+ 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());
+ }
+
+ 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 the name of the corresponding group.";
+ // Remove regexp check for the time being.
+ // else if (!match(groupStr))
+ // return
+ // "Please use only alphanumerical chars for the short technical name.";
+ return null;
+ }
+}
--- /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.jcr.ui.explorer.wizards;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+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.eclipse.ui.specific.ImportToServerWizardPage;
+import org.argeo.eclipse.ui.specific.UploadFileWizardPage;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+
+public class ImportFileSystemWizard extends Wizard {
+ private final static Log log = LogFactory
+ .getLog(ImportFileSystemWizard.class);
+
+ private UploadFileWizardPage importPage;
+ private final Node folder;
+
+ public ImportFileSystemWizard(Node folder) {
+ this.folder = folder;
+ setWindowTitle("Import from file system");
+ }
+
+ @Override
+ public void addPages() {
+ importPage = new UploadFileWizardPage();
+ addPage(importPage);
+ setNeedsProgressMonitor(importPage.getNeedsProgressMonitor());
+ }
+
+ /**
+ * Called when the user click on 'Finish' in the wizard. The real upload to
+ * the JCR repository is done here.
+ */
+ @Override
+ public boolean performFinish() {
+
+ // Initialization
+ final String objectType = importPage.getObjectType();
+ final String objectPath = importPage.getObjectPath();
+
+ // We do not display a progress bar for one file only
+ if (ImportToServerWizardPage.FILE_ITEM_TYPE.equals(objectType)) {
+ // In Rap we must force the "real" upload of the file
+ importPage.performFinish();
+ try {
+ Node fileNode = folder.addNode(importPage.getObjectName(),
+ NodeType.NT_FILE);
+ Node resNode = fileNode.addNode(Property.JCR_CONTENT,
+ NodeType.NT_RESOURCE);
+ Binary binary = null;
+ try {
+ binary = folder.getSession().getValueFactory()
+ .createBinary(importPage.getFileInputStream());
+ resNode.setProperty(Property.JCR_DATA, binary);
+ } finally {
+ if (binary != null)
+ binary.dispose();
+ IOUtils.closeQuietly(importPage.getFileInputStream());
+ }
+ folder.getSession().save();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ } else if (ImportToServerWizardPage.FOLDER_ITEM_TYPE.equals(objectType)) {
+ if (objectPath == null || !new File(objectPath).exists()) {
+ ErrorFeedback.show("Directory " + objectPath
+ + " does not exist");
+ return false;
+ }
+
+ Boolean failed = false;
+ final File dir = new File(objectPath).getAbsoluteFile();
+ final Long sizeB = directorySize(dir, 0l);
+ final Stats stats = new Stats();
+ Long begin = System.currentTimeMillis();
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ try {
+ Integer sizeKB = (int) (sizeB / FileUtils.ONE_KB);
+ monitor.beginTask("", sizeKB);
+ importDirectory(folder, dir, monitor, stats);
+ monitor.done();
+ } catch (Exception e) {
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ else
+ throw new ArgeoException("Cannot import "
+ + objectPath, e);
+ }
+ }
+ });
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot import " + objectPath, e);
+ failed = true;
+ }
+
+ Long duration = System.currentTimeMillis() - begin;
+ Long durationS = duration / 1000l;
+ String durationStr = (durationS / 60) + " min " + (durationS % 60)
+ + " s";
+ StringBuffer message = new StringBuffer("Imported\n");
+ message.append(stats.fileCount).append(" files\n");
+ message.append(stats.dirCount).append(" directories\n");
+ message.append(FileUtils.byteCountToDisplaySize(stats.sizeB));
+ if (failed)
+ message.append(" of planned ").append(
+ FileUtils.byteCountToDisplaySize(sizeB));
+ message.append("\n");
+ message.append("in ").append(durationStr).append("\n");
+ if (failed)
+ MessageDialog.openError(getShell(), "Import failed",
+ message.toString());
+ else
+ MessageDialog.openInformation(getShell(), "Import successful",
+ message.toString());
+
+ return true;
+ }
+ return false;
+
+ }
+
+ /** Recursively computes the size of the directory in bytes. */
+ protected Long directorySize(File dir, Long currentSize) {
+ Long size = currentSize;
+ File[] files = dir.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+ size = directorySize(file, size);
+ } else {
+ size = size + file.length();
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Import recursively a directory and its content to the repository.
+ */
+ protected void importDirectory(Node folder, File dir,
+ IProgressMonitor monitor, Stats stats) {
+ try {
+ File[] files = dir.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+ Node childFolder = folder.addNode(file.getName(),
+ NodeType.NT_FOLDER);
+ importDirectory(childFolder, file, monitor, stats);
+ folder.getSession().save();
+ stats.dirCount++;
+ } else {
+ Long fileSize = file.length();
+
+ // we skip tempory files that are created by apps when a
+ // file is being edited.
+ // TODO : make this configurable.
+ if (file.getName().lastIndexOf('~') != file.getName()
+ .length() - 1) {
+
+ monitor.subTask(file.getName() + " ("
+ + FileUtils.byteCountToDisplaySize(fileSize)
+ + ") " + file.getCanonicalPath());
+ try {
+ Node fileNode = folder.addNode(file.getName(),
+ NodeType.NT_FILE);
+ Node resNode = fileNode.addNode(
+ Property.JCR_CONTENT, NodeType.NT_RESOURCE);
+ Binary binary = null;
+ try {
+ binary = folder
+ .getSession()
+ .getValueFactory()
+ .createBinary(new FileInputStream(file));
+ resNode.setProperty(Property.JCR_DATA, binary);
+ } finally {
+ if (binary != null)
+ binary.dispose();
+ }
+ folder.getSession().save();
+ stats.fileCount++;
+ stats.sizeB = stats.sizeB + fileSize;
+ } catch (Exception e) {
+ log.warn("Import of "
+ + file
+ + " ("
+ + FileUtils
+ .byteCountToDisplaySize(fileSize)
+ + ") failed: " + e);
+ folder.getSession().refresh(false);
+ }
+ monitor.worked((int) (fileSize / FileUtils.ONE_KB));
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot import " + dir + " to " + folder,
+ e);
+ }
+ }
+
+ static class Stats {
+ public Long fileCount = 0l;
+ public Long dirCount = 0l;
+ public Long sizeB = 0l;
+ }
+}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>>>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
+++ /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.osgi.ui.explorer;
-
-import org.eclipse.swt.graphics.Image;
-
-/** Shared icons. */
-public class OsgiExplorerImages {
- public final static Image INSTALLED = OsgiExplorerPlugin
- .getImageDescriptor("icons/installed.gif").createImage();
- public final static Image RESOLVED = OsgiExplorerPlugin.getImageDescriptor(
- "icons/resolved.gif").createImage();
- public final static Image STARTING = OsgiExplorerPlugin.getImageDescriptor(
- "icons/starting.gif").createImage();
- public final static Image ACTIVE = OsgiExplorerPlugin.getImageDescriptor(
- "icons/active.gif").createImage();
-}
+++ /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.osgi.ui.explorer;
-
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-/** OSGi explorer perspective (to be enriched declaratively) */
-public class OsgiExplorerPerspective implements IPerspectiveFactory {
-
- public void createInitialLayout(IPageLayout layout) {
- layout.setEditorAreaVisible(true);
- layout.setFixed(false);
-
- }
-
-}
+++ /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.osgi.ui.explorer;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class OsgiExplorerPlugin extends AbstractUIPlugin {
-
- // The plug-in ID
- public static final String PLUGIN_ID = "org.argeo.osgi.ui.explorer"; //$NON-NLS-1$
-
- // The shared instance
- private static OsgiExplorerPlugin plugin;
-
- /**
- * The constructor
- */
- public OsgiExplorerPlugin() {
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
- * )
- */
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
- * )
- */
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- super.stop(context);
- }
-
- /**
- * Returns the shared instance
- *
- * @return the shared instance
- */
- public static OsgiExplorerPlugin getDefault() {
- return plugin;
- }
-
- public static ImageDescriptor getImageDescriptor(String path) {
- return imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
-
-}
+++ /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.osgi.ui.explorer.views;
-
-import java.util.Comparator;
-
-import org.argeo.eclipse.ui.ColumnViewerComparator;
-import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
-import org.argeo.osgi.ui.explorer.OsgiExplorerImages;
-import org.argeo.osgi.ui.explorer.OsgiExplorerPlugin;
-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.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.part.ViewPart;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-
-/**
- * Overview of the bundles as a table. Equivalent to Equinox 'ss' console
- * command.
- */
-public class BundlesView extends ViewPart {
- private TableViewer viewer;
-
- @Override
- public void createPartControl(Composite parent) {
- viewer = new TableViewer(parent);
- viewer.setContentProvider(new BundleContentProvider());
- viewer.getTable().setHeaderVisible(true);
-
- EclipseUiSpecificUtils.enableToolTipSupport(viewer);
-
- // ID
- TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setWidth(30);
- column.getColumn().setText("ID");
- column.getColumn().setAlignment(SWT.RIGHT);
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- return Long.toString(((Bundle) element).getBundleId());
- }
- });
- new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
- public int compare(Bundle o1, Bundle o2) {
- return (int) (o1.getBundleId() - o2.getBundleId());
- }
- });
-
- // State
- column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setWidth(18);
- column.getColumn().setText("State");
- column.setLabelProvider(new StateLabelProvider());
- new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
- public int compare(Bundle o1, Bundle o2) {
- return o1.getState() - o2.getState();
- }
- });
-
- // Symbolic name
- column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setWidth(300);
- column.getColumn().setText("Symbolic Name");
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- return ((Bundle) element).getSymbolicName();
- }
- });
- new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
- public int compare(Bundle o1, Bundle o2) {
- return o1.getSymbolicName().compareTo(o2.getSymbolicName());
- }
- });
-
- // Version
- column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setWidth(150);
- column.getColumn().setText("Version");
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- return ((Bundle) element).getVersion().toString();
- }
- });
- new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
- public int compare(Bundle o1, Bundle o2) {
- return o1.getVersion().compareTo(o2.getVersion());
- }
- });
-
- viewer.setInput(OsgiExplorerPlugin.getDefault().getBundle()
- .getBundleContext());
-
- }
-
- @Override
- public void setFocus() {
- if (viewer != null)
- viewer.getControl().setFocus();
- }
-
- /** Content provider managing the array of bundles */
- private static class BundleContentProvider implements
- IStructuredContentProvider {
- public Object[] getElements(Object inputElement) {
- if (inputElement instanceof BundleContext) {
- BundleContext bc = (BundleContext) inputElement;
- return bc.getBundles();
- }
- return null;
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- }
-
- /** Label provider for the state column */
- private static class StateLabelProvider extends ColumnLabelProvider {
- @Override
- public Image getImage(Object element) {
- Integer state = ((Bundle) element).getState();
- switch (state) {
- case Bundle.UNINSTALLED:
- return OsgiExplorerImages.INSTALLED;
- case Bundle.INSTALLED:
- return OsgiExplorerImages.INSTALLED;
- case Bundle.RESOLVED:
- return OsgiExplorerImages.RESOLVED;
- case Bundle.STARTING:
- return OsgiExplorerImages.STARTING;
- case Bundle.STOPPING:
- return OsgiExplorerImages.STARTING;
- case Bundle.ACTIVE:
- return OsgiExplorerImages.ACTIVE;
- default:
- return null;
- }
- }
-
- @Override
- public String getText(Object element) {
- return null;
- }
-
- @Override
- public String getToolTipText(Object element) {
- Bundle bundle = (Bundle) element;
- Integer state = bundle.getState();
- switch (state) {
- case Bundle.UNINSTALLED:
- return "UNINSTALLED";
- case Bundle.INSTALLED:
- return "INSTALLED";
- case Bundle.RESOLVED:
- return "RESOLVED";
- case Bundle.STARTING:
- String activationPolicy = bundle.getHeaders()
- .get(Constants.BUNDLE_ACTIVATIONPOLICY).toString();
- if (activationPolicy != null
- && activationPolicy.equals(Constants.ACTIVATION_LAZY))
- return "<<LAZY>>";
- return "STARTING";
- case Bundle.STOPPING:
- return "STOPPING";
- case Bundle.ACTIVE:
- return "ACTIVE";
- default:
- return null;
- }
- }
-
- }
-}
+++ /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.osgi.ui.explorer.views;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.osgi.ui.explorer.OsgiExplorerPlugin;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.part.ViewPart;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-
-/** <b>Experimental</b> The OSGi runtime from a module perspective. */
-public class ModulesView extends ViewPart {
- private final static Log log = LogFactory.getLog(ModulesView.class);
-
- private TreeViewer viewer;
-
- private PackageAdmin packageAdmin;
-
- private Comparator<ExportedPackage> exportedPackageComparator = new Comparator<ExportedPackage>() {
-
- public int compare(ExportedPackage o1, ExportedPackage o2) {
- if (!o1.getName().equals(o2.getName()))
- return o1.getName().compareTo(o2.getName());
- else
- return o1.getVersion().compareTo(o2.getVersion());
- }
- };
-
- @Override
- public void createPartControl(Composite parent) {
- viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
- viewer.setContentProvider(new ModulesContentProvider());
- viewer.setLabelProvider(new ModulesLabelProvider());
- viewer.setInput(OsgiExplorerPlugin.getDefault().getBundle()
- .getBundleContext());
- }
-
- @Override
- public void setFocus() {
- viewer.getTree().setFocus();
- }
-
- private class ModulesContentProvider implements ITreeContentProvider {
-
- public Object[] getElements(Object inputElement) {
- return getChildren(inputElement);
- }
-
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof BundleContext) {
- BundleContext bundleContext = (BundleContext) parentElement;
- Bundle[] bundles = bundleContext.getBundles();
-
- TreeParent bundlesNode = new TreeParent("Bundles");
- for (Bundle bundle : bundles) {
- if (bundle.getState() == Bundle.ACTIVE)
- bundlesNode.addChild(new BundleNode(bundle));
- }
-
- // scan packages
- ServiceReference paSr = bundleContext
- .getServiceReference(PackageAdmin.class.getName());
- // TODO: make a cleaner referencing
- packageAdmin = (PackageAdmin) bundleContext.getService(paSr);
-
- Bundle bundle1 = null;
- Bundle bundle2 = null;
-
- Map<Bundle, Set<ExportedPackage>> importedPackages = new HashMap<Bundle, Set<ExportedPackage>>();
- Map<String, Set<ExportedPackage>> packages = new TreeMap<String, Set<ExportedPackage>>();
- for (Bundle bundle : bundles) {
- if (bundle.getSymbolicName()
- .equals("org.argeo.security.ui"))
- bundle1 = bundle;
- if (bundle.getSymbolicName().equals(
- "org.argeo.security.equinox"))
- bundle2 = bundle;
-
- ExportedPackage[] pkgs = packageAdmin
- .getExportedPackages(bundle);
- if (pkgs != null)
- for (ExportedPackage pkg : pkgs) {
- if (!packages.containsKey(pkg.getName()))
- packages.put(pkg.getName(),
- new TreeSet<ExportedPackage>(
- exportedPackageComparator));
- Set<ExportedPackage> expPackages = (Set<ExportedPackage>) packages
- .get(pkg.getName());
- expPackages.add(pkg);
-
- // imported
- for (Bundle b : pkg.getImportingBundles()) {
- if (bundle.getBundleId() != b.getBundleId()) {
- if (!importedPackages.containsKey(b))
- importedPackages
- .put(b,
- new TreeSet<ExportedPackage>(
- exportedPackageComparator));
- Set<ExportedPackage> impPackages = (Set<ExportedPackage>) importedPackages
- .get(b);
- impPackages.add(pkg);
- }
- }
- }
- }
-
- TreeParent mPackageNode = new TreeParent("Multiple Packages");
- // TreeParent aPackageNode = new TreeParent("All Packages");
- for (String packageName : packages.keySet()) {
- Set<ExportedPackage> pkgs = packages.get(packageName);
- if (pkgs.size() > 1) {
- MultiplePackagesNode mpn = new MultiplePackagesNode(
- packageName, pkgs);
- mPackageNode.addChild(mpn);
- // aPackageNode.addChild(mpn);
- } else {
- // aPackageNode.addChild(new ExportedPackageNode(pkgs
- // .iterator().next()));
- }
- }
-
- return new Object[] { bundlesNode, mPackageNode };// ,
- // aPackageNode
- // };
- } else if (parentElement instanceof TreeParent) {
- return ((TreeParent) parentElement).getChildren();
- } else {
- return null;
- }
- }
-
- public Object getParent(Object element) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public boolean hasChildren(Object element) {
- if (element instanceof TreeParent) {
- return ((TreeParent) element).hasChildren();
- }
- return false;
- }
-
- public void dispose() {
- // TODO Auto-generated method stub
-
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- // TODO Auto-generated method stub
-
- }
-
- }
-
- protected Map<String, ExportedPackage> dependencySpace(Bundle bundle,
- Map<Bundle, Set<ExportedPackage>> importedPackages,
- Map<String, Set<String>> traces) {
- log.debug("Dependency space for " + bundle.getSymbolicName());
- Map<String, ExportedPackage> space = new TreeMap<String, ExportedPackage>();
- fillDependencySpace(space, bundle, importedPackages,
- bundle.getSymbolicName(), traces);
- return space;
- }
-
- /** Recursive */
- protected void fillDependencySpace(Map<String, ExportedPackage> space,
- Bundle bundle, Map<Bundle, Set<ExportedPackage>> importedPackages,
- String currTrace, Map<String, Set<String>> traces) {
- if (importedPackages.containsKey(bundle)) {
- Set<ExportedPackage> imports = importedPackages.get(bundle);
- // log.debug("## Fill dependency space for " + bundle + " : ");
- for (ExportedPackage pkg : imports) {
- if (!traces.containsKey(pkg.getName()))
- traces.put(pkg.getName(), new TreeSet<String>());
- traces.get(pkg.getName()).add(currTrace);
- if (!space.containsKey(pkg.getName())) {
- space.put(pkg.getName(), pkg);
- Bundle exportingBundle = pkg.getExportingBundle();
- // if (bundle.getBundleId() !=
- // exportingBundle.getBundleId())
- fillDependencySpace(space, exportingBundle,
- importedPackages, currTrace + " > "
- + exportingBundle.getSymbolicName(), traces);
- }
- }
- }
- }
-
- private class ModulesLabelProvider extends LabelProvider implements
- ITableLabelProvider {
-
- public Image getColumnImage(Object element, int columnIndex) {
- // TODO Auto-generated method stub
- return null;
- }
-
- public String getColumnText(Object element, int columnIndex) {
- return getText(element);
- }
-
- }
-
- class BundleNode extends TreeParent {
- private final Bundle bundle;
-
- public BundleNode(Bundle bundle) {
- super(bundle.getSymbolicName());
- this.bundle = bundle;
-
- // Registered services
- ServiceReference[] registeredServices = bundle
- .getRegisteredServices();
- if (registeredServices != null) {
- TreeParent registeredServicesNode = new TreeParent(
- "Registered Services");
- addChild(registeredServicesNode);
- for (ServiceReference sr : registeredServices) {
- if (sr != null)
- registeredServicesNode
- .addChild(new ServiceReferenceNode(sr));
- }
- }
-
- // Used services
- ServiceReference[] usedServices = bundle.getRegisteredServices();
- if (usedServices != null) {
- TreeParent usedServicesNode = new TreeParent("Used Services");
- addChild(usedServicesNode);
- for (ServiceReference sr : usedServices) {
- if (sr != null)
- usedServicesNode.addChild(new ServiceReferenceNode(sr));
- }
- }
- }
-
- public Bundle getBundle() {
- return bundle;
- }
-
- }
-
- class ServiceReferenceNode extends TreeParent {
- private final ServiceReference serviceReference;
-
- public ServiceReferenceNode(ServiceReference serviceReference) {
- super(serviceReference.toString());
- this.serviceReference = serviceReference;
-
- Bundle[] usedBundles = serviceReference.getUsingBundles();
- if (usedBundles != null) {
- TreeParent usingBundles = new TreeParent("Using Bundles");
- addChild(usingBundles);
- for (Bundle b : usedBundles) {
- if (b != null)
- usingBundles.addChild(new TreeParent(b
- .getSymbolicName()));
- }
- }
-
- TreeParent properties = new TreeParent("Properties");
- addChild(properties);
- for (String key : serviceReference.getPropertyKeys()) {
- properties.addChild(new TreeParent(key + "="
- + serviceReference.getProperty(key)));
- }
-
- }
-
- public ServiceReference getServiceReference() {
- return serviceReference;
- }
-
- }
-
- class MultiplePackagesNode extends TreeParent {
- private String packageName;
- private Set<ExportedPackage> exportedPackages;
-
- public MultiplePackagesNode(String packageName,
- Set<ExportedPackage> exportedPackages) {
- super(packageName);
- this.packageName = packageName;
- this.exportedPackages = exportedPackages;
- for (ExportedPackage pkg : exportedPackages) {
- addChild(new ExportedPackageNode(pkg));
- }
- }
-
- }
-
- class ConflictingPackageNode extends TreeParent {
- private ExportedPackage exportedPackage;
-
- public ConflictingPackageNode(ExportedPackage exportedPackage) {
- super(exportedPackage.getName() + " - "
- + exportedPackage.getVersion() + " ("
- + exportedPackage.getExportingBundle() + ")");
- this.exportedPackage = exportedPackage;
-
- TreeParent bundlesNode = new TreeParent("Dependent Bundles");
- this.addChild(bundlesNode);
- Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
- for (Bundle b : exportedPackage.getImportingBundles()) {
- bundles.put(b.getSymbolicName(), b);
- }
- for (String key : bundles.keySet()) {
- addDependentBundles(bundlesNode, bundles.get(key));
- }
- }
- }
-
- protected void addDependentBundles(TreeParent parent, Bundle bundle) {
- TreeParent bundleNode = new TreeParent(bundle.toString());
- parent.addChild(bundleNode);
- Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
- ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle);
- if (pkgs != null)
- for (ExportedPackage pkg : pkgs) {
- for (Bundle b : pkg.getImportingBundles()) {
- if (!bundles.containsKey(b.getSymbolicName())
- && b.getBundleId() != bundle.getBundleId()) {
- bundles.put(b.getSymbolicName(), b);
- }
- }
- }
-
- for (String key : bundles.keySet()) {
- addDependentBundles(bundleNode, bundles.get(key));
- }
- }
-
- class ExportedPackageNode extends TreeParent {
- private ExportedPackage exportedPackage;
-
- public ExportedPackageNode(ExportedPackage exportedPackage) {
- super(exportedPackage.getName() + " - "
- + exportedPackage.getVersion() + " ("
- + exportedPackage.getExportingBundle() + ")");
- this.exportedPackage = exportedPackage;
- for (Bundle bundle : exportedPackage.getImportingBundles()) {
- addChild(new BundleNode(bundle));
- }
- }
- }
-}
--- /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.osgi.ui.explorer;
+
+import org.eclipse.swt.graphics.Image;
+
+/** Shared icons. */
+public class OsgiExplorerImages {
+ public final static Image INSTALLED = OsgiExplorerPlugin
+ .getImageDescriptor("icons/installed.gif").createImage();
+ public final static Image RESOLVED = OsgiExplorerPlugin.getImageDescriptor(
+ "icons/resolved.gif").createImage();
+ public final static Image STARTING = OsgiExplorerPlugin.getImageDescriptor(
+ "icons/starting.gif").createImage();
+ public final static Image ACTIVE = OsgiExplorerPlugin.getImageDescriptor(
+ "icons/active.gif").createImage();
+}
--- /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.osgi.ui.explorer;
+
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/** OSGi explorer perspective (to be enriched declaratively) */
+public class OsgiExplorerPerspective implements IPerspectiveFactory {
+
+ public void createInitialLayout(IPageLayout layout) {
+ layout.setEditorAreaVisible(true);
+ layout.setFixed(false);
+
+ }
+
+}
--- /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.osgi.ui.explorer;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class OsgiExplorerPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.argeo.osgi.ui.explorer"; //$NON-NLS-1$
+
+ // The shared instance
+ private static OsgiExplorerPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public OsgiExplorerPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static OsgiExplorerPlugin getDefault() {
+ return plugin;
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+}
--- /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.osgi.ui.explorer.views;
+
+import java.util.Comparator;
+
+import org.argeo.eclipse.ui.ColumnViewerComparator;
+import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
+import org.argeo.osgi.ui.explorer.OsgiExplorerImages;
+import org.argeo.osgi.ui.explorer.OsgiExplorerPlugin;
+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.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Overview of the bundles as a table. Equivalent to Equinox 'ss' console
+ * command.
+ */
+public class BundlesView extends ViewPart {
+ private TableViewer viewer;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ viewer = new TableViewer(parent);
+ viewer.setContentProvider(new BundleContentProvider());
+ viewer.getTable().setHeaderVisible(true);
+
+ EclipseUiSpecificUtils.enableToolTipSupport(viewer);
+
+ // ID
+ TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
+ column.getColumn().setWidth(30);
+ column.getColumn().setText("ID");
+ column.getColumn().setAlignment(SWT.RIGHT);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return Long.toString(((Bundle) element).getBundleId());
+ }
+ });
+ new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
+ public int compare(Bundle o1, Bundle o2) {
+ return (int) (o1.getBundleId() - o2.getBundleId());
+ }
+ });
+
+ // State
+ column = new TableViewerColumn(viewer, SWT.NONE);
+ column.getColumn().setWidth(18);
+ column.getColumn().setText("State");
+ column.setLabelProvider(new StateLabelProvider());
+ new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
+ public int compare(Bundle o1, Bundle o2) {
+ return o1.getState() - o2.getState();
+ }
+ });
+
+ // Symbolic name
+ column = new TableViewerColumn(viewer, SWT.NONE);
+ column.getColumn().setWidth(300);
+ column.getColumn().setText("Symbolic Name");
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return ((Bundle) element).getSymbolicName();
+ }
+ });
+ new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
+ public int compare(Bundle o1, Bundle o2) {
+ return o1.getSymbolicName().compareTo(o2.getSymbolicName());
+ }
+ });
+
+ // Version
+ column = new TableViewerColumn(viewer, SWT.NONE);
+ column.getColumn().setWidth(150);
+ column.getColumn().setText("Version");
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return ((Bundle) element).getVersion().toString();
+ }
+ });
+ new ColumnViewerComparator<Bundle>(column, new Comparator<Bundle>() {
+ public int compare(Bundle o1, Bundle o2) {
+ return o1.getVersion().compareTo(o2.getVersion());
+ }
+ });
+
+ viewer.setInput(OsgiExplorerPlugin.getDefault().getBundle()
+ .getBundleContext());
+
+ }
+
+ @Override
+ public void setFocus() {
+ if (viewer != null)
+ viewer.getControl().setFocus();
+ }
+
+ /** Content provider managing the array of bundles */
+ private static class BundleContentProvider implements
+ IStructuredContentProvider {
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof BundleContext) {
+ BundleContext bc = (BundleContext) inputElement;
+ return bc.getBundles();
+ }
+ return null;
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+ /** Label provider for the state column */
+ private static class StateLabelProvider extends ColumnLabelProvider {
+ @Override
+ public Image getImage(Object element) {
+ Integer state = ((Bundle) element).getState();
+ switch (state) {
+ case Bundle.UNINSTALLED:
+ return OsgiExplorerImages.INSTALLED;
+ case Bundle.INSTALLED:
+ return OsgiExplorerImages.INSTALLED;
+ case Bundle.RESOLVED:
+ return OsgiExplorerImages.RESOLVED;
+ case Bundle.STARTING:
+ return OsgiExplorerImages.STARTING;
+ case Bundle.STOPPING:
+ return OsgiExplorerImages.STARTING;
+ case Bundle.ACTIVE:
+ return OsgiExplorerImages.ACTIVE;
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public String getText(Object element) {
+ return null;
+ }
+
+ @Override
+ public String getToolTipText(Object element) {
+ Bundle bundle = (Bundle) element;
+ Integer state = bundle.getState();
+ switch (state) {
+ case Bundle.UNINSTALLED:
+ return "UNINSTALLED";
+ case Bundle.INSTALLED:
+ return "INSTALLED";
+ case Bundle.RESOLVED:
+ return "RESOLVED";
+ case Bundle.STARTING:
+ String activationPolicy = bundle.getHeaders()
+ .get(Constants.BUNDLE_ACTIVATIONPOLICY).toString();
+ if (activationPolicy != null
+ && activationPolicy.equals(Constants.ACTIVATION_LAZY))
+ return "<<LAZY>>";
+ return "STARTING";
+ case Bundle.STOPPING:
+ return "STOPPING";
+ case Bundle.ACTIVE:
+ return "ACTIVE";
+ default:
+ return null;
+ }
+ }
+
+ }
+}
--- /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.osgi.ui.explorer.views;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.osgi.ui.explorer.OsgiExplorerPlugin;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/** <b>Experimental</b> The OSGi runtime from a module perspective. */
+public class ModulesView extends ViewPart {
+ private final static Log log = LogFactory.getLog(ModulesView.class);
+
+ private TreeViewer viewer;
+
+ private PackageAdmin packageAdmin;
+
+ private Comparator<ExportedPackage> exportedPackageComparator = new Comparator<ExportedPackage>() {
+
+ public int compare(ExportedPackage o1, ExportedPackage o2) {
+ if (!o1.getName().equals(o2.getName()))
+ return o1.getName().compareTo(o2.getName());
+ else
+ return o1.getVersion().compareTo(o2.getVersion());
+ }
+ };
+
+ @Override
+ public void createPartControl(Composite parent) {
+ viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new ModulesContentProvider());
+ viewer.setLabelProvider(new ModulesLabelProvider());
+ viewer.setInput(OsgiExplorerPlugin.getDefault().getBundle()
+ .getBundleContext());
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getTree().setFocus();
+ }
+
+ private class ModulesContentProvider implements ITreeContentProvider {
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof BundleContext) {
+ BundleContext bundleContext = (BundleContext) parentElement;
+ Bundle[] bundles = bundleContext.getBundles();
+
+ TreeParent bundlesNode = new TreeParent("Bundles");
+ for (Bundle bundle : bundles) {
+ if (bundle.getState() == Bundle.ACTIVE)
+ bundlesNode.addChild(new BundleNode(bundle));
+ }
+
+ // scan packages
+ ServiceReference paSr = bundleContext
+ .getServiceReference(PackageAdmin.class.getName());
+ // TODO: make a cleaner referencing
+ packageAdmin = (PackageAdmin) bundleContext.getService(paSr);
+
+ Bundle bundle1 = null;
+ Bundle bundle2 = null;
+
+ Map<Bundle, Set<ExportedPackage>> importedPackages = new HashMap<Bundle, Set<ExportedPackage>>();
+ Map<String, Set<ExportedPackage>> packages = new TreeMap<String, Set<ExportedPackage>>();
+ for (Bundle bundle : bundles) {
+ if (bundle.getSymbolicName()
+ .equals("org.argeo.security.ui"))
+ bundle1 = bundle;
+ if (bundle.getSymbolicName().equals(
+ "org.argeo.security.equinox"))
+ bundle2 = bundle;
+
+ ExportedPackage[] pkgs = packageAdmin
+ .getExportedPackages(bundle);
+ if (pkgs != null)
+ for (ExportedPackage pkg : pkgs) {
+ if (!packages.containsKey(pkg.getName()))
+ packages.put(pkg.getName(),
+ new TreeSet<ExportedPackage>(
+ exportedPackageComparator));
+ Set<ExportedPackage> expPackages = (Set<ExportedPackage>) packages
+ .get(pkg.getName());
+ expPackages.add(pkg);
+
+ // imported
+ for (Bundle b : pkg.getImportingBundles()) {
+ if (bundle.getBundleId() != b.getBundleId()) {
+ if (!importedPackages.containsKey(b))
+ importedPackages
+ .put(b,
+ new TreeSet<ExportedPackage>(
+ exportedPackageComparator));
+ Set<ExportedPackage> impPackages = (Set<ExportedPackage>) importedPackages
+ .get(b);
+ impPackages.add(pkg);
+ }
+ }
+ }
+ }
+
+ TreeParent mPackageNode = new TreeParent("Multiple Packages");
+ // TreeParent aPackageNode = new TreeParent("All Packages");
+ for (String packageName : packages.keySet()) {
+ Set<ExportedPackage> pkgs = packages.get(packageName);
+ if (pkgs.size() > 1) {
+ MultiplePackagesNode mpn = new MultiplePackagesNode(
+ packageName, pkgs);
+ mPackageNode.addChild(mpn);
+ // aPackageNode.addChild(mpn);
+ } else {
+ // aPackageNode.addChild(new ExportedPackageNode(pkgs
+ // .iterator().next()));
+ }
+ }
+
+ return new Object[] { bundlesNode, mPackageNode };// ,
+ // aPackageNode
+ // };
+ } else if (parentElement instanceof TreeParent) {
+ return ((TreeParent) parentElement).getChildren();
+ } else {
+ return null;
+ }
+ }
+
+ public Object getParent(Object element) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).hasChildren();
+ }
+ return false;
+ }
+
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+ protected Map<String, ExportedPackage> dependencySpace(Bundle bundle,
+ Map<Bundle, Set<ExportedPackage>> importedPackages,
+ Map<String, Set<String>> traces) {
+ log.debug("Dependency space for " + bundle.getSymbolicName());
+ Map<String, ExportedPackage> space = new TreeMap<String, ExportedPackage>();
+ fillDependencySpace(space, bundle, importedPackages,
+ bundle.getSymbolicName(), traces);
+ return space;
+ }
+
+ /** Recursive */
+ protected void fillDependencySpace(Map<String, ExportedPackage> space,
+ Bundle bundle, Map<Bundle, Set<ExportedPackage>> importedPackages,
+ String currTrace, Map<String, Set<String>> traces) {
+ if (importedPackages.containsKey(bundle)) {
+ Set<ExportedPackage> imports = importedPackages.get(bundle);
+ // log.debug("## Fill dependency space for " + bundle + " : ");
+ for (ExportedPackage pkg : imports) {
+ if (!traces.containsKey(pkg.getName()))
+ traces.put(pkg.getName(), new TreeSet<String>());
+ traces.get(pkg.getName()).add(currTrace);
+ if (!space.containsKey(pkg.getName())) {
+ space.put(pkg.getName(), pkg);
+ Bundle exportingBundle = pkg.getExportingBundle();
+ // if (bundle.getBundleId() !=
+ // exportingBundle.getBundleId())
+ fillDependencySpace(space, exportingBundle,
+ importedPackages, currTrace + " > "
+ + exportingBundle.getSymbolicName(), traces);
+ }
+ }
+ }
+ }
+
+ private class ModulesLabelProvider extends LabelProvider implements
+ ITableLabelProvider {
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ return getText(element);
+ }
+
+ }
+
+ class BundleNode extends TreeParent {
+ private final Bundle bundle;
+
+ public BundleNode(Bundle bundle) {
+ super(bundle.getSymbolicName());
+ this.bundle = bundle;
+
+ // Registered services
+ ServiceReference[] registeredServices = bundle
+ .getRegisteredServices();
+ if (registeredServices != null) {
+ TreeParent registeredServicesNode = new TreeParent(
+ "Registered Services");
+ addChild(registeredServicesNode);
+ for (ServiceReference sr : registeredServices) {
+ if (sr != null)
+ registeredServicesNode
+ .addChild(new ServiceReferenceNode(sr));
+ }
+ }
+
+ // Used services
+ ServiceReference[] usedServices = bundle.getRegisteredServices();
+ if (usedServices != null) {
+ TreeParent usedServicesNode = new TreeParent("Used Services");
+ addChild(usedServicesNode);
+ for (ServiceReference sr : usedServices) {
+ if (sr != null)
+ usedServicesNode.addChild(new ServiceReferenceNode(sr));
+ }
+ }
+ }
+
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ }
+
+ class ServiceReferenceNode extends TreeParent {
+ private final ServiceReference serviceReference;
+
+ public ServiceReferenceNode(ServiceReference serviceReference) {
+ super(serviceReference.toString());
+ this.serviceReference = serviceReference;
+
+ Bundle[] usedBundles = serviceReference.getUsingBundles();
+ if (usedBundles != null) {
+ TreeParent usingBundles = new TreeParent("Using Bundles");
+ addChild(usingBundles);
+ for (Bundle b : usedBundles) {
+ if (b != null)
+ usingBundles.addChild(new TreeParent(b
+ .getSymbolicName()));
+ }
+ }
+
+ TreeParent properties = new TreeParent("Properties");
+ addChild(properties);
+ for (String key : serviceReference.getPropertyKeys()) {
+ properties.addChild(new TreeParent(key + "="
+ + serviceReference.getProperty(key)));
+ }
+
+ }
+
+ public ServiceReference getServiceReference() {
+ return serviceReference;
+ }
+
+ }
+
+ class MultiplePackagesNode extends TreeParent {
+ private String packageName;
+ private Set<ExportedPackage> exportedPackages;
+
+ public MultiplePackagesNode(String packageName,
+ Set<ExportedPackage> exportedPackages) {
+ super(packageName);
+ this.packageName = packageName;
+ this.exportedPackages = exportedPackages;
+ for (ExportedPackage pkg : exportedPackages) {
+ addChild(new ExportedPackageNode(pkg));
+ }
+ }
+
+ }
+
+ class ConflictingPackageNode extends TreeParent {
+ private ExportedPackage exportedPackage;
+
+ public ConflictingPackageNode(ExportedPackage exportedPackage) {
+ super(exportedPackage.getName() + " - "
+ + exportedPackage.getVersion() + " ("
+ + exportedPackage.getExportingBundle() + ")");
+ this.exportedPackage = exportedPackage;
+
+ TreeParent bundlesNode = new TreeParent("Dependent Bundles");
+ this.addChild(bundlesNode);
+ Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
+ for (Bundle b : exportedPackage.getImportingBundles()) {
+ bundles.put(b.getSymbolicName(), b);
+ }
+ for (String key : bundles.keySet()) {
+ addDependentBundles(bundlesNode, bundles.get(key));
+ }
+ }
+ }
+
+ protected void addDependentBundles(TreeParent parent, Bundle bundle) {
+ TreeParent bundleNode = new TreeParent(bundle.toString());
+ parent.addChild(bundleNode);
+ Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
+ ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle);
+ if (pkgs != null)
+ for (ExportedPackage pkg : pkgs) {
+ for (Bundle b : pkg.getImportingBundles()) {
+ if (!bundles.containsKey(b.getSymbolicName())
+ && b.getBundleId() != bundle.getBundleId()) {
+ bundles.put(b.getSymbolicName(), b);
+ }
+ }
+ }
+
+ for (String key : bundles.keySet()) {
+ addDependentBundles(bundleNode, bundles.get(key));
+ }
+ }
+
+ class ExportedPackageNode extends TreeParent {
+ private ExportedPackage exportedPackage;
+
+ public ExportedPackageNode(ExportedPackage exportedPackage) {
+ super(exportedPackage.getName() + " - "
+ + exportedPackage.getVersion() + " ("
+ + exportedPackage.getExportingBundle() + ")");
+ this.exportedPackage = exportedPackage;
+ for (Bundle bundle : exportedPackage.getImportingBundles()) {
+ addChild(new BundleNode(bundle));
+ }
+ }
+ }
+}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
+++ /dev/null
-#Sun Jan 16 11:19:07 CET 2011
-eclipse.preferences.version=1
-pluginProject.extensions=false
-resolve.requirebundle=false
-bin.includes = META-INF/,\
- plugin.xml
-source.. = src/main/java/
-output.. = target/classes/
+source.. = src/
\ 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.security.equinox;
-
-import java.util.Map;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-
-import org.argeo.security.OsAuthenticationToken;
-import org.springframework.security.Authentication;
-import org.springframework.security.AuthenticationManager;
-import org.springframework.security.context.SecurityContextHolder;
-import org.springframework.security.providers.jaas.SecurityContextLoginModule;
-
-/** Login module which caches one subject per thread. */
-public class OsSpringLoginModule extends SecurityContextLoginModule {
- // private final static Log log =
- // LogFactory.getLog(OsSpringLoginModule.class);
-
- private AuthenticationManager authenticationManager;
-
- private Subject subject;
-
- public OsSpringLoginModule() {
-
- }
-
- @SuppressWarnings("rawtypes")
- public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map sharedState, Map options) {
- super.initialize(subject, callbackHandler, sharedState, options);
- this.subject = subject;
- }
-
- public boolean login() throws LoginException {
- // thread already logged in
- if (SecurityContextHolder.getContext().getAuthentication() != null)
- return super.login();
-
- OsAuthenticationToken oat = new OsAuthenticationToken();
- Authentication authentication = authenticationManager.authenticate(oat);
- registerAuthentication(authentication);
- return super.login();
- }
-
- @Override
- public boolean logout() throws LoginException {
- subject.getPrincipals().clear();
- return super.logout();
- }
-
- /**
- * Register an {@link Authentication} in the security context.
- *
- * @param authentication
- * has to implement {@link Authentication}.
- */
- protected void registerAuthentication(Object authentication) {
- SecurityContextHolder.getContext().setAuthentication(
- (Authentication) authentication);
- }
-
- public void setAuthenticationManager(
- AuthenticationManager authenticationManager) {
- this.authenticationManager = authenticationManager;
- }
-}
+++ /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.security.equinox;
-
-import java.util.Locale;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.security.NodeAuthenticationToken;
-import org.argeo.util.LocaleCallback;
-import org.argeo.util.LocaleUtils;
-import org.springframework.security.Authentication;
-import org.springframework.security.AuthenticationManager;
-import org.springframework.security.BadCredentialsException;
-import org.springframework.security.GrantedAuthority;
-import org.springframework.security.GrantedAuthorityImpl;
-import org.springframework.security.context.SecurityContextHolder;
-import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
-import org.springframework.security.providers.jaas.SecurityContextLoginModule;
-
-/** Login module which caches one subject per thread. */
-public class SpringLoginModule extends SecurityContextLoginModule {
- final static String NODE_REPO_URI = "argeo.node.repo.uri";
-
- private final static Log log = LogFactory.getLog(SpringLoginModule.class);
-
- private AuthenticationManager authenticationManager;
-
- private CallbackHandler callbackHandler;
-
- private Subject subject;
-
- private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
-
- private Boolean remote = false;
- private Boolean anonymous = false;
- /** Comma separated list of locales */
- private String availableLocales = "";
-
- private String key = null;
- private String anonymousRole = "ROLE_ANONYMOUS";
-
- public SpringLoginModule() {
-
- }
-
- @SuppressWarnings("rawtypes")
- public void initialize(Subject subject, CallbackHandler callbackHandler,
- Map sharedState, Map options) {
- super.initialize(subject, callbackHandler, sharedState, options);
- this.callbackHandler = callbackHandler;
- this.subject = subject;
- }
-
- public boolean login() throws LoginException {
- try {
- // thread already logged in
- if (SecurityContextHolder.getContext().getAuthentication() != null)
- return super.login();
-
- if (remote && anonymous)
- throw new LoginException(
- "Cannot have a Spring login module which is remote and anonymous");
-
- // reset all principals and credentials
- if (log.isTraceEnabled())
- log.trace("Resetting all principals and credentials of "
- + subject);
- if (subject.getPrincipals() != null)
- subject.getPrincipals().clear();
- if (subject.getPrivateCredentials() != null)
- subject.getPrivateCredentials().clear();
- if (subject.getPublicCredentials() != null)
- subject.getPublicCredentials().clear();
-
- Locale selectedLocale = null;
- // deals first with public access since it's simple
- if (anonymous) {
- // multi locale
- if (callbackHandler != null && availableLocales != null
- && !availableLocales.trim().equals("")) {
- LocaleCallback localeCallback = new LocaleCallback(
- availableLocales);
- callbackHandler.handle(new Callback[] { localeCallback });
- selectedLocale = localeCallback.getSelectedLocale();
- }
-
- // TODO integrate with JCR?
- Object principal = UUID.randomUUID().toString();
- GrantedAuthority[] authorities = { new GrantedAuthorityImpl(
- anonymousRole) };
- AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
- key, principal, authorities);
- Authentication auth = authenticationManager
- .authenticate(anonymousToken);
- registerAuthentication(auth);
- } else {
- if (callbackHandler == null)
- throw new LoginException("No call back handler available");
-
- // ask for username and password
- NameCallback nameCallback = new NameCallback("User");
- PasswordCallback passwordCallback = new PasswordCallback(
- "Password", false);
- final String defaultNodeUrl = System
- .getProperty(NODE_REPO_URI,
- "http://localhost:7070/org.argeo.jcr.webapp/remoting/node");
- NameCallback urlCallback = new NameCallback("Site URL",
- defaultNodeUrl);
- LocaleCallback localeCallback = new LocaleCallback(
- availableLocales);
-
- // handle callbacks
- if (remote)
- callbackHandler.handle(new Callback[] { nameCallback,
- passwordCallback, urlCallback, localeCallback });
- else
- callbackHandler.handle(new Callback[] { nameCallback,
- passwordCallback, localeCallback });
-
- selectedLocale = localeCallback.getSelectedLocale();
-
- // create credentials
- String username = nameCallback.getName();
- if (username == null || username.trim().equals(""))
- return false;
-
- String password = "";
- if (passwordCallback.getPassword() != null)
- password = String.valueOf(passwordCallback.getPassword());
-
- NodeAuthenticationToken credentials;
- if (remote) {
- String url = urlCallback.getName();
- credentials = new NodeAuthenticationToken(username,
- password, url);
- } else {
- credentials = new NodeAuthenticationToken(username,
- password);
- }
-
- Authentication authentication;
- try {
- authentication = authenticationManager
- .authenticate(credentials);
- } catch (BadCredentialsException e) {
- // wait between failed login attempts
- Thread.sleep(waitBetweenFailedLoginAttempts);
- throw e;
- }
- registerAuthentication(authentication);
- }
-
- if (selectedLocale != null)
- LocaleUtils.threadLocale.set(selectedLocale);
-
- return super.login();
- } catch (LoginException e) {
- throw e;
- } catch (ThreadDeath e) {
- LoginException le = new LoginException(
- "Spring Security login thread died");
- le.initCause(e);
- throw le;
- } catch (Exception e) {
- LoginException le = new LoginException(
- "Spring Security login failed");
- le.initCause(e);
- throw le;
- }
- }
-
- @Override
- public boolean logout() throws LoginException {
- subject.getPrincipals().clear();
- return super.logout();
- }
-
- /**
- * Register an {@link Authentication} in the security context.
- *
- * @param authentication
- * has to implement {@link Authentication}.
- */
- protected void registerAuthentication(Object authentication) {
- SecurityContextHolder.getContext().setAuthentication(
- (Authentication) authentication);
- }
-
- public void setAuthenticationManager(
- AuthenticationManager authenticationManager) {
- this.authenticationManager = authenticationManager;
- }
-
- /** Authenticates on a remote node */
- public void setRemote(Boolean remote) {
- this.remote = remote;
- }
-
- /**
- * Request anonymous authentication (incompatible with remote)
- */
- public void setAnonymous(Boolean anonymous) {
- this.anonymous = anonymous;
- }
-
- /** Role identifying an anonymous user */
- public void setAnonymousRole(String anonymousRole) {
- this.anonymousRole = anonymousRole;
- }
-
- /** System key */
- public void setKey(String key) {
- this.key = key;
- }
-
- public void setAvailableLocales(String locales) {
- this.availableLocales = locales;
- }
-
-}
--- /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.security.equinox;
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+
+import org.argeo.security.OsAuthenticationToken;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationManager;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.jaas.SecurityContextLoginModule;
+
+/** Login module which caches one subject per thread. */
+public class OsSpringLoginModule extends SecurityContextLoginModule {
+ // private final static Log log =
+ // LogFactory.getLog(OsSpringLoginModule.class);
+
+ private AuthenticationManager authenticationManager;
+
+ private Subject subject;
+
+ public OsSpringLoginModule() {
+
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
+ Map sharedState, Map options) {
+ super.initialize(subject, callbackHandler, sharedState, options);
+ this.subject = subject;
+ }
+
+ public boolean login() throws LoginException {
+ // thread already logged in
+ if (SecurityContextHolder.getContext().getAuthentication() != null)
+ return super.login();
+
+ OsAuthenticationToken oat = new OsAuthenticationToken();
+ Authentication authentication = authenticationManager.authenticate(oat);
+ registerAuthentication(authentication);
+ return super.login();
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ subject.getPrincipals().clear();
+ return super.logout();
+ }
+
+ /**
+ * Register an {@link Authentication} in the security context.
+ *
+ * @param authentication
+ * has to implement {@link Authentication}.
+ */
+ protected void registerAuthentication(Object authentication) {
+ SecurityContextHolder.getContext().setAuthentication(
+ (Authentication) authentication);
+ }
+
+ public void setAuthenticationManager(
+ AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+}
--- /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.security.equinox;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.security.NodeAuthenticationToken;
+import org.argeo.util.LocaleCallback;
+import org.argeo.util.LocaleUtils;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationManager;
+import org.springframework.security.BadCredentialsException;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
+import org.springframework.security.providers.jaas.SecurityContextLoginModule;
+
+/** Login module which caches one subject per thread. */
+public class SpringLoginModule extends SecurityContextLoginModule {
+ final static String NODE_REPO_URI = "argeo.node.repo.uri";
+
+ private final static Log log = LogFactory.getLog(SpringLoginModule.class);
+
+ private AuthenticationManager authenticationManager;
+
+ private CallbackHandler callbackHandler;
+
+ private Subject subject;
+
+ private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
+
+ private Boolean remote = false;
+ private Boolean anonymous = false;
+ /** Comma separated list of locales */
+ private String availableLocales = "";
+
+ private String key = null;
+ private String anonymousRole = "ROLE_ANONYMOUS";
+
+ public SpringLoginModule() {
+
+ }
+
+ @SuppressWarnings("rawtypes")
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
+ Map sharedState, Map options) {
+ super.initialize(subject, callbackHandler, sharedState, options);
+ this.callbackHandler = callbackHandler;
+ this.subject = subject;
+ }
+
+ public boolean login() throws LoginException {
+ try {
+ // thread already logged in
+ if (SecurityContextHolder.getContext().getAuthentication() != null)
+ return super.login();
+
+ if (remote && anonymous)
+ throw new LoginException(
+ "Cannot have a Spring login module which is remote and anonymous");
+
+ // reset all principals and credentials
+ if (log.isTraceEnabled())
+ log.trace("Resetting all principals and credentials of "
+ + subject);
+ if (subject.getPrincipals() != null)
+ subject.getPrincipals().clear();
+ if (subject.getPrivateCredentials() != null)
+ subject.getPrivateCredentials().clear();
+ if (subject.getPublicCredentials() != null)
+ subject.getPublicCredentials().clear();
+
+ Locale selectedLocale = null;
+ // deals first with public access since it's simple
+ if (anonymous) {
+ // multi locale
+ if (callbackHandler != null && availableLocales != null
+ && !availableLocales.trim().equals("")) {
+ LocaleCallback localeCallback = new LocaleCallback(
+ availableLocales);
+ callbackHandler.handle(new Callback[] { localeCallback });
+ selectedLocale = localeCallback.getSelectedLocale();
+ }
+
+ // TODO integrate with JCR?
+ Object principal = UUID.randomUUID().toString();
+ GrantedAuthority[] authorities = { new GrantedAuthorityImpl(
+ anonymousRole) };
+ AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
+ key, principal, authorities);
+ Authentication auth = authenticationManager
+ .authenticate(anonymousToken);
+ registerAuthentication(auth);
+ } else {
+ if (callbackHandler == null)
+ throw new LoginException("No call back handler available");
+
+ // ask for username and password
+ NameCallback nameCallback = new NameCallback("User");
+ PasswordCallback passwordCallback = new PasswordCallback(
+ "Password", false);
+ final String defaultNodeUrl = System
+ .getProperty(NODE_REPO_URI,
+ "http://localhost:7070/org.argeo.jcr.webapp/remoting/node");
+ NameCallback urlCallback = new NameCallback("Site URL",
+ defaultNodeUrl);
+ LocaleCallback localeCallback = new LocaleCallback(
+ availableLocales);
+
+ // handle callbacks
+ if (remote)
+ callbackHandler.handle(new Callback[] { nameCallback,
+ passwordCallback, urlCallback, localeCallback });
+ else
+ callbackHandler.handle(new Callback[] { nameCallback,
+ passwordCallback, localeCallback });
+
+ selectedLocale = localeCallback.getSelectedLocale();
+
+ // create credentials
+ String username = nameCallback.getName();
+ if (username == null || username.trim().equals(""))
+ return false;
+
+ String password = "";
+ if (passwordCallback.getPassword() != null)
+ password = String.valueOf(passwordCallback.getPassword());
+
+ NodeAuthenticationToken credentials;
+ if (remote) {
+ String url = urlCallback.getName();
+ credentials = new NodeAuthenticationToken(username,
+ password, url);
+ } else {
+ credentials = new NodeAuthenticationToken(username,
+ password);
+ }
+
+ Authentication authentication;
+ try {
+ authentication = authenticationManager
+ .authenticate(credentials);
+ } catch (BadCredentialsException e) {
+ // wait between failed login attempts
+ Thread.sleep(waitBetweenFailedLoginAttempts);
+ throw e;
+ }
+ registerAuthentication(authentication);
+ }
+
+ if (selectedLocale != null)
+ LocaleUtils.threadLocale.set(selectedLocale);
+
+ return super.login();
+ } catch (LoginException e) {
+ throw e;
+ } catch (ThreadDeath e) {
+ LoginException le = new LoginException(
+ "Spring Security login thread died");
+ le.initCause(e);
+ throw le;
+ } catch (Exception e) {
+ LoginException le = new LoginException(
+ "Spring Security login failed");
+ le.initCause(e);
+ throw le;
+ }
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ subject.getPrincipals().clear();
+ return super.logout();
+ }
+
+ /**
+ * Register an {@link Authentication} in the security context.
+ *
+ * @param authentication
+ * has to implement {@link Authentication}.
+ */
+ protected void registerAuthentication(Object authentication) {
+ SecurityContextHolder.getContext().setAuthentication(
+ (Authentication) authentication);
+ }
+
+ public void setAuthenticationManager(
+ AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+
+ /** Authenticates on a remote node */
+ public void setRemote(Boolean remote) {
+ this.remote = remote;
+ }
+
+ /**
+ * Request anonymous authentication (incompatible with remote)
+ */
+ public void setAnonymous(Boolean anonymous) {
+ this.anonymous = anonymous;
+ }
+
+ /** Role identifying an anonymous user */
+ public void setAnonymousRole(String anonymousRole) {
+ this.anonymousRole = anonymousRole;
+ }
+
+ /** System key */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public void setAvailableLocales(String locales) {
+ this.availableLocales = locales;
+ }
+
+}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
-bin.includes = plugin.xml,\
- META-INF/,\
- security-admin.properties
-source.. = src/main/java/
-output.. = target/classes/
+source.. = src/
+++ /dev/null
-/*
- * Argeo Connect - Data management and communications
- * Copyright (C) 2012 Argeo GmbH
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- * Additional permission under GNU GPL version 3 section 7
- *
- * If you modify this Program, or any covered work, by linking or combining it
- * with software covered by the terms of the Eclipse Public License, the
- * licensors of this Program grant you additional permission to convey the
- * resulting work. Corresponding Source for a non-source form of such a
- * combination shall include the source code for the parts of such software
- * which are used as well as that of the covered work.
- */
-package org.argeo.security.ui.admin;
-
-/** Shared icons that must be declared programmatically . */
-public class SecurityAdminImages {
- @SuppressWarnings("unused")
- private final static String PREFIX = "icons/";
-}
+++ /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.security.ui.admin;
-
-import org.argeo.security.ui.admin.views.RolesView;
-import org.argeo.security.ui.admin.views.UsersView;
-import org.eclipse.ui.IFolderLayout;
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-public class SecurityAdminPerspective implements IPerspectiveFactory {
- public void createInitialLayout(IPageLayout layout) {
- String editorArea = layout.getEditorArea();
- layout.setEditorAreaVisible(true);
- layout.setFixed(false);
-
- IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
- 0.65f, editorArea);
- left.addView(UsersView.ID);
- left.addView(RolesView.ID);
- }
-
-}
+++ /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.security.ui.admin;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-public class SecurityAdminPlugin extends AbstractUIPlugin {
- public static final String PLUGIN_ID = "org.argeo.security.ui.admin"; //$NON-NLS-1$
- private static SecurityAdminPlugin plugin;
-
- public SecurityAdminPlugin() {
- }
-
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
- }
-
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- super.stop(context);
- }
-
- public static SecurityAdminPlugin getDefault() {
- return plugin;
- }
-
- public static ImageDescriptor getImageDescriptor(String path) {
- return imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
-
-}
+++ /dev/null
-package org.argeo.security.ui.admin;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.qom.Constraint;
-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 javax.jcr.query.qom.StaticOperand;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.jcr.JcrUiUtils;
-import org.argeo.eclipse.ui.jcr.lists.ColumnDefinition;
-import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
-import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider;
-import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
-import org.argeo.eclipse.ui.utils.ViewerUtils;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
-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.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-
-public class UserTableComposite extends Composite implements ArgeoNames {
- // private final static Log log =
- // LogFactory.getLog(UserTableComposite.class);
-
- private static final long serialVersionUID = -7385959046279360420L;
-
- private TableViewer usersViewer;
- private Text filterTxt;
- private final static String FILTER_HELP_MSG = "Type filter criterion "
- + "separated by a space";
- private Session session;
-
- private Font italic;
- private Font bold;
-
- private boolean hasFilter;
- private boolean hasSelectionColumn;
-
- // private List<Node> selectedItems = new ArrayList<Node>();
-
- /**
- * Overwrite to display other columns
- */
- public List<ColumnDefinition> getColumnsDef() {
- List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
-
- // User ID
- columnDefs.add(new ColumnDefinition(null, ARGEO_USER_ID,
- PropertyType.STRING, "User ID", 100));
- // Displayed name
- columnDefs.add(new ColumnDefinition(null, Property.JCR_TITLE,
- PropertyType.STRING, "Name", 150));
-
- // E-mail
- columnDefs.add(new ColumnDefinition(null, ARGEO_PRIMARY_EMAIL,
- PropertyType.STRING, "E-mail", 150));
-
- // Description
- columnDefs.add(new ColumnDefinition(null, Property.JCR_DESCRIPTION,
- PropertyType.STRING, "Description", 200));
-
- return columnDefs;
- }
-
- public UserTableComposite(Composite parent, int style, Session session) {
- super(parent, style);
- this.session = session;
- }
-
- /**
- *
- * @param addFilter
- * choose to add a field to filter results or not
- * @param addSelection
- * choose to add a column to select some of the displayed results
- * or not
- */
- public void populate(boolean addFilter, boolean addSelection) {
- // initialization
- Composite parent = this;
- italic = EclipseUiUtils.getItalicFont(parent);
- bold = EclipseUiUtils.getBoldFont(parent);
- hasFilter = addFilter;
- hasSelectionColumn = addSelection;
-
- // Main Layout
- this.setLayout(new GridLayout(1, false));
- if (hasFilter)
- createFilterPart(parent);
- usersViewer = createTableViewer(parent);
- EclipseUiSpecificUtils.enableToolTipSupport(usersViewer);
- usersViewer.setContentProvider(new UsersContentProvider());
- refreshFilteredList();
- }
-
- public List<Node> getSelectedUsers() {
- if (hasSelectionColumn) {
- Object[] elements = ((CheckboxTableViewer) usersViewer)
- .getCheckedElements();
-
- List<Node> result = new ArrayList<Node>();
- for (Object obj : elements) {
- result.add((Node) obj);
- }
- return result;
- } else
- throw new ArgeoException("Unvalid request: no selection column "
- + "has been created for the current table");
- }
-
- /** Returns the User table viewer, typically to add doubleclick listener */
- public TableViewer getTableViewer() {
- return usersViewer;
- }
-
- /** Returns filter String or null*/
- protected String getFilterString() {
- return hasFilter ? filterTxt.getText() : null;
- }
-
-
-
- private TableViewer createTableViewer(final Composite parent) {
- int style = SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
- if (hasSelectionColumn)
- style = style | SWT.CHECK;
-
- Table table = new Table(parent, style);
- table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- TableViewer viewer;
- if (hasSelectionColumn)
- viewer = new CheckboxTableViewer(table);
- else
- viewer = new TableViewer(table);
- table.setLinesVisible(true);
- table.setHeaderVisible(true);
-
- // pass a mapping between col index and property name to the comparator.
- // List<String> propertiesList = new ArrayList<String>();
-
- TableViewerColumn column;
- int offset = 0;
- if (hasSelectionColumn) {
- offset = 1;
- column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE,
- 25);
- column.setLabelProvider(new ColumnLabelProvider() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public String getText(Object element) {
- return null;
- }
- });
- SelectionAdapter selectionAdapter = new SelectionAdapter() {
- private static final long serialVersionUID = 1L;
-
- boolean allSelected = false;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- allSelected = !allSelected;
- ((CheckboxTableViewer) usersViewer)
- .setAllChecked(allSelected);
- }
- };
- column.getColumn().addSelectionListener(selectionAdapter);
- }
-
- // Create other columns
- List<ColumnDefinition> colDefs = getColumnsDef();
-
- NodeViewerComparator comparator = new NodeViewerComparator();
- int i = offset;
- for (ColumnDefinition colDef : colDefs) {
- column = ViewerUtils.createTableViewerColumn(viewer,
- colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
- column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
- column.getColumn().addSelectionListener(
- JcrUiUtils.getNodeSelectionAdapter(i,
- colDef.getPropertyType(), colDef.getPropertyName(),
- comparator, viewer));
- i++;
- }
-
- // IMPORTANT: initialize comparator before setting it
- ColumnDefinition firstCol = colDefs.get(0);
- comparator.setColumn(firstCol.getPropertyType(),
- firstCol.getPropertyName());
- viewer.setComparator(comparator);
-
- return viewer;
- }
-
- private class CLProvider extends SimpleJcrNodeLabelProvider {
-
- private static final long serialVersionUID = 1L;
-
- public CLProvider(String propertyName) {
- super(propertyName);
- }
-
- public String getToolTipText(Object element) {
- return getText(element);
- }
-
- @Override
- public Font getFont(Object elem) {
- // self
- String username = getProperty(elem, ARGEO_USER_ID);
- if (username.equals(session.getUserID()))
- return bold;
-
- // disabled
- try {
- Node userProfile = (Node) elem;
- // Node userProfile = userHome.getNode(ARGEO_PROFILE);
- if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean())
- return italic;
- else
- return null;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot get font for " + username, e);
- }
- }
- }
-
- @Override
- public boolean setFocus() {
- usersViewer.getTable().setFocus();
- return true;
- }
-
- @Override
- public void dispose() {
- super.dispose();
- }
-
- public void refresh() {
- refreshFilteredList();
- }
-
- private String getProperty(Object element, String name) {
- try {
- Node userProfile = (Node) element;
- return userProfile.hasProperty(name) ? userProfile
- .getProperty(name).getString() : "";
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot get property " + name, e);
- }
- }
-
- private class UsersContentProvider implements IStructuredContentProvider {
- private static final long serialVersionUID = 1L;
-
- public Object[] getElements(Object inputElement) {
- return (Object[]) inputElement;
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
- }
-
- /* MANAGE FILTER */
- private void createFilterPart(Composite parent) {
- // Text Area for the filter
- filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH
- | SWT.ICON_CANCEL);
- filterTxt.setMessage(FILTER_HELP_MSG);
- filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
- | GridData.HORIZONTAL_ALIGN_FILL));
- filterTxt.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = 1L;
-
- public void modifyText(ModifyEvent event) {
- refreshFilteredList();
- }
- });
- }
-
- /**
- * Refresh the user list: caller might overwrite in order to display a
- * subset of all users, typically to remove current user from the list
- */
- protected void refreshFilteredList() {
- List<Node> nodes;
- try {
- nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session,
- hasFilter ? filterTxt.getText() : null));
- usersViewer.setInput(nodes.toArray());
- } catch (RepositoryException e) {
- throw new ArgeoException("Unable to list users", e);
- }
- }
-
- /**
- * Build repository request : caller might overwrite in order to display a
- * subset of all users
- */
- protected NodeIterator listFilteredElements(Session session, String filter)
- throws RepositoryException {
- QueryManager queryManager = session.getWorkspace().getQueryManager();
- QueryObjectModelFactory factory = queryManager.getQOMFactory();
-
- Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE,
- ArgeoTypes.ARGEO_USER_PROFILE);
-
- // Dynamically build constraint depending on the filter String
- Constraint defaultC = null;
- if (filter != null && !"".equals(filter.trim())) {
- String[] strs = filter.trim().split(" ");
- for (String token : strs) {
- StaticOperand so = factory.literal(session.getValueFactory()
- .createValue("*" + token + "*"));
- Constraint currC = factory.fullTextSearch(
- source.getSelectorName(), null, so);
- if (defaultC == null)
- defaultC = currC;
- else
- defaultC = factory.and(defaultC, currC);
- }
- }
-
- Ordering order = factory.ascending(factory.propertyValue(
- source.getSelectorName(), ARGEO_USER_ID));
- Ordering[] orderings = { order };
-
- QueryObjectModel query = factory.createQuery(source, defaultC,
- orderings, null);
-
- QueryResult result = query.execute();
- return result.getNodes();
- }
-}
\ 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.security.ui.admin.commands;
-
-import org.argeo.ArgeoException;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.editors.ArgeoUserEditor;
-import org.argeo.security.ui.admin.views.RolesView;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.ui.IEditorReference;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Add a new role. */
-public class AddRole extends AbstractHandler {
- public final static String COMMAND_ID = "org.argeo.security.ui.admin.addRole";
- private UserAdminService userAdminService;
- private String rolePrefix = "ROLE_";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- RolesView rolesView = (RolesView) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(RolesView.ID);
- String role = rolesView.getNewRole();
- if (role.trim().equals(""))
- return null;
- if (role.equals(rolesView.getAddNewRoleText()))
- return null;
- role = role.trim().toUpperCase();
- if (!role.startsWith(rolePrefix))
- role = rolePrefix + role;
- if (userAdminService.listEditableRoles().contains(role))
- throw new ArgeoException("Role " + role + " already exists");
- userAdminService.newRole(role);
- rolesView.refresh();
-
- // refresh editors
- IEditorReference[] refs = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage()
- .findEditors(null, ArgeoUserEditor.ID, IWorkbenchPage.MATCH_ID);
- for (IEditorReference ref : refs) {
- ArgeoUserEditor userEditor = (ArgeoUserEditor) ref.getEditor(false);
- if (userEditor != null) {
- userEditor.refresh();
- }
- }
- return null;
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
-}
+++ /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.security.ui.admin.commands;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.views.RolesView;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Deletes the selected roles */
-public class DeleteRole extends AbstractHandler {
- private UserAdminService userAdminService;
-
- @SuppressWarnings("unchecked")
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ISelection selection = HandlerUtil.getCurrentSelection(event);
- if (selection.isEmpty())
- return null;
-
- List<String> toDelete = new ArrayList<String>();
- Iterator<String> it = ((IStructuredSelection) selection).iterator();
- while (it.hasNext()) {
- toDelete.add(it.next());
- }
-
- if (!MessageDialog
- .openQuestion(
- HandlerUtil.getActiveShell(event),
- "Delete Role",
- "Are you sure that you want to delete "
- + toDelete
- + "?\n"
- + "This may lead to inconsistencies in the application."))
- return null;
-
- for (String role : toDelete) {
- userAdminService.deleteRole(role);
- }
-
- RolesView view = (RolesView) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(RolesView.ID);
- view.refresh();
- return null;
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-}
\ 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.security.ui.admin.commands;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.jcr.Node;
-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.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Deletes the selected user nodes */
-public class DeleteUser extends AbstractHandler {
- private final static Log log = LogFactory.getLog(DeleteUser.class);
-
- private UserAdminService userAdminService;
-
- @SuppressWarnings("unchecked")
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ISelection selection = HandlerUtil.getCurrentSelection(event);
- if (selection.isEmpty())
- return null;
-
- Map<String, Node> toDelete = new TreeMap<String, Node>();
- Iterator<Node> it = ((IStructuredSelection) selection).iterator();
- nodes: while (it.hasNext()) {
- Node profileNode = it.next();
- try {
- String userName = profileNode.getProperty(
- ArgeoNames.ARGEO_USER_ID).getString();
- if (userName.equals(profileNode.getSession().getUserID())) {
- log.warn("Cannot delete its own user: " + userName);
- continue nodes;
- }
- toDelete.put(userName, profileNode);
- } catch (RepositoryException e) {
- log.warn("Cannot interpred user " + profileNode);
- }
- }
-
- if (!MessageDialog
- .openQuestion(
- HandlerUtil.getActiveShell(event),
- "Delete User",
- "Are you sure that you want to delete users "
- + toDelete.keySet()
- + "?\n"
- + "This may lead to inconsistencies in the application."))
- return null;
-
- for (String username : toDelete.keySet()) {
- Session session = null;
- try {
- Node profileNode = toDelete.get(username);
- userAdminService.deleteUser(username);
- profileNode.getParent().remove();
- session = profileNode.getSession();
- session.save();
- } catch (RepositoryException e) {
- JcrUtils.discardQuietly(session);
- throw new ArgeoException("Cannot list users", e);
- }
- }
-
- userAdminService.synchronize();
- // UsersView view = (UsersView) HandlerUtil
- // .getActiveWorkbenchWindow(event).getActivePage()
- // .findView(UsersView.ID);
- // view.refresh();
- return null;
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-}
\ 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.security.ui.admin.commands;
-
-import javax.jcr.Repository;
-import javax.jcr.Session;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrSecurityModel;
-import org.argeo.security.ui.admin.wizards.NewUserWizard;
-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;
-
-/** Launch a wizard that enables creation of a new user. */
-public class NewUser extends AbstractHandler {
- private Repository repository;
- private UserAdminService userAdminService;
- private JcrSecurityModel jcrSecurityModel;
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- Session session = null;
- try {
- session = repository.login();
- NewUserWizard newUserWizard = new NewUserWizard(session,
- userAdminService, jcrSecurityModel);
- WizardDialog dialog = new WizardDialog(
- HandlerUtil.getActiveShell(event), newUserWizard);
- dialog.open();
- } catch (Exception e) {
- throw new ExecutionException("Cannot open wizard", e);
- } finally {
- JcrUtils.logoutQuietly(session);
- }
- return null;
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
- public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
- this.jcrSecurityModel = jcrSecurityModel;
- }
-
-}
+++ /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.security.ui.admin.commands;
-
-import org.argeo.security.ui.admin.editors.ArgeoUserEditor;
-import org.argeo.security.ui.admin.editors.ArgeoUserEditorInput;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Command handler to set visible or open a Argeo user. */
-public class OpenArgeoUserEditor extends AbstractHandler {
- public final static String COMMAND_ID = "org.argeo.security.ui.admin.openArgeoUserEditor";
- public final static String PARAM_USERNAME = "org.argeo.security.ui.admin.username";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- try {
- ArgeoUserEditorInput editorInput = new ArgeoUserEditorInput(
- event.getParameter(PARAM_USERNAME));
- IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow(
- event).getActivePage();
- activePage.openEditor(editorInput, ArgeoUserEditor.ID);
- } catch (Exception e) {
- throw new ExecutionException("Cannot open editor", e);
- }
- return null;
- }
-}
+++ /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.security.ui.admin.commands;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-
-/**
- * Refreshes the roles view.
- */
-public class RefreshRoles extends AbstractHandler {
- public Object execute(ExecutionEvent event) throws ExecutionException {
-
- return null;
- }
-
-}
\ 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.security.ui.admin.commands;
-
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.views.UsersView;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/**
- * Refreshes the main user list, removing nodes which are not referenced by user
- * admin service.
- */
-public class RefreshUsersList extends AbstractHandler {
- private UserAdminService userAdminService;
- private Repository repository;
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- Set<String> users = userAdminService.listUsers();
- Session session = null;
- try {
- session = repository.login();
- Query query = session
- .getWorkspace()
- .getQueryManager()
- .createQuery(
- "select * from [" + ArgeoTypes.ARGEO_USER_HOME
- + "]", Query.JCR_SQL2);
- NodeIterator nit = query.execute().getNodes();
- while (nit.hasNext()) {
- Node node = nit.nextNode();
- String username = node.getProperty(ArgeoNames.ARGEO_USER_ID)
- .getString();
- if (!users.contains(username))
- node.remove();
- }
- session.save();
- } catch (RepositoryException e) {
- JcrUtils.discardQuietly(session);
- throw new ArgeoException("Cannot list users", e);
- } finally {
- JcrUtils.logoutQuietly(session);
- }
- userAdminService.synchronize();
-
- // FIXME try to refresh views that extend the UsersView and have another
- // ID
- IWorkbenchPart part = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getActivePart();
- if (part instanceof UsersView)
- ((UsersView) part).refresh();
-
- // Try to refresh UsersView if opened
- UsersView view = (UsersView) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(UsersView.ID);
- if (view != null)
- view.refresh();
-
- return null;
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
- public void setRepository(Repository repository) {
- this.repository = 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.security.ui.admin.commands;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Save the currently edited Argeo user. */
-public class SaveArgeoUser extends AbstractHandler {
- public final static String COMMAND_ID = "org.argeo.security.ui.admin.saveArgeoUser";
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- try {
- IWorkbenchPart iwp = HandlerUtil.getActiveWorkbenchWindow(event)
- .getActivePage().getActivePart();
-
- if (!(iwp instanceof IEditorPart))
- return null;
- IEditorPart editor = (IEditorPart) iwp;
- editor.doSave(null);
- } catch (Exception e) {
- MessageDialog.openError(Display.getDefault().getActiveShell(),
- "Error", "Cannot save user: " + e.getMessage());
- }
- return null;
- }
-
-}
+++ /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.security.ui.admin.commands;
-
-import javax.jcr.Repository;
-import javax.jcr.Session;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrSecurityModel;
-import org.argeo.security.ui.admin.wizards.UserBatchUpdateWizard;
-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;
-
-/** Launch a wizard to update various properties about users in JCR. */
-public class UserBatchUpdate extends AbstractHandler {
- private Repository repository;
- private UserAdminService userAdminService;
- private JcrSecurityModel jcrSecurityModel;
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- Session session = null;
- try {
- session = repository.login();
- UserBatchUpdateWizard userBatchUpdateWizard = new UserBatchUpdateWizard(session,
- userAdminService, jcrSecurityModel);
- WizardDialog dialog = new WizardDialog(
- HandlerUtil.getActiveShell(event), userBatchUpdateWizard);
- dialog.open();
- } catch (Exception e) {
- throw new ExecutionException("Cannot open wizard", e);
- } finally {
- JcrUtils.logoutQuietly(session);
- }
- return null;
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
- public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
- this.jcrSecurityModel = jcrSecurityModel;
- }
-
-}
+++ /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.security.ui.admin.editors;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.argeo.security.ui.admin.views.UsersView;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.springframework.security.GrantedAuthority;
-
-/** Editor for an Argeo user. */
-public class ArgeoUserEditor extends FormEditor {
- public final static String ID = SecurityAdminPlugin.PLUGIN_ID
- + ".adminArgeoUserEditor";
-
- /* DEPENDENCY INJECTION */
- private Session session;
- private UserAdminService userAdminService;
-
- // private Node userHome;
- private Node userProfile;
- private JcrUserDetails userDetails;
-
- public void init(IEditorSite site, IEditorInput input)
- throws PartInitException {
- super.init(site, input);
- String username = ((ArgeoUserEditorInput) getEditorInput())
- .getUsername();
- userProfile = UserJcrUtils.getUserProfile(session, username);
-
- if (userAdminService.userExists(username)) {
- userDetails = (JcrUserDetails) userAdminService
- .loadUserByUsername(username);
- } else {
- GrantedAuthority[] authorities = {};
- try {
- userDetails = new JcrUserDetails(session, username, null,
- authorities);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot retrieve disabled JCR profile");
- }
- }
-
- this.setPartProperty("name", username != null ? username : "<new user>");
- setPartName(username != null ? username : "<new user>");
- }
-
- protected void addPages() {
- try {
- addPage(new DefaultUserMainPage(this, userProfile));
- addPage(new UserRolesPage(this, userDetails, userAdminService));
- } catch (Exception e) {
- throw new ArgeoException("Cannot add pages", e);
- }
- }
-
- @Override
- public void doSave(IProgressMonitor monitor) {
- // list pages
- // TODO: make it more generic
- DefaultUserMainPage defaultUserMainPage = (DefaultUserMainPage) findPage(DefaultUserMainPage.ID);
- if (defaultUserMainPage.isDirty()) {
- defaultUserMainPage.doSave(monitor);
- String newPassword = defaultUserMainPage.getNewPassword();
- defaultUserMainPage.resetNewPassword();
- if (newPassword != null)
- userDetails = userDetails.cloneWithNewPassword(newPassword);
- }
-
- UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
- if (userRolesPage.isDirty()) {
- userRolesPage.doSave(monitor);
- userDetails = userDetails.cloneWithNewRoles(userRolesPage
- .getRoles());
- }
-
- userAdminService.updateUser(userDetails);
-
- // if (userAdminService.userExists(user.getUsername()))
- // userAdminService.updateUser(user);
- // else {
- // userAdminService.newUser(user);
- // setPartName(user.getUsername());
- // }
- firePropertyChange(PROP_DIRTY);
-
- userRolesPage.setUserDetails(userDetails);
-
- // FIXME rather use a refresh command. Fails when called by another
- // view.
- // refresh users view
- IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
- UsersView usersView = (UsersView) iw.getActiveWorkbenchWindow()
- .getActivePage().findView(UsersView.ID);
- if (usersView != null)
- usersView.refresh();
- }
-
- @Override
- public void doSaveAs() {
- }
-
- @Override
- public boolean isSaveAsAllowed() {
- return false;
- }
-
- public void refresh() {
- UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
- userRolesPage.refresh();
- }
-
- @Override
- public void dispose() {
- JcrUtils.logoutQuietly(session);
- super.dispose();
- }
-
- /* DEPENDENCY INJECTION */
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
- public void setRepository(Repository repository) {
- try {
- session = repository.login();
- } catch (RepositoryException re) {
- throw new ArgeoException("Unable to initialise local session", re);
- }
- }
-}
+++ /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.security.ui.admin.editors;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-/** Editor input for an Argeo user. */
-public class ArgeoUserEditorInput implements IEditorInput {
- private final String username;
-
- public ArgeoUserEditorInput(String username) {
- this.username = username;
- }
-
- public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
- return null;
- }
-
- public boolean exists() {
- return username != null;
- }
-
- public ImageDescriptor getImageDescriptor() {
- return null;
- }
-
- public String getName() {
- return username != null ? username : "<new user>";
- }
-
- public IPersistableElement getPersistable() {
- return null;
- }
-
- public String getToolTipText() {
- return username != null ? username : "<new user>";
- }
-
- public boolean equals(Object obj) {
- if (!(obj instanceof ArgeoUserEditorInput))
- return false;
- if (((ArgeoUserEditorInput) obj).getUsername() == null)
- return false;
- return ((ArgeoUserEditorInput) obj).getUsername().equals(username);
- }
-
- public String getUsername() {
- return username;
- }
-}
+++ /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.security.ui.admin.editors;
-
-import java.util.Arrays;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-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.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.forms.AbstractFormPart;
-import org.eclipse.ui.forms.IManagedForm;
-import org.eclipse.ui.forms.SectionPart;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.eclipse.ui.forms.editor.FormPage;
-import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ScrolledForm;
-import org.eclipse.ui.forms.widgets.Section;
-
-/**
- * Display/edit the properties common to all Argeo users
- */
-public class DefaultUserMainPage extends FormPage implements ArgeoNames {
- final static String ID = "argeoUserEditor.mainPage";
-
- private final static Log log = LogFactory.getLog(DefaultUserMainPage.class);
- private Node userProfile;
-
- private char[] newPassword;
-
- public DefaultUserMainPage(FormEditor editor, Node userProfile) {
- super(editor, ID, "Main");
- this.userProfile = userProfile;
- }
-
- protected void createFormContent(final IManagedForm mf) {
- try {
- ScrolledForm form = mf.getForm();
- refreshFormTitle(form);
- GridLayout mainLayout = new GridLayout(1, true);
- form.getBody().setLayout(mainLayout);
-
- createGeneralPart(form.getBody());
- createPassworPart(form.getBody());
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot create form content", e);
- }
- }
-
- /** Creates the general section */
- protected void createGeneralPart(Composite parent)
- throws RepositoryException {
- FormToolkit tk = getManagedForm().getToolkit();
- Section section = tk.createSection(parent, Section.TITLE_BAR);
- section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- section.setText("General");
- Composite body = tk.createComposite(section, SWT.WRAP);
- section.setClient(body);
- GridLayout layout = new GridLayout(2, false);
- body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- body.setLayout(layout);
-
- final Text commonName = createLT(body, "Displayed Name",
- getProperty(Property.JCR_TITLE));
- final Text firstName = createLT(body, "First name",
- getProperty(ARGEO_FIRST_NAME));
- final Text lastName = createLT(body, "Last name",
- getProperty(ARGEO_LAST_NAME));
- final Text email = createLT(body, "Email",
- getProperty(ARGEO_PRIMARY_EMAIL));
- final Text description = createLMT(body, "Description",
- getProperty(Property.JCR_DESCRIPTION));
-
- // create form part (controller)
- AbstractFormPart part = new SectionPart(section) {
- public void commit(boolean onSave) {
- try {
- userProfile.getSession().getWorkspace().getVersionManager()
- .checkout(userProfile.getPath());
- userProfile.setProperty(Property.JCR_TITLE,
- commonName.getText());
- userProfile.setProperty(ARGEO_FIRST_NAME,
- firstName.getText());
- userProfile
- .setProperty(ARGEO_LAST_NAME, lastName.getText());
- userProfile.setProperty(ARGEO_PRIMARY_EMAIL,
- email.getText());
- userProfile.setProperty(Property.JCR_DESCRIPTION,
- description.getText());
- userProfile.getSession().save();
- userProfile.getSession().getWorkspace().getVersionManager()
- .checkin(userProfile.getPath());
- super.commit(onSave);
- refreshFormTitle(getManagedForm().getForm());
- if (log.isTraceEnabled())
- log.trace("General part committed");
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot commit", e);
- }
- }
- };
- // if (username != null)
- // username.addModifyListener(new FormPartML(part));
- commonName.addModifyListener(new FormPartML(part));
- firstName.addModifyListener(new FormPartML(part));
- lastName.addModifyListener(new FormPartML(part));
- email.addModifyListener(new FormPartML(part));
- description.addModifyListener(new FormPartML(part));
- getManagedForm().addPart(part);
- }
-
- private void refreshFormTitle(ScrolledForm form) throws RepositoryException {
- form.setText(getProperty(Property.JCR_TITLE)
- + (userProfile.getProperty(ARGEO_ENABLED).getBoolean() ? ""
- : " [DISABLED]"));
- }
-
- /** @return the property, or the empty string if not set */
- protected String getProperty(String name) throws RepositoryException {
- return userProfile.hasProperty(name) ? userProfile.getProperty(name)
- .getString() : "";
- }
-
- /** Creates the password section */
- protected void createPassworPart(Composite parent) {
- FormToolkit tk = getManagedForm().getToolkit();
- Section section = tk.createSection(parent, Section.TITLE_BAR);
- section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- section.setText("Password");
-
- Composite body = tk.createComposite(section, SWT.WRAP);
- section.setClient(body);
- GridLayout layout = new GridLayout(2, false);
- body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- body.setLayout(layout);
-
- // add widgets (view)
- final Text password1 = createLP(body, "New password", "");
- final Text password2 = createLP(body, "Repeat password", "");
- // create form part (controller)
- AbstractFormPart part = new SectionPart(section) {
-
- public void commit(boolean onSave) {
- if (!password1.getText().equals("")
- || !password2.getText().equals("")) {
- if (password1.getText().equals(password2.getText())) {
- newPassword = password1.getText().toCharArray();
- password1.setText("");
- password2.setText("");
- super.commit(onSave);
- } else {
- password1.setText("");
- password2.setText("");
- throw new ArgeoException("Passwords are not equals");
- }
- }
- }
-
- };
- password1.addModifyListener(new FormPartML(part));
- password2.addModifyListener(new FormPartML(part));
- getManagedForm().addPart(part);
- }
-
- /** Creates label and text. */
- protected Text createLT(Composite body, String label, String value) {
- FormToolkit toolkit = getManagedForm().getToolkit();
- Label lbl = toolkit.createLabel(body, label);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- Text text = toolkit.createText(body, value, SWT.BORDER);
- text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- return text;
- }
-
- /** Creates label and multiline text. */
- protected Text createLMT(Composite body, String label, String value) {
- FormToolkit toolkit = getManagedForm().getToolkit();
- Label lbl = toolkit.createLabel(body, label);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI);
- text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
- return text;
- }
-
- /** Creates label and password. */
- protected Text createLP(Composite body, String label, String value) {
- FormToolkit toolkit = getManagedForm().getToolkit();
- Label lbl = toolkit.createLabel(body, label);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD);
- text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- return text;
- }
-
- private class FormPartML implements ModifyListener {
- private AbstractFormPart formPart;
-
- public FormPartML(AbstractFormPart generalPart) {
- this.formPart = generalPart;
- }
-
- public void modifyText(ModifyEvent e) {
- formPart.markDirty();
- }
-
- }
-
- public String getNewPassword() {
- if (newPassword != null)
- return new String(newPassword);
- else
- return null;
- }
-
- public void resetNewPassword() {
- if (newPassword != null)
- Arrays.fill(newPassword, 'x');
- newPassword = null;
- }
-}
+++ /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.security.ui.admin.editors;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-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.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.ui.forms.AbstractFormPart;
-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.springframework.security.GrantedAuthority;
-import org.springframework.security.userdetails.UserDetails;
-
-/**
- * Display/edit the roles of a user.
- */
-public class UserRolesPage extends FormPage implements ArgeoNames {
- final static String ID = "argeoUserEditor.rolesPage";
-
- private final static Log log = LogFactory.getLog(UserRolesPage.class);
- private final static Image ROLE_CHECKED = SecurityAdminPlugin
- .getImageDescriptor("icons/security.gif").createImage();
-
- private TableViewer rolesViewer;
- private UserAdminService userAdminService;
- private List<String> roles;
-
- public UserRolesPage(FormEditor editor, UserDetails userDetails,
- UserAdminService userAdminService) {
- super(editor, ID, "Roles");
- setUserDetails(userDetails);
- this.userAdminService = userAdminService;
- }
-
- public void setUserDetails(UserDetails userDetails) {
- this.roles = new ArrayList<String>();
- for (GrantedAuthority ga : userDetails.getAuthorities())
- roles.add(ga.getAuthority());
- if (rolesViewer != null)
- rolesViewer.refresh();
- }
-
- protected void createFormContent(final IManagedForm mf) {
- ScrolledForm form = mf.getForm();
- form.setText("Roles");
- FillLayout mainLayout = new FillLayout();
- // ColumnLayout mainLayout = new ColumnLayout();
- // mainLayout.minNumColumns = 1;
- // mainLayout.maxNumColumns = 4;
- // mainLayout.topMargin = 0;
- // mainLayout.bottomMargin = 5;
- // mainLayout.leftMargin = mainLayout.rightMargin =
- // mainLayout.horizontalSpacing = mainLayout.verticalSpacing = 10;
- form.getBody().setLayout(mainLayout);
- createRolesPart(form.getBody());
- }
-
- /** Creates the role section */
- protected void createRolesPart(Composite parent) {
- Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-
- AbstractFormPart part = new AbstractFormPart() {
- public void commit(boolean onSave) {
- // roles have already been modified in editing
- super.commit(onSave);
- if (log.isTraceEnabled())
- log.trace("Role part committed");
- }
- };
- getManagedForm().addPart(part);
-
- // GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
- // gridData.verticalSpan = 20;
- // table.setLayoutData(gridData);
- table.setLinesVisible(true);
- table.setHeaderVisible(false);
- rolesViewer = new TableViewer(table);
-
- // check column
- TableViewerColumn column = createTableViewerColumn(rolesViewer,
- "checked", 20);
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- return null;
- }
-
- public Image getImage(Object element) {
- String role = element.toString();
- if (roles.contains(role)) {
- return ROLE_CHECKED;
- } else {
- return null;
- }
- }
- });
- column.setEditingSupport(new RoleEditingSupport(rolesViewer, part));
-
- // role column
- column = createTableViewerColumn(rolesViewer, "Role", 200);
- column.setLabelProvider(new ColumnLabelProvider() {
- public String getText(Object element) {
- return element.toString();
- }
-
- public Image getImage(Object element) {
- return null;
- }
- });
- rolesViewer.setContentProvider(new RolesContentProvider());
- rolesViewer.setInput(getEditorSite());
- }
-
- protected TableViewerColumn createTableViewerColumn(TableViewer viewer,
- String title, int bound) {
- final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
- SWT.NONE);
- final TableColumn column = viewerColumn.getColumn();
- column.setText(title);
- column.setWidth(bound);
- column.setResizable(true);
- column.setMoveable(true);
- return viewerColumn;
-
- }
-
- public List<String> getRoles() {
- return roles;
- }
-
- public void refresh() {
- rolesViewer.refresh();
- }
-
- private class RolesContentProvider implements IStructuredContentProvider {
- public Object[] getElements(Object inputElement) {
- return userAdminService.listEditableRoles().toArray();
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
- }
-
- /** Select the columns by editing the checkbox in the first column */
- class RoleEditingSupport extends EditingSupport {
-
- private final TableViewer viewer;
- private final AbstractFormPart formPart;
-
- public RoleEditingSupport(TableViewer viewer, AbstractFormPart formPart) {
- super(viewer);
- this.viewer = viewer;
- this.formPart = formPart;
- }
-
- @Override
- protected CellEditor getCellEditor(Object element) {
- return new CheckboxCellEditor(null, SWT.CHECK | SWT.READ_ONLY);
-
- }
-
- @Override
- protected boolean canEdit(Object element) {
- return true;
- }
-
- @Override
- protected Object getValue(Object element) {
- String role = element.toString();
- return roles.contains(role);
-
- }
-
- @Override
- protected void setValue(Object element, Object value) {
- Boolean inRole = (Boolean) value;
- String role = element.toString();
- if (inRole && !roles.contains(role)) {
- roles.add(role);
- formPart.markDirty();
- } else if (!inRole && roles.contains(role)) {
- roles.remove(role);
- formPart.markDirty();
- }
- viewer.refresh();
- }
- }
-
-}
+++ /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.security.ui.admin.views;
-
-import org.argeo.ArgeoException;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.argeo.security.ui.admin.commands.AddRole;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.handlers.IHandlerService;
-import org.eclipse.ui.part.ViewPart;
-
-/** List all roles. */
-public class RolesView extends ViewPart {
- public final static String ID = SecurityAdminPlugin.PLUGIN_ID
- + ".adminRolesView";
-
- private Text newRole;
-
- private TableViewer viewer;
- private UserAdminService userAdminService;
-
- private String addNewRoleText = "<add new role here>";
-
- @Override
- public void createPartControl(Composite parent) {
- parent.setLayout(new GridLayout(1, false));
-
- // new role text field
- newRole = new Text(parent, SWT.BORDER);
- newRole.setText(addNewRoleText);
- newRole.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- // default action is add role
- newRole.addListener(SWT.DefaultSelection, new Listener() {
- public void handleEvent(Event evt) {
- IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
- IHandlerService handlerService = (IHandlerService) iw
- .getService(IHandlerService.class);
- try {
- handlerService.executeCommand(AddRole.COMMAND_ID, evt);
- } catch (Exception e) {
- throw new ArgeoException("Cannot execute add role command",
- e);
- }
- }
- });
- // select all on focus
- newRole.addListener(SWT.FocusIn, new Listener() {
- public void handleEvent(Event e) {
- newRole.selectAll();
- }
- });
-
- // roles table
- Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER);
- table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- table.setLinesVisible(false);
- table.setHeaderVisible(false);
- viewer = new TableViewer(table);
- viewer.setContentProvider(new RolesContentProvider());
- viewer.setLabelProvider(new UsersLabelProvider());
- getViewSite().setSelectionProvider(viewer);
- viewer.setInput(getViewSite());
- }
-
- @Override
- public void setFocus() {
- viewer.getTable().setFocus();
- }
-
- public void setUserAdminService(UserAdminService userAdminService) {
- this.userAdminService = userAdminService;
- }
-
- public String getAddNewRoleText() {
- return addNewRoleText;
- }
-
- private class RolesContentProvider implements IStructuredContentProvider {
-
- public Object[] getElements(Object inputElement) {
- return userAdminService.listEditableRoles().toArray();
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- }
-
- private class UsersLabelProvider extends LabelProvider implements
- ITableLabelProvider {
- public String getColumnText(Object element, int columnIndex) {
- return element.toString();
- }
-
- public Image getColumnImage(Object element, int columnIndex) {
- return null;
- }
-
- }
-
- public String getNewRole() {
- return newRole.getText();
- }
-
- public void refresh() {
- viewer.refresh();
- newRole.setText(addNewRoleText);
- }
-}
+++ /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.security.ui.admin.views;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.utils.CommandUtils;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.argeo.security.ui.admin.UserTableComposite;
-import org.argeo.security.ui.admin.commands.OpenArgeoUserEditor;
-import org.eclipse.jface.viewers.DoubleClickEvent;
-import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.part.ViewPart;
-
-/** List all users with filter. */
-public class UsersView extends ViewPart implements ArgeoNames {
- public final static String ID = SecurityAdminPlugin.PLUGIN_ID
- + ".adminUsersView";
-
- /* DEPENDENCY INJECTION */
- private Session session;
-
- private UserTableComposite userTableCmp;
- private JcrUserListener userStructureListener;
- private JcrUserListener userPropertiesListener;
-
- @Override
- public void createPartControl(Composite parent) {
- parent.setLayout(new FillLayout());
-
- // Create the composite that displays the list and a filter
- userTableCmp = new UserTableComposite(parent, SWT.NO_FOCUS, session);
- userTableCmp.populate(true, false);
-
- // Configure
- userTableCmp.getTableViewer().addDoubleClickListener(
- new ViewDoubleClickListener());
- getViewSite().setSelectionProvider(userTableCmp.getTableViewer());
-
- // Add listener to refresh the list when something changes
- userStructureListener = new JcrUserListener(getSite().getShell()
- .getDisplay());
- JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED
- | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null);
- userPropertiesListener = new JcrUserListener(getSite().getShell()
- .getDisplay());
- JcrUtils.addListener(session, userStructureListener,
- Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
- | Event.PROPERTY_REMOVED,
- ArgeoJcrConstants.PEOPLE_BASE_PATH,
- ArgeoTypes.ARGEO_USER_PROFILE);
- }
-
- @Override
- public void setFocus() {
- userTableCmp.setFocus();
- }
-
- @Override
- public void dispose() {
- JcrUtils.removeListenerQuietly(session, userStructureListener);
- JcrUtils.removeListenerQuietly(session, userPropertiesListener);
- JcrUtils.logoutQuietly(session);
- super.dispose();
- }
-
- // public void setSession(Session session) {
- // this.session = session;
- // }
-
- public void refresh() {
- this.getSite().getShell().getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- userTableCmp.refresh();
- }
- });
- }
-
- private class JcrUserListener implements EventListener {
- private final Display display;
-
- public JcrUserListener(Display display) {
- super();
- this.display = display;
- }
-
- @Override
- public void onEvent(EventIterator events) {
- display.asyncExec(new Runnable() {
- @Override
- public void run() {
- userTableCmp.refresh();
- }
- });
- }
- }
-
- class ViewDoubleClickListener implements IDoubleClickListener {
- public void doubleClick(DoubleClickEvent evt) {
- if (evt.getSelection().isEmpty())
- return;
-
- Object obj = ((IStructuredSelection) evt.getSelection())
- .getFirstElement();
- if (obj instanceof Node) {
- try {
- String username = ((Node) obj).getProperty(ARGEO_USER_ID)
- .getString();
- String commandId = OpenArgeoUserEditor.COMMAND_ID;
- String paramName = OpenArgeoUserEditor.PARAM_USERNAME;
- CommandUtils.callCommand(commandId, paramName, username);
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot open user editor", e);
- }
- }
- }
- }
-
- /* DEPENDENCY INJECTION */
- public void setRepository(Repository repository) {
- try {
- session = repository.login();
- } catch (RepositoryException re) {
- throw new ArgeoException("Unable to initialise local session", re);
- }
- }
-
-}
\ 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.security.ui.admin.wizards;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.security.UserAdminService;
-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.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Text;
-import org.springframework.security.userdetails.UserDetails;
-import org.springframework.security.userdetails.UsernameNotFoundException;
-
-public class MainUserInfoWizardPage extends WizardPage implements
- ModifyListener, ArgeoNames {
- private Text username, firstName, lastName, primaryEmail, password1,
- password2;
- private UserAdminService userAdminService;
-
- public MainUserInfoWizardPage(UserAdminService userAdminService) {
- super("Main");
- this.userAdminService = userAdminService;
- setTitle("Required Information");
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- username = EclipseUiUtils.createGridLT(composite, "Username", this);
- primaryEmail = EclipseUiUtils.createGridLT(composite, "Email", this);
- firstName = EclipseUiUtils.createGridLT(composite, "First name", this);
- lastName = EclipseUiUtils.createGridLT(composite, "Last name", this);
- password1 = EclipseUiUtils.createGridLP(composite, "Password", this);
- password2 = EclipseUiUtils.createGridLP(composite, "Repeat password",
- this);
- setControl(composite);
-
- // Initialize buttons
- setPageComplete(false);
- getContainer().updateButtons();
- }
-
- @Override
- public void modifyText(ModifyEvent event) {
- String message = checkComplete();
- if (message != null) {
- setMessage(message, WizardPage.ERROR);
- setPageComplete(false);
- } else {
- setMessage("Complete", WizardPage.INFORMATION);
- setPageComplete(true);
- }
- getContainer().updateButtons();
- }
-
- /** @return error message or null if complete */
- protected String checkComplete() {
- // if (!username.getText().matches(UserAdminService.USERNAME_PATTERN))
- // return
- // "Wrong user name format, should be lower case, between 3 and 64 characters with only '_' an '@' as acceptable special character.";
-
- if (username.getText().trim().equals(""))
- return "User name must not be empty";
-
- try {
- UserDetails userDetails = userAdminService
- .loadUserByUsername(username.getText());
- return "User " + userDetails.getUsername() + " already exists";
- } catch (UsernameNotFoundException e) {
- // silent
- }
- if (!primaryEmail.getText().matches(UserAdminService.EMAIL_PATTERN))
- return "Not a valid email address";
- if (firstName.getText().trim().equals(""))
- return "Specify a first name";
- if (lastName.getText().trim().equals(""))
- return "Specify a last name";
- if (password1.getText().trim().equals(""))
- return "Specify a password";
- if (password2.getText().trim().equals(""))
- return "Repeat the password";
- if (!password2.getText().equals(password1.getText()))
- return "Passwords are different";
- return null;
- }
-
- public String getUsername() {
- return username.getText();
- }
-
- public String getPassword() {
- return password1.getText();
- }
-
- public void mapToProfileNode(Node up) {
- try {
- up.setProperty(ARGEO_PRIMARY_EMAIL, primaryEmail.getText());
- up.setProperty(ARGEO_FIRST_NAME, firstName.getText());
- up.setProperty(ARGEO_LAST_NAME, lastName.getText());
-
- // derived values
- // TODO add wizard pages to do it
- up.setProperty(Property.JCR_TITLE, firstName.getText() + " "
- + lastName.getText());
- up.setProperty(Property.JCR_DESCRIPTION, "");
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot map to " + up, e);
- }
- }
-}
+++ /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.security.ui.admin.wizards;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrSecurityModel;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.eclipse.jface.wizard.Wizard;
-import org.springframework.security.GrantedAuthority;
-
-/** Wizard to create a new user */
-public class NewUserWizard extends Wizard {
- private final static Log log = LogFactory.getLog(NewUserWizard.class);
- private Session session;
- private UserAdminService userAdminService;
- private JcrSecurityModel jcrSecurityModel;
-
- // pages
- private MainUserInfoWizardPage mainUserInfo;
-
- public NewUserWizard(Session session, UserAdminService userAdminService,
- JcrSecurityModel jcrSecurityModel) {
- this.session = session;
- this.userAdminService = userAdminService;
- this.jcrSecurityModel = jcrSecurityModel;
- }
-
- @Override
- public void addPages() {
- mainUserInfo = new MainUserInfoWizardPage(userAdminService);
- addPage(mainUserInfo);
- }
-
- @Override
- public boolean performFinish() {
- if (!canFinish())
- return false;
-
- String username = mainUserInfo.getUsername();
- try {
- // Node userProfile = SecurityJcrUtils.createUserProfile(session,
- // username);
- Node userProfile = jcrSecurityModel.sync(session, username, null);
- session.getWorkspace().getVersionManager()
- .checkout(userProfile.getPath());
- mainUserInfo.mapToProfileNode(userProfile);
- String password = mainUserInfo.getPassword();
- // TODO add roles
- JcrUserDetails jcrUserDetails = new JcrUserDetails(userProfile,
- password, new GrantedAuthority[0]);
- session.save();
- session.getWorkspace().getVersionManager()
- .checkin(userProfile.getPath());
- userAdminService.createUser(jcrUserDetails);
- return true;
- } catch (Exception e) {
- JcrUtils.discardQuietly(session);
- Node userHome = UserJcrUtils.getUserHome(session, username);
- if (userHome != null) {
- try {
- userHome.remove();
- session.save();
- } catch (RepositoryException e1) {
- JcrUtils.discardQuietly(session);
- log.warn("Error when trying to clean up failed new user "
- + username, e1);
- }
- }
- ErrorFeedback.show("Cannot create new user " + username, e);
- return false;
- }
- }
-
- public void setSession(Session session) {
- this.session = session;
- }
-
-}
+++ /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.security.ui.admin.wizards;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.version.VersionManager;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.ArgeoMonitor;
-import org.argeo.eclipse.ui.EclipseArgeoMonitor;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.jcr.JcrSecurityModel;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.ui.PrivilegedJob;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.argeo.security.ui.admin.UserTableComposite;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.IPageChangeProvider;
-import org.eclipse.jface.dialogs.IPageChangedListener;
-import org.eclipse.jface.dialogs.PageChangedEvent;
-import org.eclipse.jface.wizard.IWizardContainer;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Wizard to update users */
-public class UserBatchUpdateWizard extends Wizard {
- private final static Log log = LogFactory
- .getLog(UserBatchUpdateWizard.class);
- private Session session;
- private UserAdminService userAdminService;
-
- // pages
- private ChooseCommandWizardPage chooseCommandPage;
- private ChooseUsersWizardPage userListPage;
- private ValidateAndLaunchWizardPage validatePage;
-
- // /////////////////////////////////////////////////
- // / Definition of the various implemented commands
- private final static String CMD_UPDATE_PASSWORD = "resetPassword";
- private final static String CMD_GROUP_MEMBERSHIP = "groupMembership";
-
- private final Map<String, String> commands = new HashMap<String, String>() {
- private static final long serialVersionUID = 1L;
- {
- put("Enable user(s)", ArgeoNames.ARGEO_ENABLED);
- put("Expire credentials", ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED);
- put("Expire account(s)", ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED);
- put("Lock account(s)", ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED);
- put("Reset password(s)", CMD_UPDATE_PASSWORD);
- // TODO implement role / group management
- // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP);
- }
- };
-
- public UserBatchUpdateWizard(Session session,
- UserAdminService userAdminService, JcrSecurityModel jcrSecurityModel) {
- this.session = session;
- this.userAdminService = userAdminService;
- // this.jcrSecurityModel = jcrSecurityModel;
- }
-
- @Override
- public void addPages() {
- chooseCommandPage = new ChooseCommandWizardPage();
- addPage(chooseCommandPage);
- userListPage = new ChooseUsersWizardPage(session);
- addPage(userListPage);
- validatePage = new ValidateAndLaunchWizardPage(session);
- addPage(validatePage);
- }
-
- @Override
- public boolean performFinish() {
- if (!canFinish())
- return false;
-
- UpdateJob job = null;
- if (ArgeoNames.ARGEO_ENABLED.equals(chooseCommandPage.getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_ENABLED,
- chooseCommandPage.getBoleanValue());
- } else if (ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED
- .equals(chooseCommandPage.getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED,
- chooseCommandPage.getBoleanValue());
- } else if (ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED
- .equals(chooseCommandPage.getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED,
- chooseCommandPage.getBoleanValue());
- } else if (ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED.equals(chooseCommandPage
- .getCommand())) {
- job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
- ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED,
- chooseCommandPage.getBoleanValue());
- } else if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) {
- String newValue = chooseCommandPage.getPwdValue();
- if (newValue == null)
- throw new ArgeoException(
- "Password cannot be null or an empty string");
- job = new ResetPassword(session, userAdminService,
- userListPage.getSelectedUsers(), newValue);
- }
-
- if (job != null)
- job.schedule();
- return true;
- }
-
- public void setSession(Session session) {
- this.session = session;
- }
-
- public boolean canFinish() {
- if (this.getContainer().getCurrentPage() == validatePage)
- return true;
- return false;
- }
-
- // /////////////////////////
- // REEL UPDATE JOB
- private class UpdateBoolean extends UpdateJob {
- private String propertyName;
- private boolean value;
-
- public UpdateBoolean(Session session, List<Node> nodesToUpdate,
- String propertyName, boolean value) {
- super(session, nodesToUpdate);
- this.propertyName = propertyName;
- this.value = value;
- }
-
- protected void doUpdate(Node node) {
- try {
- node.setProperty(propertyName, value);
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unable to update boolean value for node " + node, re);
- }
- }
- }
-
- private class ResetPassword extends UpdateJob {
- private String newValue;
- private UserAdminService userAdminService;
-
- public ResetPassword(Session session,
- UserAdminService userAdminService, List<Node> nodesToUpdate,
- String newValue) {
- super(session, nodesToUpdate);
- this.newValue = newValue;
- this.userAdminService = userAdminService;
- }
-
- protected void doUpdate(Node node) {
- try {
- String userId = node.getProperty(ArgeoNames.ARGEO_USER_ID)
- .getString();
- if (userAdminService.userExists(userId)) {
- JcrUserDetails userDetails = (JcrUserDetails) userAdminService
- .loadUserByUsername(userId);
- userAdminService.updateUser(userDetails
- .cloneWithNewPassword(newValue));
- }
- } catch (RepositoryException re) {
- throw new ArgeoException(
- "Unable to update boolean value for node " + node, re);
- }
- }
- }
-
- @SuppressWarnings("unused")
- private class AddToGroup extends UpdateJob {
- private String groupID;
- private Session session;
-
- public AddToGroup(Session session, List<Node> nodesToUpdate,
- String groupID) {
- super(session, nodesToUpdate);
- this.session = session;
- this.groupID = groupID;
- }
-
- protected void doUpdate(Node node) {
- log.info("Add/Remove to group actions are not yet implemented");
- // TODO implement this
- // try {
- // throw new ArgeoException("Not yet implemented");
- // } catch (RepositoryException re) {
- // throw new ArgeoException(
- // "Unable to update boolean value for node " + node, re);
- // }
- }
- }
-
- /**
- * Base privileged job that will be run asynchronously to perform the batch
- * update
- */
- private abstract class UpdateJob extends PrivilegedJob {
-
- private final Session currSession;
- private final List<Node> nodesToUpdate;
-
- protected abstract void doUpdate(Node node);
-
- public UpdateJob(Session session, List<Node> nodesToUpdate) {
- super("Perform update");
- try {
- this.currSession = session.getRepository().login();
- // "move" nodes to update in the new session
- // the "old" session will be closed by the calling command
- // before the job has effectively ran
- // TODO there must be a cleaner way to do.
- List<Node> nodes = new ArrayList<Node>();
- for (Node node : nodesToUpdate) {
- nodes.add(currSession.getNode(node.getPath()));
- }
- this.nodesToUpdate = nodes;
- } catch (RepositoryException e) {
- throw new ArgeoException("Error while dupplicating "
- + "session for job", e);
- }
- }
-
- @Override
- protected IStatus doRun(IProgressMonitor progressMonitor) {
- try {
- ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor);
- VersionManager vm = currSession.getWorkspace()
- .getVersionManager();
- int total = nodesToUpdate.size();
- monitor.beginTask("Performing change", total);
- for (Node node : nodesToUpdate) {
- String path = node.getPath();
- vm.checkout(path);
- doUpdate(node);
- currSession.save();
- vm.checkin(path);
- monitor.worked(1);
- }
- } catch (Exception e) {
- log.error("Cannot perform batch update on users", e);
- // e.printStackTrace();
-
- // Dig exception to find the root cause that will enable the
- // user to understand the problem
- Throwable cause = e;
- Throwable originalCause = e;
- while (cause != null) {
- if (log.isTraceEnabled())
- log.trace("Parent Cause message : "
- + cause.getMessage());
- originalCause = cause;
- cause = cause.getCause();
- }
- return new Status(IStatus.ERROR, SecurityAdminPlugin.PLUGIN_ID,
- "Cannot perform updates.", originalCause);
- } finally {
- JcrUtils.logoutQuietly(currSession);
- }
- return Status.OK_STATUS;
- }
- }
-
- // //////////////////////
- // Pages definition
- /** Displays a combo box that enables user to choose which action to perform */
- private class ChooseCommandWizardPage extends WizardPage {
- private static final long serialVersionUID = 1L;
-
- private Combo chooseCommandCmb;
- private Button trueChk;
- private Text valueTxt;
- private Text pwdTxt;
- private Text pwd2Txt;
-
- public ChooseCommandWizardPage() {
- super("Choose a command to run.");
- setTitle("Choose a command to run.");
- }
-
- @Override
- public void createControl(Composite parent) {
- GridLayout gl = new GridLayout();
- Composite container = new Composite(parent, SWT.NO_FOCUS);
- container.setLayout(gl);
-
- chooseCommandCmb = new Combo(container, SWT.NO_FOCUS);
- String[] values = commands.keySet().toArray(
- new String[commands.size()]);
- chooseCommandCmb.setItems(values);
- chooseCommandCmb.setLayoutData(new GridData(SWT.FILL, SWT.TOP,
- true, false));
-
- final Composite bottomPart = new Composite(container, SWT.NO_FOCUS);
- gl = new GridLayout();
- gl.horizontalSpacing = gl.marginWidth = gl.verticalSpacing = 0;
- bottomPart.setLayout(gl);
- bottomPart.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
- true));
-
- chooseCommandCmb.addSelectionListener(new SelectionListener() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (getCommand().equals(CMD_UPDATE_PASSWORD))
- populatePasswordCmp(bottomPart);
- else if (getCommand().equals(CMD_GROUP_MEMBERSHIP))
- populateGroupCmp(bottomPart);
- else
- populateBooleanFlagCmp(bottomPart);
- bottomPart.pack(true);
- bottomPart.layout();
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
-
- setControl(container);
- }
-
- private void cleanParent(Composite parent) {
- if (parent.getChildren().length > 0) {
- for (Control control : parent.getChildren())
- control.dispose();
- }
- }
-
- private void populateBooleanFlagCmp(Composite parent) {
- cleanParent(parent);
- trueChk = new Button(parent, SWT.CHECK);
- trueChk.setText("Do it. (It will to the contrary if unchecked)");
- trueChk.setSelection(true);
- trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
- }
-
- private void populatePasswordCmp(Composite parent) {
- cleanParent(parent);
- Composite body = new Composite(parent, SWT.NO_FOCUS);
- body.setLayout(new GridLayout(2, false));
- body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- pwdTxt = createLP(body, "New password", "");
- pwd2Txt = createLP(body, "Repeat password", "");
- }
-
- /** Creates label and password. */
- protected Text createLP(Composite body, String label, String value) {
- Label lbl = new Label(body, SWT.NONE);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- lbl.setText(label);
- Text text = new Text(body, SWT.BORDER | SWT.PASSWORD);
- text.setText(value);
- text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- return text;
- }
-
- private void populateGroupCmp(Composite parent) {
- if (parent.getChildren().length > 0) {
- for (Control control : parent.getChildren())
- control.dispose();
- }
- trueChk = new Button(parent, SWT.CHECK);
- trueChk.setText("Add to group. (It will remove user(s) from the "
- + "corresponding group if unchecked)");
- trueChk.setSelection(true);
- trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
- }
-
- protected String getCommand() {
- return commands.get(chooseCommandCmb.getItem(chooseCommandCmb
- .getSelectionIndex()));
- }
-
- protected String getCommandLbl() {
- return chooseCommandCmb.getItem(chooseCommandCmb
- .getSelectionIndex());
- }
-
- protected boolean getBoleanValue() {
- // FIXME this is not consistent and will lead to errors.
- if (ArgeoNames.ARGEO_ENABLED.equals(getCommand()))
- return trueChk.getSelection();
- else
- return !trueChk.getSelection();
- }
-
- @SuppressWarnings("unused")
- protected String getStringValue() {
- String value = null;
- if (valueTxt != null) {
- value = valueTxt.getText();
- if ("".equals(value.trim()))
- value = null;
- }
- return value;
- }
-
- protected String getPwdValue() {
- String newPwd = null;
- if (pwdTxt == null || pwd2Txt == null)
- return null;
- if (!pwdTxt.getText().equals("") || !pwd2Txt.getText().equals("")) {
- if (pwdTxt.getText().equals(pwd2Txt.getText())) {
- newPwd = pwdTxt.getText();
- pwdTxt.setText("");
- pwd2Txt.setText("");
- } else {
- pwdTxt.setText("");
- pwd2Txt.setText("");
- throw new ArgeoException("Passwords are not equals");
- }
- }
- return newPwd;
- }
- }
-
- /**
- * Displays a list of users with a check box to be able to choose some of
- * them
- */
- private class ChooseUsersWizardPage extends WizardPage implements
- IPageChangedListener {
- private static final long serialVersionUID = 1L;
- private UserTableComposite userTableCmp;
- private Composite container;
- private Session session;
-
- public ChooseUsersWizardPage(Session session) {
- super("Choose Users");
- this.session = session;
- setTitle("Select users who will be impacted");
- }
-
- @Override
- public void createControl(Composite parent) {
- container = new Composite(parent, SWT.NONE);
- container.setLayout(new FillLayout());
- userTableCmp = new MyUserTableCmp(container, SWT.NO_FOCUS, session);
- userTableCmp.populate(true, true);
- setControl(container);
-
- // Add listener to update message when shown
- final IWizardContainer container = this.getContainer();
- if (container instanceof IPageChangeProvider) {
- ((IPageChangeProvider) container).addPageChangedListener(this);
- }
-
- }
-
- @Override
- public void pageChanged(PageChangedEvent event) {
- if (event.getSelectedPage() == this) {
- String msg = "Chosen batch action: "
- + chooseCommandPage.getCommandLbl();
- ((WizardPage) event.getSelectedPage()).setMessage(msg);
- }
- }
-
- protected List<Node> getSelectedUsers() {
- return userTableCmp.getSelectedUsers();
- }
-
- private class MyUserTableCmp extends UserTableComposite {
-
- private static final long serialVersionUID = 1L;
-
- public MyUserTableCmp(Composite parent, int style, Session session) {
- super(parent, style, session);
- }
-
- @Override
- protected void refreshFilteredList() {
- List<Node> nodes = new ArrayList<Node>();
- try {
- NodeIterator ni = listFilteredElements(session,
- getFilterString());
-
- users: while (ni.hasNext()) {
- Node currNode = ni.nextNode();
- String username = currNode.hasProperty(ARGEO_USER_ID) ? currNode
- .getProperty(ARGEO_USER_ID).getString() : "";
- if (username.equals(session.getUserID()))
- continue users;
- else
- nodes.add(currNode);
- }
- getTableViewer().setInput(nodes.toArray());
- } catch (RepositoryException e) {
- throw new ArgeoException("Unable to list users", e);
- }
- }
- }
- }
-
- /**
- * Recapitulation of input data before running real update
- */
- private class ValidateAndLaunchWizardPage extends WizardPage implements
- IPageChangedListener {
- private static final long serialVersionUID = 1L;
- private UserTableComposite userTableCmp;
- private Session session;
-
- public ValidateAndLaunchWizardPage(Session session) {
- super("Validate and launch");
- this.session = session;
- setTitle("Validate and launch");
- }
-
- @Override
- public void createControl(Composite parent) {
- Composite mainCmp = new Composite(parent, SWT.NO_FOCUS);
- mainCmp.setLayout(new FillLayout());
-
- // Add listener to update user list when shown
- final IWizardContainer container = this.getContainer();
- if (container instanceof IPageChangeProvider) {
- ((IPageChangeProvider) container).addPageChangedListener(this);
- }
-
- userTableCmp = new UserTableComposite(mainCmp, SWT.NO_FOCUS,
- session);
- userTableCmp.populate(false, false);
- setControl(mainCmp);
- }
-
- @Override
- public void pageChanged(PageChangedEvent event) {
- if (event.getSelectedPage() == this) {
- @SuppressWarnings({ "unchecked", "rawtypes" })
- Object[] values = ((ArrayList) userListPage.getSelectedUsers())
- .toArray(new Object[userListPage.getSelectedUsers()
- .size()]);
- userTableCmp.getTableViewer().setInput(values);
- String msg = "Following batch action: ["
- + chooseCommandPage.getCommandLbl()
- + "] will be perfomed on the users listed below.\n"
- + "Are you sure you want to proceed?";
- ((WizardPage) event.getSelectedPage()).setMessage(msg);
- }
- }
-
- // private class MyUserTableCmp extends UserTableComposite {
- // public MyUserTableCmp(Composite parent, int style, Session session) {
- // super(parent, style, session);
- // }
- //
- // @Override
- // protected void refreshFilteredList() {
- // @SuppressWarnings({ "unchecked", "rawtypes" })
- //
- // setFilteredList(values);
- // }
- //
- // @Override
- // public void setVisible(boolean visible) {
- // super.setVisible(visible);
- // if (visible)
- // refreshFilteredList();
- // }
- // }
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Argeo Connect - Data management and communications
+ * Copyright (C) 2012 Argeo GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ * Additional permission under GNU GPL version 3 section 7
+ *
+ * If you modify this Program, or any covered work, by linking or combining it
+ * with software covered by the terms of the Eclipse Public License, the
+ * licensors of this Program grant you additional permission to convey the
+ * resulting work. Corresponding Source for a non-source form of such a
+ * combination shall include the source code for the parts of such software
+ * which are used as well as that of the covered work.
+ */
+package org.argeo.security.ui.admin;
+
+/** Shared icons that must be declared programmatically . */
+public class SecurityAdminImages {
+ @SuppressWarnings("unused")
+ private final static String PREFIX = "icons/";
+}
--- /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.security.ui.admin;
+
+import org.argeo.security.ui.admin.views.RolesView;
+import org.argeo.security.ui.admin.views.UsersView;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class SecurityAdminPerspective implements IPerspectiveFactory {
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(true);
+ layout.setFixed(false);
+
+ IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
+ 0.65f, editorArea);
+ left.addView(UsersView.ID);
+ left.addView(RolesView.ID);
+ }
+
+}
--- /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.security.ui.admin;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+public class SecurityAdminPlugin extends AbstractUIPlugin {
+ public static final String PLUGIN_ID = "org.argeo.security.ui.admin"; //$NON-NLS-1$
+ private static SecurityAdminPlugin plugin;
+
+ public SecurityAdminPlugin() {
+ }
+
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ public static SecurityAdminPlugin getDefault() {
+ return plugin;
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+}
--- /dev/null
+package org.argeo.security.ui.admin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+import javax.jcr.query.qom.Constraint;
+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 javax.jcr.query.qom.StaticOperand;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.eclipse.ui.jcr.JcrUiUtils;
+import org.argeo.eclipse.ui.jcr.lists.ColumnDefinition;
+import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
+import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider;
+import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
+import org.argeo.eclipse.ui.utils.ViewerUtils;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+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.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+
+public class UserTableComposite extends Composite implements ArgeoNames {
+ // private final static Log log =
+ // LogFactory.getLog(UserTableComposite.class);
+
+ private static final long serialVersionUID = -7385959046279360420L;
+
+ private TableViewer usersViewer;
+ private Text filterTxt;
+ private final static String FILTER_HELP_MSG = "Type filter criterion "
+ + "separated by a space";
+ private Session session;
+
+ private Font italic;
+ private Font bold;
+
+ private boolean hasFilter;
+ private boolean hasSelectionColumn;
+
+ // private List<Node> selectedItems = new ArrayList<Node>();
+
+ /**
+ * Overwrite to display other columns
+ */
+ public List<ColumnDefinition> getColumnsDef() {
+ List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+
+ // User ID
+ columnDefs.add(new ColumnDefinition(null, ARGEO_USER_ID,
+ PropertyType.STRING, "User ID", 100));
+ // Displayed name
+ columnDefs.add(new ColumnDefinition(null, Property.JCR_TITLE,
+ PropertyType.STRING, "Name", 150));
+
+ // E-mail
+ columnDefs.add(new ColumnDefinition(null, ARGEO_PRIMARY_EMAIL,
+ PropertyType.STRING, "E-mail", 150));
+
+ // Description
+ columnDefs.add(new ColumnDefinition(null, Property.JCR_DESCRIPTION,
+ PropertyType.STRING, "Description", 200));
+
+ return columnDefs;
+ }
+
+ public UserTableComposite(Composite parent, int style, Session session) {
+ super(parent, style);
+ this.session = session;
+ }
+
+ /**
+ *
+ * @param addFilter
+ * choose to add a field to filter results or not
+ * @param addSelection
+ * choose to add a column to select some of the displayed results
+ * or not
+ */
+ public void populate(boolean addFilter, boolean addSelection) {
+ // initialization
+ Composite parent = this;
+ italic = EclipseUiUtils.getItalicFont(parent);
+ bold = EclipseUiUtils.getBoldFont(parent);
+ hasFilter = addFilter;
+ hasSelectionColumn = addSelection;
+
+ // Main Layout
+ this.setLayout(new GridLayout(1, false));
+ if (hasFilter)
+ createFilterPart(parent);
+ usersViewer = createTableViewer(parent);
+ EclipseUiSpecificUtils.enableToolTipSupport(usersViewer);
+ usersViewer.setContentProvider(new UsersContentProvider());
+ refreshFilteredList();
+ }
+
+ public List<Node> getSelectedUsers() {
+ if (hasSelectionColumn) {
+ Object[] elements = ((CheckboxTableViewer) usersViewer)
+ .getCheckedElements();
+
+ List<Node> result = new ArrayList<Node>();
+ for (Object obj : elements) {
+ result.add((Node) obj);
+ }
+ return result;
+ } else
+ throw new ArgeoException("Unvalid request: no selection column "
+ + "has been created for the current table");
+ }
+
+ /** Returns the User table viewer, typically to add doubleclick listener */
+ public TableViewer getTableViewer() {
+ return usersViewer;
+ }
+
+ /** Returns filter String or null*/
+ protected String getFilterString() {
+ return hasFilter ? filterTxt.getText() : null;
+ }
+
+
+
+ private TableViewer createTableViewer(final Composite parent) {
+ int style = SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
+ if (hasSelectionColumn)
+ style = style | SWT.CHECK;
+
+ Table table = new Table(parent, style);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ TableViewer viewer;
+ if (hasSelectionColumn)
+ viewer = new CheckboxTableViewer(table);
+ else
+ viewer = new TableViewer(table);
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+
+ // pass a mapping between col index and property name to the comparator.
+ // List<String> propertiesList = new ArrayList<String>();
+
+ TableViewerColumn column;
+ int offset = 0;
+ if (hasSelectionColumn) {
+ offset = 1;
+ column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE,
+ 25);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String getText(Object element) {
+ return null;
+ }
+ });
+ SelectionAdapter selectionAdapter = new SelectionAdapter() {
+ private static final long serialVersionUID = 1L;
+
+ boolean allSelected = false;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ allSelected = !allSelected;
+ ((CheckboxTableViewer) usersViewer)
+ .setAllChecked(allSelected);
+ }
+ };
+ column.getColumn().addSelectionListener(selectionAdapter);
+ }
+
+ // Create other columns
+ List<ColumnDefinition> colDefs = getColumnsDef();
+
+ NodeViewerComparator comparator = new NodeViewerComparator();
+ int i = offset;
+ for (ColumnDefinition colDef : colDefs) {
+ column = ViewerUtils.createTableViewerColumn(viewer,
+ colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
+ column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
+ column.getColumn().addSelectionListener(
+ JcrUiUtils.getNodeSelectionAdapter(i,
+ colDef.getPropertyType(), colDef.getPropertyName(),
+ comparator, viewer));
+ i++;
+ }
+
+ // IMPORTANT: initialize comparator before setting it
+ ColumnDefinition firstCol = colDefs.get(0);
+ comparator.setColumn(firstCol.getPropertyType(),
+ firstCol.getPropertyName());
+ viewer.setComparator(comparator);
+
+ return viewer;
+ }
+
+ private class CLProvider extends SimpleJcrNodeLabelProvider {
+
+ private static final long serialVersionUID = 1L;
+
+ public CLProvider(String propertyName) {
+ super(propertyName);
+ }
+
+ public String getToolTipText(Object element) {
+ return getText(element);
+ }
+
+ @Override
+ public Font getFont(Object elem) {
+ // self
+ String username = getProperty(elem, ARGEO_USER_ID);
+ if (username.equals(session.getUserID()))
+ return bold;
+
+ // disabled
+ try {
+ Node userProfile = (Node) elem;
+ // Node userProfile = userHome.getNode(ARGEO_PROFILE);
+ if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean())
+ return italic;
+ else
+ return null;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot get font for " + username, e);
+ }
+ }
+ }
+
+ @Override
+ public boolean setFocus() {
+ usersViewer.getTable().setFocus();
+ return true;
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ }
+
+ public void refresh() {
+ refreshFilteredList();
+ }
+
+ private String getProperty(Object element, String name) {
+ try {
+ Node userProfile = (Node) element;
+ return userProfile.hasProperty(name) ? userProfile
+ .getProperty(name).getString() : "";
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot get property " + name, e);
+ }
+ }
+
+ private class UsersContentProvider implements IStructuredContentProvider {
+ private static final long serialVersionUID = 1L;
+
+ public Object[] getElements(Object inputElement) {
+ return (Object[]) inputElement;
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+ }
+
+ /* MANAGE FILTER */
+ private void createFilterPart(Composite parent) {
+ // Text Area for the filter
+ filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH
+ | SWT.ICON_CANCEL);
+ filterTxt.setMessage(FILTER_HELP_MSG);
+ filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.HORIZONTAL_ALIGN_FILL));
+ filterTxt.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = 1L;
+
+ public void modifyText(ModifyEvent event) {
+ refreshFilteredList();
+ }
+ });
+ }
+
+ /**
+ * Refresh the user list: caller might overwrite in order to display a
+ * subset of all users, typically to remove current user from the list
+ */
+ protected void refreshFilteredList() {
+ List<Node> nodes;
+ try {
+ nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session,
+ hasFilter ? filterTxt.getText() : null));
+ usersViewer.setInput(nodes.toArray());
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Unable to list users", e);
+ }
+ }
+
+ /**
+ * Build repository request : caller might overwrite in order to display a
+ * subset of all users
+ */
+ protected NodeIterator listFilteredElements(Session session, String filter)
+ throws RepositoryException {
+ QueryManager queryManager = session.getWorkspace().getQueryManager();
+ QueryObjectModelFactory factory = queryManager.getQOMFactory();
+
+ Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE,
+ ArgeoTypes.ARGEO_USER_PROFILE);
+
+ // Dynamically build constraint depending on the filter String
+ Constraint defaultC = null;
+ if (filter != null && !"".equals(filter.trim())) {
+ String[] strs = filter.trim().split(" ");
+ for (String token : strs) {
+ StaticOperand so = factory.literal(session.getValueFactory()
+ .createValue("*" + token + "*"));
+ Constraint currC = factory.fullTextSearch(
+ source.getSelectorName(), null, so);
+ if (defaultC == null)
+ defaultC = currC;
+ else
+ defaultC = factory.and(defaultC, currC);
+ }
+ }
+
+ Ordering order = factory.ascending(factory.propertyValue(
+ source.getSelectorName(), ARGEO_USER_ID));
+ Ordering[] orderings = { order };
+
+ QueryObjectModel query = factory.createQuery(source, defaultC,
+ orderings, null);
+
+ QueryResult result = query.execute();
+ return result.getNodes();
+ }
+}
\ 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.security.ui.admin.commands;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.ui.admin.editors.ArgeoUserEditor;
+import org.argeo.security.ui.admin.views.RolesView;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Add a new role. */
+public class AddRole extends AbstractHandler {
+ public final static String COMMAND_ID = "org.argeo.security.ui.admin.addRole";
+ private UserAdminService userAdminService;
+ private String rolePrefix = "ROLE_";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ RolesView rolesView = (RolesView) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(RolesView.ID);
+ String role = rolesView.getNewRole();
+ if (role.trim().equals(""))
+ return null;
+ if (role.equals(rolesView.getAddNewRoleText()))
+ return null;
+ role = role.trim().toUpperCase();
+ if (!role.startsWith(rolePrefix))
+ role = rolePrefix + role;
+ if (userAdminService.listEditableRoles().contains(role))
+ throw new ArgeoException("Role " + role + " already exists");
+ userAdminService.newRole(role);
+ rolesView.refresh();
+
+ // refresh editors
+ IEditorReference[] refs = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage()
+ .findEditors(null, ArgeoUserEditor.ID, IWorkbenchPage.MATCH_ID);
+ for (IEditorReference ref : refs) {
+ ArgeoUserEditor userEditor = (ArgeoUserEditor) ref.getEditor(false);
+ if (userEditor != null) {
+ userEditor.refresh();
+ }
+ }
+ return null;
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+
+}
--- /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.security.ui.admin.commands;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.argeo.security.UserAdminService;
+import org.argeo.security.ui.admin.views.RolesView;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Deletes the selected roles */
+public class DeleteRole extends AbstractHandler {
+ private UserAdminService userAdminService;
+
+ @SuppressWarnings("unchecked")
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection.isEmpty())
+ return null;
+
+ List<String> toDelete = new ArrayList<String>();
+ Iterator<String> it = ((IStructuredSelection) selection).iterator();
+ while (it.hasNext()) {
+ toDelete.add(it.next());
+ }
+
+ if (!MessageDialog
+ .openQuestion(
+ HandlerUtil.getActiveShell(event),
+ "Delete Role",
+ "Are you sure that you want to delete "
+ + toDelete
+ + "?\n"
+ + "This may lead to inconsistencies in the application."))
+ return null;
+
+ for (String role : toDelete) {
+ userAdminService.deleteRole(role);
+ }
+
+ RolesView view = (RolesView) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(RolesView.ID);
+ view.refresh();
+ return null;
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+}
\ 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.security.ui.admin.commands;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.jcr.Node;
+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.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.UserAdminService;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Deletes the selected user nodes */
+public class DeleteUser extends AbstractHandler {
+ private final static Log log = LogFactory.getLog(DeleteUser.class);
+
+ private UserAdminService userAdminService;
+
+ @SuppressWarnings("unchecked")
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection.isEmpty())
+ return null;
+
+ Map<String, Node> toDelete = new TreeMap<String, Node>();
+ Iterator<Node> it = ((IStructuredSelection) selection).iterator();
+ nodes: while (it.hasNext()) {
+ Node profileNode = it.next();
+ try {
+ String userName = profileNode.getProperty(
+ ArgeoNames.ARGEO_USER_ID).getString();
+ if (userName.equals(profileNode.getSession().getUserID())) {
+ log.warn("Cannot delete its own user: " + userName);
+ continue nodes;
+ }
+ toDelete.put(userName, profileNode);
+ } catch (RepositoryException e) {
+ log.warn("Cannot interpred user " + profileNode);
+ }
+ }
+
+ if (!MessageDialog
+ .openQuestion(
+ HandlerUtil.getActiveShell(event),
+ "Delete User",
+ "Are you sure that you want to delete users "
+ + toDelete.keySet()
+ + "?\n"
+ + "This may lead to inconsistencies in the application."))
+ return null;
+
+ for (String username : toDelete.keySet()) {
+ Session session = null;
+ try {
+ Node profileNode = toDelete.get(username);
+ userAdminService.deleteUser(username);
+ profileNode.getParent().remove();
+ session = profileNode.getSession();
+ session.save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new ArgeoException("Cannot list users", e);
+ }
+ }
+
+ userAdminService.synchronize();
+ // UsersView view = (UsersView) HandlerUtil
+ // .getActiveWorkbenchWindow(event).getActivePage()
+ // .findView(UsersView.ID);
+ // view.refresh();
+ return null;
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+}
\ 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.security.ui.admin.commands;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.ui.admin.wizards.NewUserWizard;
+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;
+
+/** Launch a wizard that enables creation of a new user. */
+public class NewUser extends AbstractHandler {
+ private Repository repository;
+ private UserAdminService userAdminService;
+ private JcrSecurityModel jcrSecurityModel;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ Session session = null;
+ try {
+ session = repository.login();
+ NewUserWizard newUserWizard = new NewUserWizard(session,
+ userAdminService, jcrSecurityModel);
+ WizardDialog dialog = new WizardDialog(
+ HandlerUtil.getActiveShell(event), newUserWizard);
+ dialog.open();
+ } catch (Exception e) {
+ throw new ExecutionException("Cannot open wizard", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ return null;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+
+ public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
+ this.jcrSecurityModel = jcrSecurityModel;
+ }
+
+}
--- /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.security.ui.admin.commands;
+
+import org.argeo.security.ui.admin.editors.ArgeoUserEditor;
+import org.argeo.security.ui.admin.editors.ArgeoUserEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Command handler to set visible or open a Argeo user. */
+public class OpenArgeoUserEditor extends AbstractHandler {
+ public final static String COMMAND_ID = "org.argeo.security.ui.admin.openArgeoUserEditor";
+ public final static String PARAM_USERNAME = "org.argeo.security.ui.admin.username";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ try {
+ ArgeoUserEditorInput editorInput = new ArgeoUserEditorInput(
+ event.getParameter(PARAM_USERNAME));
+ IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow(
+ event).getActivePage();
+ activePage.openEditor(editorInput, ArgeoUserEditor.ID);
+ } catch (Exception e) {
+ throw new ExecutionException("Cannot open editor", e);
+ }
+ return null;
+ }
+}
--- /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.security.ui.admin.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+
+/**
+ * Refreshes the roles view.
+ */
+public class RefreshRoles extends AbstractHandler {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ return null;
+ }
+
+}
\ 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.security.ui.admin.commands;
+
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.ui.admin.views.UsersView;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Refreshes the main user list, removing nodes which are not referenced by user
+ * admin service.
+ */
+public class RefreshUsersList extends AbstractHandler {
+ private UserAdminService userAdminService;
+ private Repository repository;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ Set<String> users = userAdminService.listUsers();
+ Session session = null;
+ try {
+ session = repository.login();
+ Query query = session
+ .getWorkspace()
+ .getQueryManager()
+ .createQuery(
+ "select * from [" + ArgeoTypes.ARGEO_USER_HOME
+ + "]", Query.JCR_SQL2);
+ NodeIterator nit = query.execute().getNodes();
+ while (nit.hasNext()) {
+ Node node = nit.nextNode();
+ String username = node.getProperty(ArgeoNames.ARGEO_USER_ID)
+ .getString();
+ if (!users.contains(username))
+ node.remove();
+ }
+ session.save();
+ } catch (RepositoryException e) {
+ JcrUtils.discardQuietly(session);
+ throw new ArgeoException("Cannot list users", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ userAdminService.synchronize();
+
+ // FIXME try to refresh views that extend the UsersView and have another
+ // ID
+ IWorkbenchPart part = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getActivePart();
+ if (part instanceof UsersView)
+ ((UsersView) part).refresh();
+
+ // Try to refresh UsersView if opened
+ UsersView view = (UsersView) HandlerUtil
+ .getActiveWorkbenchWindow(event).getActivePage()
+ .findView(UsersView.ID);
+ if (view != null)
+ view.refresh();
+
+ return null;
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = 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.security.ui.admin.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Save the currently edited Argeo user. */
+public class SaveArgeoUser extends AbstractHandler {
+ public final static String COMMAND_ID = "org.argeo.security.ui.admin.saveArgeoUser";
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ try {
+ IWorkbenchPart iwp = HandlerUtil.getActiveWorkbenchWindow(event)
+ .getActivePage().getActivePart();
+
+ if (!(iwp instanceof IEditorPart))
+ return null;
+ IEditorPart editor = (IEditorPart) iwp;
+ editor.doSave(null);
+ } catch (Exception e) {
+ MessageDialog.openError(Display.getDefault().getActiveShell(),
+ "Error", "Cannot save user: " + e.getMessage());
+ }
+ return null;
+ }
+
+}
--- /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.security.ui.admin.commands;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.ui.admin.wizards.UserBatchUpdateWizard;
+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;
+
+/** Launch a wizard to update various properties about users in JCR. */
+public class UserBatchUpdate extends AbstractHandler {
+ private Repository repository;
+ private UserAdminService userAdminService;
+ private JcrSecurityModel jcrSecurityModel;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ Session session = null;
+ try {
+ session = repository.login();
+ UserBatchUpdateWizard userBatchUpdateWizard = new UserBatchUpdateWizard(session,
+ userAdminService, jcrSecurityModel);
+ WizardDialog dialog = new WizardDialog(
+ HandlerUtil.getActiveShell(event), userBatchUpdateWizard);
+ dialog.open();
+ } catch (Exception e) {
+ throw new ExecutionException("Cannot open wizard", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ return null;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+
+ public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
+ this.jcrSecurityModel = jcrSecurityModel;
+ }
+
+}
--- /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.security.ui.admin.editors;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.views.UsersView;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.springframework.security.GrantedAuthority;
+
+/** Editor for an Argeo user. */
+public class ArgeoUserEditor extends FormEditor {
+ public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+ + ".adminArgeoUserEditor";
+
+ /* DEPENDENCY INJECTION */
+ private Session session;
+ private UserAdminService userAdminService;
+
+ // private Node userHome;
+ private Node userProfile;
+ private JcrUserDetails userDetails;
+
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ super.init(site, input);
+ String username = ((ArgeoUserEditorInput) getEditorInput())
+ .getUsername();
+ userProfile = UserJcrUtils.getUserProfile(session, username);
+
+ if (userAdminService.userExists(username)) {
+ userDetails = (JcrUserDetails) userAdminService
+ .loadUserByUsername(username);
+ } else {
+ GrantedAuthority[] authorities = {};
+ try {
+ userDetails = new JcrUserDetails(session, username, null,
+ authorities);
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot retrieve disabled JCR profile");
+ }
+ }
+
+ this.setPartProperty("name", username != null ? username : "<new user>");
+ setPartName(username != null ? username : "<new user>");
+ }
+
+ protected void addPages() {
+ try {
+ addPage(new DefaultUserMainPage(this, userProfile));
+ addPage(new UserRolesPage(this, userDetails, userAdminService));
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot add pages", e);
+ }
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ // list pages
+ // TODO: make it more generic
+ DefaultUserMainPage defaultUserMainPage = (DefaultUserMainPage) findPage(DefaultUserMainPage.ID);
+ if (defaultUserMainPage.isDirty()) {
+ defaultUserMainPage.doSave(monitor);
+ String newPassword = defaultUserMainPage.getNewPassword();
+ defaultUserMainPage.resetNewPassword();
+ if (newPassword != null)
+ userDetails = userDetails.cloneWithNewPassword(newPassword);
+ }
+
+ UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
+ if (userRolesPage.isDirty()) {
+ userRolesPage.doSave(monitor);
+ userDetails = userDetails.cloneWithNewRoles(userRolesPage
+ .getRoles());
+ }
+
+ userAdminService.updateUser(userDetails);
+
+ // if (userAdminService.userExists(user.getUsername()))
+ // userAdminService.updateUser(user);
+ // else {
+ // userAdminService.newUser(user);
+ // setPartName(user.getUsername());
+ // }
+ firePropertyChange(PROP_DIRTY);
+
+ userRolesPage.setUserDetails(userDetails);
+
+ // FIXME rather use a refresh command. Fails when called by another
+ // view.
+ // refresh users view
+ IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
+ UsersView usersView = (UsersView) iw.getActiveWorkbenchWindow()
+ .getActivePage().findView(UsersView.ID);
+ if (usersView != null)
+ usersView.refresh();
+ }
+
+ @Override
+ public void doSaveAs() {
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ public void refresh() {
+ UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
+ userRolesPage.refresh();
+ }
+
+ @Override
+ public void dispose() {
+ JcrUtils.logoutQuietly(session);
+ super.dispose();
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+
+ public void setRepository(Repository repository) {
+ try {
+ session = repository.login();
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unable to initialise local session", re);
+ }
+ }
+}
--- /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.security.ui.admin.editors;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+/** Editor input for an Argeo user. */
+public class ArgeoUserEditorInput implements IEditorInput {
+ private final String username;
+
+ public ArgeoUserEditorInput(String username) {
+ this.username = username;
+ }
+
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ return null;
+ }
+
+ public boolean exists() {
+ return username != null;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ public String getName() {
+ return username != null ? username : "<new user>";
+ }
+
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ public String getToolTipText() {
+ return username != null ? username : "<new user>";
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ArgeoUserEditorInput))
+ return false;
+ if (((ArgeoUserEditorInput) obj).getUsername() == null)
+ return false;
+ return ((ArgeoUserEditorInput) obj).getUsername().equals(username);
+ }
+
+ public String getUsername() {
+ return username;
+ }
+}
--- /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.security.ui.admin.editors;
+
+import java.util.Arrays;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+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.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.SectionPart;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * Display/edit the properties common to all Argeo users
+ */
+public class DefaultUserMainPage extends FormPage implements ArgeoNames {
+ final static String ID = "argeoUserEditor.mainPage";
+
+ private final static Log log = LogFactory.getLog(DefaultUserMainPage.class);
+ private Node userProfile;
+
+ private char[] newPassword;
+
+ public DefaultUserMainPage(FormEditor editor, Node userProfile) {
+ super(editor, ID, "Main");
+ this.userProfile = userProfile;
+ }
+
+ protected void createFormContent(final IManagedForm mf) {
+ try {
+ ScrolledForm form = mf.getForm();
+ refreshFormTitle(form);
+ GridLayout mainLayout = new GridLayout(1, true);
+ form.getBody().setLayout(mainLayout);
+
+ createGeneralPart(form.getBody());
+ createPassworPart(form.getBody());
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot create form content", e);
+ }
+ }
+
+ /** Creates the general section */
+ protected void createGeneralPart(Composite parent)
+ throws RepositoryException {
+ FormToolkit tk = getManagedForm().getToolkit();
+ Section section = tk.createSection(parent, Section.TITLE_BAR);
+ section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ section.setText("General");
+ Composite body = tk.createComposite(section, SWT.WRAP);
+ section.setClient(body);
+ GridLayout layout = new GridLayout(2, false);
+ body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ body.setLayout(layout);
+
+ final Text commonName = createLT(body, "Displayed Name",
+ getProperty(Property.JCR_TITLE));
+ final Text firstName = createLT(body, "First name",
+ getProperty(ARGEO_FIRST_NAME));
+ final Text lastName = createLT(body, "Last name",
+ getProperty(ARGEO_LAST_NAME));
+ final Text email = createLT(body, "Email",
+ getProperty(ARGEO_PRIMARY_EMAIL));
+ final Text description = createLMT(body, "Description",
+ getProperty(Property.JCR_DESCRIPTION));
+
+ // create form part (controller)
+ AbstractFormPart part = new SectionPart(section) {
+ public void commit(boolean onSave) {
+ try {
+ userProfile.getSession().getWorkspace().getVersionManager()
+ .checkout(userProfile.getPath());
+ userProfile.setProperty(Property.JCR_TITLE,
+ commonName.getText());
+ userProfile.setProperty(ARGEO_FIRST_NAME,
+ firstName.getText());
+ userProfile
+ .setProperty(ARGEO_LAST_NAME, lastName.getText());
+ userProfile.setProperty(ARGEO_PRIMARY_EMAIL,
+ email.getText());
+ userProfile.setProperty(Property.JCR_DESCRIPTION,
+ description.getText());
+ userProfile.getSession().save();
+ userProfile.getSession().getWorkspace().getVersionManager()
+ .checkin(userProfile.getPath());
+ super.commit(onSave);
+ refreshFormTitle(getManagedForm().getForm());
+ if (log.isTraceEnabled())
+ log.trace("General part committed");
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot commit", e);
+ }
+ }
+ };
+ // if (username != null)
+ // username.addModifyListener(new FormPartML(part));
+ commonName.addModifyListener(new FormPartML(part));
+ firstName.addModifyListener(new FormPartML(part));
+ lastName.addModifyListener(new FormPartML(part));
+ email.addModifyListener(new FormPartML(part));
+ description.addModifyListener(new FormPartML(part));
+ getManagedForm().addPart(part);
+ }
+
+ private void refreshFormTitle(ScrolledForm form) throws RepositoryException {
+ form.setText(getProperty(Property.JCR_TITLE)
+ + (userProfile.getProperty(ARGEO_ENABLED).getBoolean() ? ""
+ : " [DISABLED]"));
+ }
+
+ /** @return the property, or the empty string if not set */
+ protected String getProperty(String name) throws RepositoryException {
+ return userProfile.hasProperty(name) ? userProfile.getProperty(name)
+ .getString() : "";
+ }
+
+ /** Creates the password section */
+ protected void createPassworPart(Composite parent) {
+ FormToolkit tk = getManagedForm().getToolkit();
+ Section section = tk.createSection(parent, Section.TITLE_BAR);
+ section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ section.setText("Password");
+
+ Composite body = tk.createComposite(section, SWT.WRAP);
+ section.setClient(body);
+ GridLayout layout = new GridLayout(2, false);
+ body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ body.setLayout(layout);
+
+ // add widgets (view)
+ final Text password1 = createLP(body, "New password", "");
+ final Text password2 = createLP(body, "Repeat password", "");
+ // create form part (controller)
+ AbstractFormPart part = new SectionPart(section) {
+
+ public void commit(boolean onSave) {
+ if (!password1.getText().equals("")
+ || !password2.getText().equals("")) {
+ if (password1.getText().equals(password2.getText())) {
+ newPassword = password1.getText().toCharArray();
+ password1.setText("");
+ password2.setText("");
+ super.commit(onSave);
+ } else {
+ password1.setText("");
+ password2.setText("");
+ throw new ArgeoException("Passwords are not equals");
+ }
+ }
+ }
+
+ };
+ password1.addModifyListener(new FormPartML(part));
+ password2.addModifyListener(new FormPartML(part));
+ getManagedForm().addPart(part);
+ }
+
+ /** Creates label and text. */
+ protected Text createLT(Composite body, String label, String value) {
+ FormToolkit toolkit = getManagedForm().getToolkit();
+ Label lbl = toolkit.createLabel(body, label);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ Text text = toolkit.createText(body, value, SWT.BORDER);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ return text;
+ }
+
+ /** Creates label and multiline text. */
+ protected Text createLMT(Composite body, String label, String value) {
+ FormToolkit toolkit = getManagedForm().getToolkit();
+ Label lbl = toolkit.createLabel(body, label);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+ return text;
+ }
+
+ /** Creates label and password. */
+ protected Text createLP(Composite body, String label, String value) {
+ FormToolkit toolkit = getManagedForm().getToolkit();
+ Label lbl = toolkit.createLabel(body, label);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ return text;
+ }
+
+ private class FormPartML implements ModifyListener {
+ private AbstractFormPart formPart;
+
+ public FormPartML(AbstractFormPart generalPart) {
+ this.formPart = generalPart;
+ }
+
+ public void modifyText(ModifyEvent e) {
+ formPart.markDirty();
+ }
+
+ }
+
+ public String getNewPassword() {
+ if (newPassword != null)
+ return new String(newPassword);
+ else
+ return null;
+ }
+
+ public void resetNewPassword() {
+ if (newPassword != null)
+ Arrays.fill(newPassword, 'x');
+ newPassword = null;
+ }
+}
--- /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.security.ui.admin.editors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.ui.admin.SecurityAdminPlugin;
+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.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.forms.AbstractFormPart;
+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.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.UserDetails;
+
+/**
+ * Display/edit the roles of a user.
+ */
+public class UserRolesPage extends FormPage implements ArgeoNames {
+ final static String ID = "argeoUserEditor.rolesPage";
+
+ private final static Log log = LogFactory.getLog(UserRolesPage.class);
+ private final static Image ROLE_CHECKED = SecurityAdminPlugin
+ .getImageDescriptor("icons/security.gif").createImage();
+
+ private TableViewer rolesViewer;
+ private UserAdminService userAdminService;
+ private List<String> roles;
+
+ public UserRolesPage(FormEditor editor, UserDetails userDetails,
+ UserAdminService userAdminService) {
+ super(editor, ID, "Roles");
+ setUserDetails(userDetails);
+ this.userAdminService = userAdminService;
+ }
+
+ public void setUserDetails(UserDetails userDetails) {
+ this.roles = new ArrayList<String>();
+ for (GrantedAuthority ga : userDetails.getAuthorities())
+ roles.add(ga.getAuthority());
+ if (rolesViewer != null)
+ rolesViewer.refresh();
+ }
+
+ protected void createFormContent(final IManagedForm mf) {
+ ScrolledForm form = mf.getForm();
+ form.setText("Roles");
+ FillLayout mainLayout = new FillLayout();
+ // ColumnLayout mainLayout = new ColumnLayout();
+ // mainLayout.minNumColumns = 1;
+ // mainLayout.maxNumColumns = 4;
+ // mainLayout.topMargin = 0;
+ // mainLayout.bottomMargin = 5;
+ // mainLayout.leftMargin = mainLayout.rightMargin =
+ // mainLayout.horizontalSpacing = mainLayout.verticalSpacing = 10;
+ form.getBody().setLayout(mainLayout);
+ createRolesPart(form.getBody());
+ }
+
+ /** Creates the role section */
+ protected void createRolesPart(Composite parent) {
+ Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+
+ AbstractFormPart part = new AbstractFormPart() {
+ public void commit(boolean onSave) {
+ // roles have already been modified in editing
+ super.commit(onSave);
+ if (log.isTraceEnabled())
+ log.trace("Role part committed");
+ }
+ };
+ getManagedForm().addPart(part);
+
+ // GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ // gridData.verticalSpan = 20;
+ // table.setLayoutData(gridData);
+ table.setLinesVisible(true);
+ table.setHeaderVisible(false);
+ rolesViewer = new TableViewer(table);
+
+ // check column
+ TableViewerColumn column = createTableViewerColumn(rolesViewer,
+ "checked", 20);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return null;
+ }
+
+ public Image getImage(Object element) {
+ String role = element.toString();
+ if (roles.contains(role)) {
+ return ROLE_CHECKED;
+ } else {
+ return null;
+ }
+ }
+ });
+ column.setEditingSupport(new RoleEditingSupport(rolesViewer, part));
+
+ // role column
+ column = createTableViewerColumn(rolesViewer, "Role", 200);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ public String getText(Object element) {
+ return element.toString();
+ }
+
+ public Image getImage(Object element) {
+ return null;
+ }
+ });
+ rolesViewer.setContentProvider(new RolesContentProvider());
+ rolesViewer.setInput(getEditorSite());
+ }
+
+ protected TableViewerColumn createTableViewerColumn(TableViewer viewer,
+ String title, int bound) {
+ final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
+ SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+ column.setText(title);
+ column.setWidth(bound);
+ column.setResizable(true);
+ column.setMoveable(true);
+ return viewerColumn;
+
+ }
+
+ public List<String> getRoles() {
+ return roles;
+ }
+
+ public void refresh() {
+ rolesViewer.refresh();
+ }
+
+ private class RolesContentProvider implements IStructuredContentProvider {
+ public Object[] getElements(Object inputElement) {
+ return userAdminService.listEditableRoles().toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+ }
+
+ /** Select the columns by editing the checkbox in the first column */
+ class RoleEditingSupport extends EditingSupport {
+
+ private final TableViewer viewer;
+ private final AbstractFormPart formPart;
+
+ public RoleEditingSupport(TableViewer viewer, AbstractFormPart formPart) {
+ super(viewer);
+ this.viewer = viewer;
+ this.formPart = formPart;
+ }
+
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ return new CheckboxCellEditor(null, SWT.CHECK | SWT.READ_ONLY);
+
+ }
+
+ @Override
+ protected boolean canEdit(Object element) {
+ return true;
+ }
+
+ @Override
+ protected Object getValue(Object element) {
+ String role = element.toString();
+ return roles.contains(role);
+
+ }
+
+ @Override
+ protected void setValue(Object element, Object value) {
+ Boolean inRole = (Boolean) value;
+ String role = element.toString();
+ if (inRole && !roles.contains(role)) {
+ roles.add(role);
+ formPart.markDirty();
+ } else if (!inRole && roles.contains(role)) {
+ roles.remove(role);
+ formPart.markDirty();
+ }
+ viewer.refresh();
+ }
+ }
+
+}
--- /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.security.ui.admin.views;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.commands.AddRole;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.part.ViewPart;
+
+/** List all roles. */
+public class RolesView extends ViewPart {
+ public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+ + ".adminRolesView";
+
+ private Text newRole;
+
+ private TableViewer viewer;
+ private UserAdminService userAdminService;
+
+ private String addNewRoleText = "<add new role here>";
+
+ @Override
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new GridLayout(1, false));
+
+ // new role text field
+ newRole = new Text(parent, SWT.BORDER);
+ newRole.setText(addNewRoleText);
+ newRole.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ // default action is add role
+ newRole.addListener(SWT.DefaultSelection, new Listener() {
+ public void handleEvent(Event evt) {
+ IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
+ IHandlerService handlerService = (IHandlerService) iw
+ .getService(IHandlerService.class);
+ try {
+ handlerService.executeCommand(AddRole.COMMAND_ID, evt);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot execute add role command",
+ e);
+ }
+ }
+ });
+ // select all on focus
+ newRole.addListener(SWT.FocusIn, new Listener() {
+ public void handleEvent(Event e) {
+ newRole.selectAll();
+ }
+ });
+
+ // roles table
+ Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ table.setLinesVisible(false);
+ table.setHeaderVisible(false);
+ viewer = new TableViewer(table);
+ viewer.setContentProvider(new RolesContentProvider());
+ viewer.setLabelProvider(new UsersLabelProvider());
+ getViewSite().setSelectionProvider(viewer);
+ viewer.setInput(getViewSite());
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getTable().setFocus();
+ }
+
+ public void setUserAdminService(UserAdminService userAdminService) {
+ this.userAdminService = userAdminService;
+ }
+
+ public String getAddNewRoleText() {
+ return addNewRoleText;
+ }
+
+ private class RolesContentProvider implements IStructuredContentProvider {
+
+ public Object[] getElements(Object inputElement) {
+ return userAdminService.listEditableRoles().toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+ private class UsersLabelProvider extends LabelProvider implements
+ ITableLabelProvider {
+ public String getColumnText(Object element, int columnIndex) {
+ return element.toString();
+ }
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ }
+
+ public String getNewRole() {
+ return newRole.getText();
+ }
+
+ public void refresh() {
+ viewer.refresh();
+ newRole.setText(addNewRoleText);
+ }
+}
--- /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.security.ui.admin.views;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.utils.CommandUtils;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.UserTableComposite;
+import org.argeo.security.ui.admin.commands.OpenArgeoUserEditor;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.part.ViewPart;
+
+/** List all users with filter. */
+public class UsersView extends ViewPart implements ArgeoNames {
+ public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+ + ".adminUsersView";
+
+ /* DEPENDENCY INJECTION */
+ private Session session;
+
+ private UserTableComposite userTableCmp;
+ private JcrUserListener userStructureListener;
+ private JcrUserListener userPropertiesListener;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new FillLayout());
+
+ // Create the composite that displays the list and a filter
+ userTableCmp = new UserTableComposite(parent, SWT.NO_FOCUS, session);
+ userTableCmp.populate(true, false);
+
+ // Configure
+ userTableCmp.getTableViewer().addDoubleClickListener(
+ new ViewDoubleClickListener());
+ getViewSite().setSelectionProvider(userTableCmp.getTableViewer());
+
+ // Add listener to refresh the list when something changes
+ userStructureListener = new JcrUserListener(getSite().getShell()
+ .getDisplay());
+ JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED
+ | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null);
+ userPropertiesListener = new JcrUserListener(getSite().getShell()
+ .getDisplay());
+ JcrUtils.addListener(session, userStructureListener,
+ Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
+ | Event.PROPERTY_REMOVED,
+ ArgeoJcrConstants.PEOPLE_BASE_PATH,
+ ArgeoTypes.ARGEO_USER_PROFILE);
+ }
+
+ @Override
+ public void setFocus() {
+ userTableCmp.setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ JcrUtils.removeListenerQuietly(session, userStructureListener);
+ JcrUtils.removeListenerQuietly(session, userPropertiesListener);
+ JcrUtils.logoutQuietly(session);
+ super.dispose();
+ }
+
+ // public void setSession(Session session) {
+ // this.session = session;
+ // }
+
+ public void refresh() {
+ this.getSite().getShell().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ userTableCmp.refresh();
+ }
+ });
+ }
+
+ private class JcrUserListener implements EventListener {
+ private final Display display;
+
+ public JcrUserListener(Display display) {
+ super();
+ this.display = display;
+ }
+
+ @Override
+ public void onEvent(EventIterator events) {
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ userTableCmp.refresh();
+ }
+ });
+ }
+ }
+
+ class ViewDoubleClickListener implements IDoubleClickListener {
+ public void doubleClick(DoubleClickEvent evt) {
+ if (evt.getSelection().isEmpty())
+ return;
+
+ Object obj = ((IStructuredSelection) evt.getSelection())
+ .getFirstElement();
+ if (obj instanceof Node) {
+ try {
+ String username = ((Node) obj).getProperty(ARGEO_USER_ID)
+ .getString();
+ String commandId = OpenArgeoUserEditor.COMMAND_ID;
+ String paramName = OpenArgeoUserEditor.PARAM_USERNAME;
+ CommandUtils.callCommand(commandId, paramName, username);
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot open user editor", e);
+ }
+ }
+ }
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ try {
+ session = repository.login();
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unable to initialise local session", re);
+ }
+ }
+
+}
\ 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.security.ui.admin.wizards;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.security.UserAdminService;
+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.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.UsernameNotFoundException;
+
+public class MainUserInfoWizardPage extends WizardPage implements
+ ModifyListener, ArgeoNames {
+ private Text username, firstName, lastName, primaryEmail, password1,
+ password2;
+ private UserAdminService userAdminService;
+
+ public MainUserInfoWizardPage(UserAdminService userAdminService) {
+ super("Main");
+ this.userAdminService = userAdminService;
+ setTitle("Required Information");
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ username = EclipseUiUtils.createGridLT(composite, "Username", this);
+ primaryEmail = EclipseUiUtils.createGridLT(composite, "Email", this);
+ firstName = EclipseUiUtils.createGridLT(composite, "First name", this);
+ lastName = EclipseUiUtils.createGridLT(composite, "Last name", this);
+ password1 = EclipseUiUtils.createGridLP(composite, "Password", this);
+ password2 = EclipseUiUtils.createGridLP(composite, "Repeat password",
+ this);
+ setControl(composite);
+
+ // Initialize buttons
+ setPageComplete(false);
+ getContainer().updateButtons();
+ }
+
+ @Override
+ public void modifyText(ModifyEvent event) {
+ String message = checkComplete();
+ if (message != null) {
+ setMessage(message, WizardPage.ERROR);
+ setPageComplete(false);
+ } else {
+ setMessage("Complete", WizardPage.INFORMATION);
+ setPageComplete(true);
+ }
+ getContainer().updateButtons();
+ }
+
+ /** @return error message or null if complete */
+ protected String checkComplete() {
+ // if (!username.getText().matches(UserAdminService.USERNAME_PATTERN))
+ // return
+ // "Wrong user name format, should be lower case, between 3 and 64 characters with only '_' an '@' as acceptable special character.";
+
+ if (username.getText().trim().equals(""))
+ return "User name must not be empty";
+
+ try {
+ UserDetails userDetails = userAdminService
+ .loadUserByUsername(username.getText());
+ return "User " + userDetails.getUsername() + " already exists";
+ } catch (UsernameNotFoundException e) {
+ // silent
+ }
+ if (!primaryEmail.getText().matches(UserAdminService.EMAIL_PATTERN))
+ return "Not a valid email address";
+ if (firstName.getText().trim().equals(""))
+ return "Specify a first name";
+ if (lastName.getText().trim().equals(""))
+ return "Specify a last name";
+ if (password1.getText().trim().equals(""))
+ return "Specify a password";
+ if (password2.getText().trim().equals(""))
+ return "Repeat the password";
+ if (!password2.getText().equals(password1.getText()))
+ return "Passwords are different";
+ return null;
+ }
+
+ public String getUsername() {
+ return username.getText();
+ }
+
+ public String getPassword() {
+ return password1.getText();
+ }
+
+ public void mapToProfileNode(Node up) {
+ try {
+ up.setProperty(ARGEO_PRIMARY_EMAIL, primaryEmail.getText());
+ up.setProperty(ARGEO_FIRST_NAME, firstName.getText());
+ up.setProperty(ARGEO_LAST_NAME, lastName.getText());
+
+ // derived values
+ // TODO add wizard pages to do it
+ up.setProperty(Property.JCR_TITLE, firstName.getText() + " "
+ + lastName.getText());
+ up.setProperty(Property.JCR_DESCRIPTION, "");
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot map to " + up, e);
+ }
+ }
+}
--- /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.security.ui.admin.wizards;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.eclipse.jface.wizard.Wizard;
+import org.springframework.security.GrantedAuthority;
+
+/** Wizard to create a new user */
+public class NewUserWizard extends Wizard {
+ private final static Log log = LogFactory.getLog(NewUserWizard.class);
+ private Session session;
+ private UserAdminService userAdminService;
+ private JcrSecurityModel jcrSecurityModel;
+
+ // pages
+ private MainUserInfoWizardPage mainUserInfo;
+
+ public NewUserWizard(Session session, UserAdminService userAdminService,
+ JcrSecurityModel jcrSecurityModel) {
+ this.session = session;
+ this.userAdminService = userAdminService;
+ this.jcrSecurityModel = jcrSecurityModel;
+ }
+
+ @Override
+ public void addPages() {
+ mainUserInfo = new MainUserInfoWizardPage(userAdminService);
+ addPage(mainUserInfo);
+ }
+
+ @Override
+ public boolean performFinish() {
+ if (!canFinish())
+ return false;
+
+ String username = mainUserInfo.getUsername();
+ try {
+ // Node userProfile = SecurityJcrUtils.createUserProfile(session,
+ // username);
+ Node userProfile = jcrSecurityModel.sync(session, username, null);
+ session.getWorkspace().getVersionManager()
+ .checkout(userProfile.getPath());
+ mainUserInfo.mapToProfileNode(userProfile);
+ String password = mainUserInfo.getPassword();
+ // TODO add roles
+ JcrUserDetails jcrUserDetails = new JcrUserDetails(userProfile,
+ password, new GrantedAuthority[0]);
+ session.save();
+ session.getWorkspace().getVersionManager()
+ .checkin(userProfile.getPath());
+ userAdminService.createUser(jcrUserDetails);
+ return true;
+ } catch (Exception e) {
+ JcrUtils.discardQuietly(session);
+ Node userHome = UserJcrUtils.getUserHome(session, username);
+ if (userHome != null) {
+ try {
+ userHome.remove();
+ session.save();
+ } catch (RepositoryException e1) {
+ JcrUtils.discardQuietly(session);
+ log.warn("Error when trying to clean up failed new user "
+ + username, e1);
+ }
+ }
+ ErrorFeedback.show("Cannot create new user " + username, e);
+ return false;
+ }
+ }
+
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+}
--- /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.security.ui.admin.wizards;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.version.VersionManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.ArgeoMonitor;
+import org.argeo.eclipse.ui.EclipseArgeoMonitor;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.argeo.security.ui.PrivilegedJob;
+import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.UserTableComposite;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IPageChangeProvider;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.wizard.IWizardContainer;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/** Wizard to update users */
+public class UserBatchUpdateWizard extends Wizard {
+ private final static Log log = LogFactory
+ .getLog(UserBatchUpdateWizard.class);
+ private Session session;
+ private UserAdminService userAdminService;
+
+ // pages
+ private ChooseCommandWizardPage chooseCommandPage;
+ private ChooseUsersWizardPage userListPage;
+ private ValidateAndLaunchWizardPage validatePage;
+
+ // /////////////////////////////////////////////////
+ // / Definition of the various implemented commands
+ private final static String CMD_UPDATE_PASSWORD = "resetPassword";
+ private final static String CMD_GROUP_MEMBERSHIP = "groupMembership";
+
+ private final Map<String, String> commands = new HashMap<String, String>() {
+ private static final long serialVersionUID = 1L;
+ {
+ put("Enable user(s)", ArgeoNames.ARGEO_ENABLED);
+ put("Expire credentials", ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED);
+ put("Expire account(s)", ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED);
+ put("Lock account(s)", ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED);
+ put("Reset password(s)", CMD_UPDATE_PASSWORD);
+ // TODO implement role / group management
+ // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP);
+ }
+ };
+
+ public UserBatchUpdateWizard(Session session,
+ UserAdminService userAdminService, JcrSecurityModel jcrSecurityModel) {
+ this.session = session;
+ this.userAdminService = userAdminService;
+ // this.jcrSecurityModel = jcrSecurityModel;
+ }
+
+ @Override
+ public void addPages() {
+ chooseCommandPage = new ChooseCommandWizardPage();
+ addPage(chooseCommandPage);
+ userListPage = new ChooseUsersWizardPage(session);
+ addPage(userListPage);
+ validatePage = new ValidateAndLaunchWizardPage(session);
+ addPage(validatePage);
+ }
+
+ @Override
+ public boolean performFinish() {
+ if (!canFinish())
+ return false;
+
+ UpdateJob job = null;
+ if (ArgeoNames.ARGEO_ENABLED.equals(chooseCommandPage.getCommand())) {
+ job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
+ ArgeoNames.ARGEO_ENABLED,
+ chooseCommandPage.getBoleanValue());
+ } else if (ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED
+ .equals(chooseCommandPage.getCommand())) {
+ job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
+ ArgeoNames.ARGEO_CREDENTIALS_NON_EXPIRED,
+ chooseCommandPage.getBoleanValue());
+ } else if (ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED
+ .equals(chooseCommandPage.getCommand())) {
+ job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
+ ArgeoNames.ARGEO_ACCOUNT_NON_EXPIRED,
+ chooseCommandPage.getBoleanValue());
+ } else if (ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED.equals(chooseCommandPage
+ .getCommand())) {
+ job = new UpdateBoolean(session, userListPage.getSelectedUsers(),
+ ArgeoNames.ARGEO_ACCOUNT_NON_LOCKED,
+ chooseCommandPage.getBoleanValue());
+ } else if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) {
+ String newValue = chooseCommandPage.getPwdValue();
+ if (newValue == null)
+ throw new ArgeoException(
+ "Password cannot be null or an empty string");
+ job = new ResetPassword(session, userAdminService,
+ userListPage.getSelectedUsers(), newValue);
+ }
+
+ if (job != null)
+ job.schedule();
+ return true;
+ }
+
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+ public boolean canFinish() {
+ if (this.getContainer().getCurrentPage() == validatePage)
+ return true;
+ return false;
+ }
+
+ // /////////////////////////
+ // REEL UPDATE JOB
+ private class UpdateBoolean extends UpdateJob {
+ private String propertyName;
+ private boolean value;
+
+ public UpdateBoolean(Session session, List<Node> nodesToUpdate,
+ String propertyName, boolean value) {
+ super(session, nodesToUpdate);
+ this.propertyName = propertyName;
+ this.value = value;
+ }
+
+ protected void doUpdate(Node node) {
+ try {
+ node.setProperty(propertyName, value);
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unable to update boolean value for node " + node, re);
+ }
+ }
+ }
+
+ private class ResetPassword extends UpdateJob {
+ private String newValue;
+ private UserAdminService userAdminService;
+
+ public ResetPassword(Session session,
+ UserAdminService userAdminService, List<Node> nodesToUpdate,
+ String newValue) {
+ super(session, nodesToUpdate);
+ this.newValue = newValue;
+ this.userAdminService = userAdminService;
+ }
+
+ protected void doUpdate(Node node) {
+ try {
+ String userId = node.getProperty(ArgeoNames.ARGEO_USER_ID)
+ .getString();
+ if (userAdminService.userExists(userId)) {
+ JcrUserDetails userDetails = (JcrUserDetails) userAdminService
+ .loadUserByUsername(userId);
+ userAdminService.updateUser(userDetails
+ .cloneWithNewPassword(newValue));
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException(
+ "Unable to update boolean value for node " + node, re);
+ }
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private class AddToGroup extends UpdateJob {
+ private String groupID;
+ private Session session;
+
+ public AddToGroup(Session session, List<Node> nodesToUpdate,
+ String groupID) {
+ super(session, nodesToUpdate);
+ this.session = session;
+ this.groupID = groupID;
+ }
+
+ protected void doUpdate(Node node) {
+ log.info("Add/Remove to group actions are not yet implemented");
+ // TODO implement this
+ // try {
+ // throw new ArgeoException("Not yet implemented");
+ // } catch (RepositoryException re) {
+ // throw new ArgeoException(
+ // "Unable to update boolean value for node " + node, re);
+ // }
+ }
+ }
+
+ /**
+ * Base privileged job that will be run asynchronously to perform the batch
+ * update
+ */
+ private abstract class UpdateJob extends PrivilegedJob {
+
+ private final Session currSession;
+ private final List<Node> nodesToUpdate;
+
+ protected abstract void doUpdate(Node node);
+
+ public UpdateJob(Session session, List<Node> nodesToUpdate) {
+ super("Perform update");
+ try {
+ this.currSession = session.getRepository().login();
+ // "move" nodes to update in the new session
+ // the "old" session will be closed by the calling command
+ // before the job has effectively ran
+ // TODO there must be a cleaner way to do.
+ List<Node> nodes = new ArrayList<Node>();
+ for (Node node : nodesToUpdate) {
+ nodes.add(currSession.getNode(node.getPath()));
+ }
+ this.nodesToUpdate = nodes;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Error while dupplicating "
+ + "session for job", e);
+ }
+ }
+
+ @Override
+ protected IStatus doRun(IProgressMonitor progressMonitor) {
+ try {
+ ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor);
+ VersionManager vm = currSession.getWorkspace()
+ .getVersionManager();
+ int total = nodesToUpdate.size();
+ monitor.beginTask("Performing change", total);
+ for (Node node : nodesToUpdate) {
+ String path = node.getPath();
+ vm.checkout(path);
+ doUpdate(node);
+ currSession.save();
+ vm.checkin(path);
+ monitor.worked(1);
+ }
+ } catch (Exception e) {
+ log.error("Cannot perform batch update on users", e);
+ // e.printStackTrace();
+
+ // Dig exception to find the root cause that will enable the
+ // user to understand the problem
+ Throwable cause = e;
+ Throwable originalCause = e;
+ while (cause != null) {
+ if (log.isTraceEnabled())
+ log.trace("Parent Cause message : "
+ + cause.getMessage());
+ originalCause = cause;
+ cause = cause.getCause();
+ }
+ return new Status(IStatus.ERROR, SecurityAdminPlugin.PLUGIN_ID,
+ "Cannot perform updates.", originalCause);
+ } finally {
+ JcrUtils.logoutQuietly(currSession);
+ }
+ return Status.OK_STATUS;
+ }
+ }
+
+ // //////////////////////
+ // Pages definition
+ /** Displays a combo box that enables user to choose which action to perform */
+ private class ChooseCommandWizardPage extends WizardPage {
+ private static final long serialVersionUID = 1L;
+
+ private Combo chooseCommandCmb;
+ private Button trueChk;
+ private Text valueTxt;
+ private Text pwdTxt;
+ private Text pwd2Txt;
+
+ public ChooseCommandWizardPage() {
+ super("Choose a command to run.");
+ setTitle("Choose a command to run.");
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ GridLayout gl = new GridLayout();
+ Composite container = new Composite(parent, SWT.NO_FOCUS);
+ container.setLayout(gl);
+
+ chooseCommandCmb = new Combo(container, SWT.NO_FOCUS);
+ String[] values = commands.keySet().toArray(
+ new String[commands.size()]);
+ chooseCommandCmb.setItems(values);
+ chooseCommandCmb.setLayoutData(new GridData(SWT.FILL, SWT.TOP,
+ true, false));
+
+ final Composite bottomPart = new Composite(container, SWT.NO_FOCUS);
+ gl = new GridLayout();
+ gl.horizontalSpacing = gl.marginWidth = gl.verticalSpacing = 0;
+ bottomPart.setLayout(gl);
+ bottomPart.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
+ true));
+
+ chooseCommandCmb.addSelectionListener(new SelectionListener() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (getCommand().equals(CMD_UPDATE_PASSWORD))
+ populatePasswordCmp(bottomPart);
+ else if (getCommand().equals(CMD_GROUP_MEMBERSHIP))
+ populateGroupCmp(bottomPart);
+ else
+ populateBooleanFlagCmp(bottomPart);
+ bottomPart.pack(true);
+ bottomPart.layout();
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+
+ setControl(container);
+ }
+
+ private void cleanParent(Composite parent) {
+ if (parent.getChildren().length > 0) {
+ for (Control control : parent.getChildren())
+ control.dispose();
+ }
+ }
+
+ private void populateBooleanFlagCmp(Composite parent) {
+ cleanParent(parent);
+ trueChk = new Button(parent, SWT.CHECK);
+ trueChk.setText("Do it. (It will to the contrary if unchecked)");
+ trueChk.setSelection(true);
+ trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
+ }
+
+ private void populatePasswordCmp(Composite parent) {
+ cleanParent(parent);
+ Composite body = new Composite(parent, SWT.NO_FOCUS);
+ body.setLayout(new GridLayout(2, false));
+ body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ pwdTxt = createLP(body, "New password", "");
+ pwd2Txt = createLP(body, "Repeat password", "");
+ }
+
+ /** Creates label and password. */
+ protected Text createLP(Composite body, String label, String value) {
+ Label lbl = new Label(body, SWT.NONE);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ lbl.setText(label);
+ Text text = new Text(body, SWT.BORDER | SWT.PASSWORD);
+ text.setText(value);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ return text;
+ }
+
+ private void populateGroupCmp(Composite parent) {
+ if (parent.getChildren().length > 0) {
+ for (Control control : parent.getChildren())
+ control.dispose();
+ }
+ trueChk = new Button(parent, SWT.CHECK);
+ trueChk.setText("Add to group. (It will remove user(s) from the "
+ + "corresponding group if unchecked)");
+ trueChk.setSelection(true);
+ trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
+ }
+
+ protected String getCommand() {
+ return commands.get(chooseCommandCmb.getItem(chooseCommandCmb
+ .getSelectionIndex()));
+ }
+
+ protected String getCommandLbl() {
+ return chooseCommandCmb.getItem(chooseCommandCmb
+ .getSelectionIndex());
+ }
+
+ protected boolean getBoleanValue() {
+ // FIXME this is not consistent and will lead to errors.
+ if (ArgeoNames.ARGEO_ENABLED.equals(getCommand()))
+ return trueChk.getSelection();
+ else
+ return !trueChk.getSelection();
+ }
+
+ @SuppressWarnings("unused")
+ protected String getStringValue() {
+ String value = null;
+ if (valueTxt != null) {
+ value = valueTxt.getText();
+ if ("".equals(value.trim()))
+ value = null;
+ }
+ return value;
+ }
+
+ protected String getPwdValue() {
+ String newPwd = null;
+ if (pwdTxt == null || pwd2Txt == null)
+ return null;
+ if (!pwdTxt.getText().equals("") || !pwd2Txt.getText().equals("")) {
+ if (pwdTxt.getText().equals(pwd2Txt.getText())) {
+ newPwd = pwdTxt.getText();
+ pwdTxt.setText("");
+ pwd2Txt.setText("");
+ } else {
+ pwdTxt.setText("");
+ pwd2Txt.setText("");
+ throw new ArgeoException("Passwords are not equals");
+ }
+ }
+ return newPwd;
+ }
+ }
+
+ /**
+ * Displays a list of users with a check box to be able to choose some of
+ * them
+ */
+ private class ChooseUsersWizardPage extends WizardPage implements
+ IPageChangedListener {
+ private static final long serialVersionUID = 1L;
+ private UserTableComposite userTableCmp;
+ private Composite container;
+ private Session session;
+
+ public ChooseUsersWizardPage(Session session) {
+ super("Choose Users");
+ this.session = session;
+ setTitle("Select users who will be impacted");
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ container = new Composite(parent, SWT.NONE);
+ container.setLayout(new FillLayout());
+ userTableCmp = new MyUserTableCmp(container, SWT.NO_FOCUS, session);
+ userTableCmp.populate(true, true);
+ setControl(container);
+
+ // Add listener to update message when shown
+ final IWizardContainer container = this.getContainer();
+ if (container instanceof IPageChangeProvider) {
+ ((IPageChangeProvider) container).addPageChangedListener(this);
+ }
+
+ }
+
+ @Override
+ public void pageChanged(PageChangedEvent event) {
+ if (event.getSelectedPage() == this) {
+ String msg = "Chosen batch action: "
+ + chooseCommandPage.getCommandLbl();
+ ((WizardPage) event.getSelectedPage()).setMessage(msg);
+ }
+ }
+
+ protected List<Node> getSelectedUsers() {
+ return userTableCmp.getSelectedUsers();
+ }
+
+ private class MyUserTableCmp extends UserTableComposite {
+
+ private static final long serialVersionUID = 1L;
+
+ public MyUserTableCmp(Composite parent, int style, Session session) {
+ super(parent, style, session);
+ }
+
+ @Override
+ protected void refreshFilteredList() {
+ List<Node> nodes = new ArrayList<Node>();
+ try {
+ NodeIterator ni = listFilteredElements(session,
+ getFilterString());
+
+ users: while (ni.hasNext()) {
+ Node currNode = ni.nextNode();
+ String username = currNode.hasProperty(ARGEO_USER_ID) ? currNode
+ .getProperty(ARGEO_USER_ID).getString() : "";
+ if (username.equals(session.getUserID()))
+ continue users;
+ else
+ nodes.add(currNode);
+ }
+ getTableViewer().setInput(nodes.toArray());
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Unable to list users", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Recapitulation of input data before running real update
+ */
+ private class ValidateAndLaunchWizardPage extends WizardPage implements
+ IPageChangedListener {
+ private static final long serialVersionUID = 1L;
+ private UserTableComposite userTableCmp;
+ private Session session;
+
+ public ValidateAndLaunchWizardPage(Session session) {
+ super("Validate and launch");
+ this.session = session;
+ setTitle("Validate and launch");
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite mainCmp = new Composite(parent, SWT.NO_FOCUS);
+ mainCmp.setLayout(new FillLayout());
+
+ // Add listener to update user list when shown
+ final IWizardContainer container = this.getContainer();
+ if (container instanceof IPageChangeProvider) {
+ ((IPageChangeProvider) container).addPageChangedListener(this);
+ }
+
+ userTableCmp = new UserTableComposite(mainCmp, SWT.NO_FOCUS,
+ session);
+ userTableCmp.populate(false, false);
+ setControl(mainCmp);
+ }
+
+ @Override
+ public void pageChanged(PageChangedEvent event) {
+ if (event.getSelectedPage() == this) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ Object[] values = ((ArrayList) userListPage.getSelectedUsers())
+ .toArray(new Object[userListPage.getSelectedUsers()
+ .size()]);
+ userTableCmp.getTableViewer().setInput(values);
+ String msg = "Following batch action: ["
+ + chooseCommandPage.getCommandLbl()
+ + "] will be perfomed on the users listed below.\n"
+ + "Are you sure you want to proceed?";
+ ((WizardPage) event.getSelectedPage()).setMessage(msg);
+ }
+ }
+
+ // private class MyUserTableCmp extends UserTableComposite {
+ // public MyUserTableCmp(Composite parent, int style, Session session) {
+ // super(parent, style, session);
+ // }
+ //
+ // @Override
+ // protected void refreshFilteredList() {
+ // @SuppressWarnings({ "unchecked", "rawtypes" })
+ //
+ // setFilteredList(values);
+ // }
+ //
+ // @Override
+ // public void setVisible(boolean visible) {
+ // super.setVisible(visible);
+ // if (visible)
+ // refreshFilteredList();
+ // }
+ // }
+ }
+}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>>>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
-bin.includes = plugin.xml,\
- META-INF/,\
- branding/,\
- icons/
-source.. = src/main/java/
-output.. = target/classes/
+source.. = src/
+++ /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.security.ui.rap;
-
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.application.IEntryPoint;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * RAP entry point which authenticates the subject as anonymous, for public
- * unauthenticated access.
- */
-public class AnonymousEntryPoint implements IEntryPoint {
- private final static Log log = LogFactory.getLog(AnonymousEntryPoint.class);
-
- /**
- * How many seconds to wait before invalidating the session if the user has
- * not yet logged in.
- */
- private Integer loginTimeout = 1 * 60;
- private Integer sessionTimeout = 15 * 60;
-
- @Override
- public int createUI() {
- // Short login timeout so that the modal dialog login doesn't hang
- // around too long
- RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
-
- if (log.isDebugEnabled())
- log.debug("Anonymous THREAD=" + Thread.currentThread().getId()
- + ", sessionStore=" + RWT.getSessionStore().getId());
-
- // create display
- final Display display = PlatformUI.createDisplay();
-
- // log in
- final ILoginContext loginContext = SecureRapActivator
- .createLoginContext(SecureRapActivator.CONTEXT_SPRING_ANONYMOUS);
- Subject subject = null;
- try {
- loginContext.login();
- subject = loginContext.getSubject();
- } catch (LoginException e) {
- throw new ArgeoException(
- "Unexpected exception during authentication", e);
- }
-
- // identify after successful login
- if (log.isDebugEnabled())
- log.debug("Authenticated " + subject);
- final String username = subject.getPrincipals().iterator().next()
- .getName();
-
- // Once the user is logged in, she can have a longer session timeout
- RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
-
- // Logout callback when the display is disposed
- display.disposeExec(new Runnable() {
- public void run() {
- log.debug("Display disposed");
- logout(loginContext, username);
- }
- });
-
- //
- // RUN THE WORKBENCH
- //
- Integer returnCode = null;
- try {
- returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
- public Integer run() {
- RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor(
- null);
- int result = PlatformUI.createAndRunWorkbench(display,
- workbenchAdvisor);
- return new Integer(result);
- }
- });
- logout(loginContext, username);
- } finally {
- display.dispose();
- }
- return returnCode;
- }
-
- private void logout(ILoginContext secureContext, String username) {
- try {
- secureContext.logout();
- log.info("Logged out " + (username != null ? username : "")
- + " (THREAD=" + Thread.currentThread().getId() + ")");
- } catch (LoginException e) {
- log.error("Erorr when logging out", e);
- }
- }
-}
+++ /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.security.ui.rap;
-
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.application.IEntryPoint;
-import org.eclipse.ui.PlatformUI;
-import org.springframework.security.context.SecurityContextHolder;
-
-/**
- * RAP entry point which logs out the currently authenticated user
- */
-public class LogoutEntryPoint implements IEntryPoint {
- private final static Log log = LogFactory.getLog(LogoutEntryPoint.class);
-
- /**
- * From org.springframework.security.context.
- * HttpSessionContextIntegrationFilter
- */
- protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
-
- @Override
- public int createUI() {
- // create display
- PlatformUI.createDisplay();
-
- final ILoginContext loginContext = SecureRapActivator
- .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
- try {
- loginContext.logout();
- } catch (LoginException e) {
- e.printStackTrace();
- }
-
- RWT.getRequest().getSession()
- .removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
- SecurityContextHolder.clearContext();
- RWT.getRequest().getSession().setMaxInactiveInterval(1);
-
- if (log.isDebugEnabled())
- log.debug("Logged out session " + RWT.getSessionStore().getId());
- return 0;
- }
-}
+++ /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.security.ui.rap;
-
-import org.eclipse.rap.rwt.application.IEntryPoint;
-import org.eclipse.ui.PlatformUI;
-
-/**
- * RAP entry point which does doesing except creating the display
- */
-public class NullEntryPoint implements IEntryPoint {
- @Override
- public int createUI() {
- // create display
- PlatformUI.createDisplay();
- return 0;
- }
-}
+++ /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.security.ui.rap;
-
-import org.argeo.security.ui.commands.OpenHomePerspective;
-import org.eclipse.core.commands.Category;
-import org.eclipse.core.commands.Command;
-import org.eclipse.jface.action.ICoolBarManager;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-import org.eclipse.ui.commands.ICommandService;
-
-/** Eclipse rap specific action bar advisor */
-public class RapActionBarAdvisor extends ActionBarAdvisor {
- private final static String ID_BASE = "org.argeo.security.ui.rap";
- // private final static Log log = LogFactory
- // .getLog(SecureActionBarAdvisor.class);
-
- /** Null means anonymous */
- private String username = null;
-
- // private IAction logoutAction;
- // private IWorkbenchAction openPerspectiveDialogAction;
- // private IWorkbenchAction showViewMenuAction;
- // private IWorkbenchAction preferences;
- private IWorkbenchAction saveAction;
- private IWorkbenchAction saveAllAction;
-
- // private IWorkbenchAction closeAllAction;
-
- public RapActionBarAdvisor(IActionBarConfigurer configurer, String username) {
- super(configurer);
- this.username = username;
- }
-
- protected void makeActions(IWorkbenchWindow window) {
- // preferences = ActionFactory.PREFERENCES.create(window);
- // register(preferences);
- // openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
- // .create(window);
- // register(openPerspectiveDialogAction);
- // showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
- // register(showViewMenuAction);
- //
- // // logout
- // logoutAction = ActionFactory.QUIT.create(window);
- // // logoutAction = createLogoutAction();
- // register(logoutAction);
- //
- // Save semantics
- saveAction = ActionFactory.SAVE.create(window);
- register(saveAction);
- saveAllAction = ActionFactory.SAVE_ALL.create(window);
- register(saveAllAction);
- // closeAllAction = ActionFactory.CLOSE_ALL.create(window);
- // register(closeAllAction);
-
- }
-
- protected void fillMenuBar(IMenuManager menuBar) {
- // MenuManager fileMenu = new MenuManager("&File",
- // IWorkbenchActionConstants.M_FILE);
- // MenuManager editMenu = new MenuManager("&Edit",
- // IWorkbenchActionConstants.M_EDIT);
- // MenuManager windowMenu = new MenuManager("&Window",
- // IWorkbenchActionConstants.M_WINDOW);
- //
- // menuBar.add(fileMenu);
- // menuBar.add(editMenu);
- // menuBar.add(windowMenu);
- // // Add a group marker indicating where action set menus will appear.
- // menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
- //
- // // File
- // fileMenu.add(saveAction);
- // fileMenu.add(saveAllAction);
- // fileMenu.add(closeAllAction);
- // fileMenu.add(new
- // GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
- // fileMenu.add(new Separator());
- // fileMenu.add(logoutAction);
- //
- // // Edit
- // editMenu.add(preferences);
- //
- // // Window
- // windowMenu.add(openPerspectiveDialogAction);
- // windowMenu.add(showViewMenuAction);
- }
-
- @Override
- protected void fillCoolBar(ICoolBarManager coolBar) {
- if (username != null) {
- ICommandService cmdService = (ICommandService) getActionBarConfigurer()
- .getWindowConfigurer().getWorkbenchConfigurer()
- .getWorkbench().getService(ICommandService.class);
- Category userMenus = cmdService.getCategory(ID_BASE + ".userMenus");
- if (!userMenus.isDefined())
- userMenus.define("User Menus", "User related menus");
-
- Command userMenu = cmdService.getCommand(ID_BASE
- + ".userMenuCommand");
- if (userMenu.isDefined())
- userMenu.undefine();
- userMenu.define(username, "User menu actions", userMenus);
- userMenu.setHandler(new OpenHomePerspective());
-
- // userToolbar.add(new UserMenuAction());
- // coolBar.add(userToolbar);
- } else {// anonymous
- IToolBarManager userToolbar = new ToolBarManager(SWT.FLAT
- | SWT.RIGHT);
- // userToolbar.add(logoutAction);
- coolBar.add(userToolbar);
- }
- // IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT |
- // SWT.RIGHT);
- // saveToolbar.add(saveAction);
- // saveToolbar.add(saveAllAction);
- // coolBar.add(saveToolbar);
- }
-
- // class UserMenuAction extends Action implements IWorkbenchAction {
- //
- // public UserMenuAction() {
- // super(username, IAction.AS_DROP_DOWN_MENU);
- // // setMenuCreator(new UserMenu());
- // }
- //
- // @Override
- // public String getId() {
- // return "org.argeo.security.ui.rap.userMenu";
- // }
- //
- // @Override
- // public void dispose() {
- // }
- //
- // }
-
- // class UserMenu implements IMenuCreator {
- // private Menu menu;
- //
- // public Menu getMenu(Control parent) {
- // Menu menu = new Menu(parent);
- // addActionToMenu(menu, logoutAction);
- // return menu;
- // }
- //
- // private void addActionToMenu(Menu menu, IAction action) {
- // ActionContributionItem item = new ActionContributionItem(action);
- // item.fill(menu, -1);
- // }
- //
- // public void dispose() {
- // if (menu != null) {
- // menu.dispose();
- // }
- // }
- //
- // public Menu getMenu(Menu parent) {
- // // Not use
- // return null;
- // }
- //
- // }
-
- // protected IAction createLogoutAction() {
- // Subject subject = Subject.getSubject(AccessController.getContext());
- // final String username = subject.getPrincipals().iterator().next()
- // .getName();
- //
- // IAction logoutAction = new Action() {
- // public String getId() {
- // return SecureRapActivator.ID + ".logoutAction";
- // }
- //
- // public String getText() {
- // return "Logout " + username;
- // }
- //
- // public void run() {
- // // try {
- // // Subject subject = SecureRapActivator.getLoginContext()
- // // .getSubject();
- // // String subjectStr = subject.toString();
- // // subject.getPrincipals().clear();
- // // SecureRapActivator.getLoginContext().logout();
- // // log.info(subjectStr + " logged out");
- // // } catch (LoginException e) {
- // // log.error("Error when logging out", e);
- // // }
- // // SecureEntryPoint.logout(username);
- // // PlatformUI.getWorkbench().close();
- // // try {
- // // RWT.getRequest().getSession().setMaxInactiveInterval(1);
- // // } catch (Exception e) {
- // // if (log.isTraceEnabled())
- // // log.trace("Error when invalidating session", e);
- // // }
- // }
- //
- // };
- // return logoutAction;
- // }
-
-}
+++ /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.security.ui.rap;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-import org.eclipse.ui.internal.UIPlugin;
-
-/** Eclipse RAP specific window advisor */
-public class RapWindowAdvisor extends WorkbenchWindowAdvisor {
-
- private String username;
-
- public RapWindowAdvisor(IWorkbenchWindowConfigurer configurer,
- String username) {
- super(configurer);
- this.username = username;
- }
-
- @Override
- public ActionBarAdvisor createActionBarAdvisor(
- IActionBarConfigurer configurer) {
- return new RapActionBarAdvisor(configurer, username);
- }
-
- public void preWindowOpen() {
- IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
- configurer.setShowCoolBar(true);
- configurer.setShowMenuBar(false);
- configurer.setShowStatusLine(false);
- configurer.setShowPerspectiveBar(true);
- configurer.setTitle("Argeo Web UI"); //$NON-NLS-1$
- // Full screen, see
- // http://wiki.eclipse.org/RAP/FAQ#How_to_create_a_fullscreen_application
- configurer.setShellStyle(SWT.NO_TRIM);
- Rectangle bounds = Display.getCurrent().getBounds();
- configurer.setInitialSize(new Point(bounds.width, bounds.height));
-
- // Handle window resize in Rap 2.1+ see https://bugs.eclipse.org/bugs/show_bug.cgi?id=417254
- Display.getCurrent().addListener(SWT.Resize, new Listener() {
- @Override
- public void handleEvent(Event event) {
- Rectangle bounds = event.display.getBounds();
- IWorkbenchWindow iww = UIPlugin.getDefault().getWorkbench()
- .getActiveWorkbenchWindow();
- iww.getShell().setBounds(bounds);
- }
- });
- }
-
- @Override
- public void postWindowCreate() {
- Shell shell = getWindowConfigurer().getWindow().getShell();
- shell.setMaximized(true);
- }
-
- @Override
- public void postWindowOpen() {
- String defaultPerspective = getWindowConfigurer()
- .getWorkbenchConfigurer().getWorkbench()
- .getPerspectiveRegistry().getDefaultPerspective();
- if (defaultPerspective == null) {
- IWorkbenchWindow window = getWindowConfigurer().getWindow();
- if (window == null)
- return;
-
- IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
- .create(window);
- openPerspectiveDialogAction.run();
- }
- }
-
-}
+++ /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.security.ui.rap;
-
-import org.eclipse.ui.IPerspectiveDescriptor;
-import org.eclipse.ui.application.IWorkbenchConfigurer;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-/** Eclipse RAP specific workbench advisor */
-public class RapWorkbenchAdvisor extends WorkbenchAdvisor {
- public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
- public final static String SAVE_AND_RESTORE_PROPERTY = "org.argeo.security.ui.saveAndRestore";
-
- private String initialPerspective = System.getProperty(
- INITIAL_PERSPECTIVE_PROPERTY, null);
-
- private String username;
-
- public RapWorkbenchAdvisor(String username) {
- this.username = username;
- }
-
- @Override
- public void initialize(IWorkbenchConfigurer configurer) {
- super.initialize(configurer);
- Boolean saveAndRestore = Boolean.parseBoolean(System.getProperty(
- SAVE_AND_RESTORE_PROPERTY, "false"));
- configurer.setSaveAndRestore(saveAndRestore);
- }
-
- public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
- IWorkbenchWindowConfigurer configurer) {
- return new RapWindowAdvisor(configurer, username);
- }
-
- public String getInitialWindowPerspectiveId() {
- if (initialPerspective != null) {
- // check whether this user can see the declared perspective
- // (typically the perspective won't be listed if this user doesn't
- // have the right to see it)
- IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
- .getPerspectiveRegistry()
- .findPerspectiveWithId(initialPerspective);
- if (pd == null)
- return null;
- }
- return initialPerspective;
- }
-}
+++ /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.security.ui.rap;
-
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-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.util.LocaleUtils;
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.application.IEntryPoint;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.PlatformUI;
-import org.springframework.security.BadCredentialsException;
-import org.springframework.security.context.SecurityContext;
-import org.springframework.security.context.SecurityContextHolder;
-
-/**
- * RAP entry point with login capabilities. Once the user has been
- * authenticated, the workbench is run as a privileged action by the related
- * subject.
- */
-public class SecureEntryPoint implements IEntryPoint {
- private final static Log log = LogFactory.getLog(SecureEntryPoint.class);
-
- /**
- * From org.springframework.security.context.
- * HttpSessionContextIntegrationFilter
- */
- protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
-
- /**
- * How many seconds to wait before invalidating the session if the user has
- * not yet logged in.
- */
- private Integer loginTimeout = 1 * 60;
- // TODO make it configurable
- /** Default session timeout is 8 hours (European working day length) */
- private Integer sessionTimeout = 8 * 60 * 60;
-
- /** Override to provide an application specific workbench advisor */
- protected RapWorkbenchAdvisor createRapWorkbenchAdvisor(String username) {
- return new RapWorkbenchAdvisor(username);
- }
-
- @Override
- public final int createUI() {
- // Short login timeout so that the modal dialog login doesn't hang
- // around too long
- RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
-
- // Try to load security context thanks to the session processing filter
- HttpServletRequest httpRequest = RWT.getRequest();
- HttpSession httpSession = httpRequest.getSession();
- Object contextFromSessionObject = httpSession
- .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
- if (contextFromSessionObject != null)
- SecurityContextHolder
- .setContext((SecurityContext) contextFromSessionObject);
-
-// if (log.isDebugEnabled())
-// log.debug("THREAD=" + Thread.currentThread().getId()
-// + ", sessionStore=" + RWT.getSessionStore().getId()
-// + ", remote user=" + httpRequest.getRemoteUser());
-
- // create display
- final Display display = PlatformUI.createDisplay();
-
- // log in
- final ILoginContext loginContext = SecureRapActivator
- .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
- Subject subject = null;
- tryLogin: while (subject == null && !display.isDisposed()) {
- try {
- loginContext.login();
- subject = loginContext.getSubject();
-
- // add security context to session
- if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)
- httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
- SecurityContextHolder.getContext());
- // add thread locale to RWT session
- log.info("Locale "+LocaleUtils.threadLocale.get());
- RWT.setLocale(LocaleUtils.threadLocale.get());
-
- // Once the user is logged in, she can have a longer session
- // timeout
- RWT.getRequest().getSession()
- .setMaxInactiveInterval(sessionTimeout);
- if (log.isDebugEnabled())
- log.debug("Authenticated " + subject);
- } catch (LoginException e) {
- BadCredentialsException bce = wasCausedByBadCredentials(e);
- if (bce != null) {
- MessageDialog.openInformation(display.getActiveShell(),
- "Bad Credentials", bce.getMessage());
- // retry login
- continue tryLogin;
- }
- return processLoginDeath(display, e);
- }
- }
-
- final String username = subject.getPrincipals().iterator().next()
- .getName();
- // Logout callback when the display is disposed
- display.disposeExec(new Runnable() {
- public void run() {
- log.debug("Display disposed");
- logout(loginContext, username);
- }
- });
-
- //
- // RUN THE WORKBENCH
- //
- Integer returnCode = null;
- try {
- returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
- public Integer run() {
- RapWorkbenchAdvisor workbenchAdvisor = createRapWorkbenchAdvisor(username);
- int result = PlatformUI.createAndRunWorkbench(display,
- workbenchAdvisor);
- return new Integer(result);
- }
- });
- // logout(loginContext, username);
- } finally {
- display.dispose();
- }
- return returnCode;
- }
-
- private Integer processLoginDeath(Display display, LoginException e) {
- // check thread death
- ThreadDeath td = wasCausedByThreadDeath(e);
- if (td != null) {
- display.dispose();
- throw td;
- }
- if (!display.isDisposed()) {
- ErrorFeedback.show("Unexpected exception during authentication", e);
- // this was not just bad credentials or death thread
- RWT.getRequest().getSession().setMaxInactiveInterval(1);
- display.dispose();
- return -1;
- } else {
- throw new ArgeoException(
- "Unexpected exception during authentication", e);
- }
-
- }
-
- /** Recursively look for {@link BadCredentialsException} in the root causes. */
- private BadCredentialsException wasCausedByBadCredentials(Throwable t) {
- if (t instanceof BadCredentialsException)
- return (BadCredentialsException) t;
-
- if (t.getCause() != null)
- return wasCausedByBadCredentials(t.getCause());
- else
- return null;
- }
-
- /**
- * If there is a {@link ThreadDeath} in the root causes, rethrow it
- * (important for RAP cleaning mechanism)
- */
- protected ThreadDeath wasCausedByThreadDeath(Throwable t) {
- if (t instanceof ThreadDeath)
- return (ThreadDeath) t;
-
- if (t.getCause() != null)
- return wasCausedByThreadDeath(t.getCause());
- else
- return null;
- }
-
- protected void logout(ILoginContext secureContext, String username) {
- try {
- HttpServletRequest httpRequest = RWT.getRequest();
- HttpSession httpSession = httpRequest.getSession();
- httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null);
- RWT.getRequest().getSession().setMaxInactiveInterval(1);
- SecurityContextHolder.clearContext();
- secureContext.logout();
- log.info("Logged out " + (username != null ? username : "")
- + " (THREAD=" + Thread.currentThread().getId() + ")");
- } catch (LoginException e) {
- log.error("Erorr when logging out", e);
- }
- }
-}
+++ /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.security.ui.rap;
-
-import java.net.URL;
-
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.equinox.security.auth.LoginContextFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-/** Configure Equinox login context from the bundle context. */
-public class SecureRapActivator implements BundleActivator {
-
- public final static String ID = "org.argeo.security.ui.rap";
- public final static String CONTEXT_SPRING = "SPRING";
- public final static String CONTEXT_SPRING_ANONYMOUS = "SPRING_ANONYMOUS";
- private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
-
- private BundleContext bundleContext;
- private static SecureRapActivator activator = null;
-
- public void start(BundleContext bundleContext) throws Exception {
- activator = this;
- this.bundleContext = bundleContext;
- }
-
- public void stop(BundleContext context) throws Exception {
- bundleContext = null;
- activator = null;
- }
-
- public BundleContext getBundleContext() {
- return bundleContext;
- }
-
- public static SecureRapActivator getActivator() {
- return activator;
- }
-
- static ILoginContext createLoginContext(String contextName) {
- URL configUrl = getActivator().getBundleContext().getBundle()
- .getEntry(JAAS_CONFIG_FILE);
- return LoginContextFactory.createContext(contextName, configUrl);
- }
-}
+++ /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.security.ui.rap.commands;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-
-/** Default action of the user menu */
-public class UserMenu extends AbstractHandler {
-
- @Override
- public Object execute(ExecutionEvent event) throws ExecutionException {
- return null;
- }
-
-}
--- /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.security.ui.rap;
+
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.application.IEntryPoint;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * RAP entry point which authenticates the subject as anonymous, for public
+ * unauthenticated access.
+ */
+public class AnonymousEntryPoint implements IEntryPoint {
+ private final static Log log = LogFactory.getLog(AnonymousEntryPoint.class);
+
+ /**
+ * How many seconds to wait before invalidating the session if the user has
+ * not yet logged in.
+ */
+ private Integer loginTimeout = 1 * 60;
+ private Integer sessionTimeout = 15 * 60;
+
+ @Override
+ public int createUI() {
+ // Short login timeout so that the modal dialog login doesn't hang
+ // around too long
+ RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
+
+ if (log.isDebugEnabled())
+ log.debug("Anonymous THREAD=" + Thread.currentThread().getId()
+ + ", sessionStore=" + RWT.getSessionStore().getId());
+
+ // create display
+ final Display display = PlatformUI.createDisplay();
+
+ // log in
+ final ILoginContext loginContext = SecureRapActivator
+ .createLoginContext(SecureRapActivator.CONTEXT_SPRING_ANONYMOUS);
+ Subject subject = null;
+ try {
+ loginContext.login();
+ subject = loginContext.getSubject();
+ } catch (LoginException e) {
+ throw new ArgeoException(
+ "Unexpected exception during authentication", e);
+ }
+
+ // identify after successful login
+ if (log.isDebugEnabled())
+ log.debug("Authenticated " + subject);
+ final String username = subject.getPrincipals().iterator().next()
+ .getName();
+
+ // Once the user is logged in, she can have a longer session timeout
+ RWT.getRequest().getSession().setMaxInactiveInterval(sessionTimeout);
+
+ // Logout callback when the display is disposed
+ display.disposeExec(new Runnable() {
+ public void run() {
+ log.debug("Display disposed");
+ logout(loginContext, username);
+ }
+ });
+
+ //
+ // RUN THE WORKBENCH
+ //
+ Integer returnCode = null;
+ try {
+ returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
+ public Integer run() {
+ RapWorkbenchAdvisor workbenchAdvisor = new RapWorkbenchAdvisor(
+ null);
+ int result = PlatformUI.createAndRunWorkbench(display,
+ workbenchAdvisor);
+ return new Integer(result);
+ }
+ });
+ logout(loginContext, username);
+ } finally {
+ display.dispose();
+ }
+ return returnCode;
+ }
+
+ private void logout(ILoginContext secureContext, String username) {
+ try {
+ secureContext.logout();
+ log.info("Logged out " + (username != null ? username : "")
+ + " (THREAD=" + Thread.currentThread().getId() + ")");
+ } catch (LoginException e) {
+ log.error("Erorr when logging out", e);
+ }
+ }
+}
--- /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.security.ui.rap;
+
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.application.IEntryPoint;
+import org.eclipse.ui.PlatformUI;
+import org.springframework.security.context.SecurityContextHolder;
+
+/**
+ * RAP entry point which logs out the currently authenticated user
+ */
+public class LogoutEntryPoint implements IEntryPoint {
+ private final static Log log = LogFactory.getLog(LogoutEntryPoint.class);
+
+ /**
+ * From org.springframework.security.context.
+ * HttpSessionContextIntegrationFilter
+ */
+ protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
+
+ @Override
+ public int createUI() {
+ // create display
+ PlatformUI.createDisplay();
+
+ final ILoginContext loginContext = SecureRapActivator
+ .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
+ try {
+ loginContext.logout();
+ } catch (LoginException e) {
+ e.printStackTrace();
+ }
+
+ RWT.getRequest().getSession()
+ .removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
+ SecurityContextHolder.clearContext();
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+
+ if (log.isDebugEnabled())
+ log.debug("Logged out session " + RWT.getSessionStore().getId());
+ return 0;
+ }
+}
--- /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.security.ui.rap;
+
+import org.eclipse.rap.rwt.application.IEntryPoint;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * RAP entry point which does doesing except creating the display
+ */
+public class NullEntryPoint implements IEntryPoint {
+ @Override
+ public int createUI() {
+ // create display
+ PlatformUI.createDisplay();
+ return 0;
+ }
+}
--- /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.security.ui.rap;
+
+import org.argeo.security.ui.commands.OpenHomePerspective;
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.commands.ICommandService;
+
+/** Eclipse rap specific action bar advisor */
+public class RapActionBarAdvisor extends ActionBarAdvisor {
+ private final static String ID_BASE = "org.argeo.security.ui.rap";
+ // private final static Log log = LogFactory
+ // .getLog(SecureActionBarAdvisor.class);
+
+ /** Null means anonymous */
+ private String username = null;
+
+ // private IAction logoutAction;
+ // private IWorkbenchAction openPerspectiveDialogAction;
+ // private IWorkbenchAction showViewMenuAction;
+ // private IWorkbenchAction preferences;
+ private IWorkbenchAction saveAction;
+ private IWorkbenchAction saveAllAction;
+
+ // private IWorkbenchAction closeAllAction;
+
+ public RapActionBarAdvisor(IActionBarConfigurer configurer, String username) {
+ super(configurer);
+ this.username = username;
+ }
+
+ protected void makeActions(IWorkbenchWindow window) {
+ // preferences = ActionFactory.PREFERENCES.create(window);
+ // register(preferences);
+ // openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
+ // .create(window);
+ // register(openPerspectiveDialogAction);
+ // showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
+ // register(showViewMenuAction);
+ //
+ // // logout
+ // logoutAction = ActionFactory.QUIT.create(window);
+ // // logoutAction = createLogoutAction();
+ // register(logoutAction);
+ //
+ // Save semantics
+ saveAction = ActionFactory.SAVE.create(window);
+ register(saveAction);
+ saveAllAction = ActionFactory.SAVE_ALL.create(window);
+ register(saveAllAction);
+ // closeAllAction = ActionFactory.CLOSE_ALL.create(window);
+ // register(closeAllAction);
+
+ }
+
+ protected void fillMenuBar(IMenuManager menuBar) {
+ // MenuManager fileMenu = new MenuManager("&File",
+ // IWorkbenchActionConstants.M_FILE);
+ // MenuManager editMenu = new MenuManager("&Edit",
+ // IWorkbenchActionConstants.M_EDIT);
+ // MenuManager windowMenu = new MenuManager("&Window",
+ // IWorkbenchActionConstants.M_WINDOW);
+ //
+ // menuBar.add(fileMenu);
+ // menuBar.add(editMenu);
+ // menuBar.add(windowMenu);
+ // // Add a group marker indicating where action set menus will appear.
+ // menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ //
+ // // File
+ // fileMenu.add(saveAction);
+ // fileMenu.add(saveAllAction);
+ // fileMenu.add(closeAllAction);
+ // fileMenu.add(new
+ // GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ // fileMenu.add(new Separator());
+ // fileMenu.add(logoutAction);
+ //
+ // // Edit
+ // editMenu.add(preferences);
+ //
+ // // Window
+ // windowMenu.add(openPerspectiveDialogAction);
+ // windowMenu.add(showViewMenuAction);
+ }
+
+ @Override
+ protected void fillCoolBar(ICoolBarManager coolBar) {
+ if (username != null) {
+ ICommandService cmdService = (ICommandService) getActionBarConfigurer()
+ .getWindowConfigurer().getWorkbenchConfigurer()
+ .getWorkbench().getService(ICommandService.class);
+ Category userMenus = cmdService.getCategory(ID_BASE + ".userMenus");
+ if (!userMenus.isDefined())
+ userMenus.define("User Menus", "User related menus");
+
+ Command userMenu = cmdService.getCommand(ID_BASE
+ + ".userMenuCommand");
+ if (userMenu.isDefined())
+ userMenu.undefine();
+ userMenu.define(username, "User menu actions", userMenus);
+ userMenu.setHandler(new OpenHomePerspective());
+
+ // userToolbar.add(new UserMenuAction());
+ // coolBar.add(userToolbar);
+ } else {// anonymous
+ IToolBarManager userToolbar = new ToolBarManager(SWT.FLAT
+ | SWT.RIGHT);
+ // userToolbar.add(logoutAction);
+ coolBar.add(userToolbar);
+ }
+ // IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT |
+ // SWT.RIGHT);
+ // saveToolbar.add(saveAction);
+ // saveToolbar.add(saveAllAction);
+ // coolBar.add(saveToolbar);
+ }
+
+ // class UserMenuAction extends Action implements IWorkbenchAction {
+ //
+ // public UserMenuAction() {
+ // super(username, IAction.AS_DROP_DOWN_MENU);
+ // // setMenuCreator(new UserMenu());
+ // }
+ //
+ // @Override
+ // public String getId() {
+ // return "org.argeo.security.ui.rap.userMenu";
+ // }
+ //
+ // @Override
+ // public void dispose() {
+ // }
+ //
+ // }
+
+ // class UserMenu implements IMenuCreator {
+ // private Menu menu;
+ //
+ // public Menu getMenu(Control parent) {
+ // Menu menu = new Menu(parent);
+ // addActionToMenu(menu, logoutAction);
+ // return menu;
+ // }
+ //
+ // private void addActionToMenu(Menu menu, IAction action) {
+ // ActionContributionItem item = new ActionContributionItem(action);
+ // item.fill(menu, -1);
+ // }
+ //
+ // public void dispose() {
+ // if (menu != null) {
+ // menu.dispose();
+ // }
+ // }
+ //
+ // public Menu getMenu(Menu parent) {
+ // // Not use
+ // return null;
+ // }
+ //
+ // }
+
+ // protected IAction createLogoutAction() {
+ // Subject subject = Subject.getSubject(AccessController.getContext());
+ // final String username = subject.getPrincipals().iterator().next()
+ // .getName();
+ //
+ // IAction logoutAction = new Action() {
+ // public String getId() {
+ // return SecureRapActivator.ID + ".logoutAction";
+ // }
+ //
+ // public String getText() {
+ // return "Logout " + username;
+ // }
+ //
+ // public void run() {
+ // // try {
+ // // Subject subject = SecureRapActivator.getLoginContext()
+ // // .getSubject();
+ // // String subjectStr = subject.toString();
+ // // subject.getPrincipals().clear();
+ // // SecureRapActivator.getLoginContext().logout();
+ // // log.info(subjectStr + " logged out");
+ // // } catch (LoginException e) {
+ // // log.error("Error when logging out", e);
+ // // }
+ // // SecureEntryPoint.logout(username);
+ // // PlatformUI.getWorkbench().close();
+ // // try {
+ // // RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ // // } catch (Exception e) {
+ // // if (log.isTraceEnabled())
+ // // log.trace("Error when invalidating session", e);
+ // // }
+ // }
+ //
+ // };
+ // return logoutAction;
+ // }
+
+}
--- /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.security.ui.rap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+import org.eclipse.ui.internal.UIPlugin;
+
+/** Eclipse RAP specific window advisor */
+public class RapWindowAdvisor extends WorkbenchWindowAdvisor {
+
+ private String username;
+
+ public RapWindowAdvisor(IWorkbenchWindowConfigurer configurer,
+ String username) {
+ super(configurer);
+ this.username = username;
+ }
+
+ @Override
+ public ActionBarAdvisor createActionBarAdvisor(
+ IActionBarConfigurer configurer) {
+ return new RapActionBarAdvisor(configurer, username);
+ }
+
+ public void preWindowOpen() {
+ IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+ configurer.setShowCoolBar(true);
+ configurer.setShowMenuBar(false);
+ configurer.setShowStatusLine(false);
+ configurer.setShowPerspectiveBar(true);
+ configurer.setTitle("Argeo Web UI"); //$NON-NLS-1$
+ // Full screen, see
+ // http://wiki.eclipse.org/RAP/FAQ#How_to_create_a_fullscreen_application
+ configurer.setShellStyle(SWT.NO_TRIM);
+ Rectangle bounds = Display.getCurrent().getBounds();
+ configurer.setInitialSize(new Point(bounds.width, bounds.height));
+
+ // Handle window resize in Rap 2.1+ see https://bugs.eclipse.org/bugs/show_bug.cgi?id=417254
+ Display.getCurrent().addListener(SWT.Resize, new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ Rectangle bounds = event.display.getBounds();
+ IWorkbenchWindow iww = UIPlugin.getDefault().getWorkbench()
+ .getActiveWorkbenchWindow();
+ iww.getShell().setBounds(bounds);
+ }
+ });
+ }
+
+ @Override
+ public void postWindowCreate() {
+ Shell shell = getWindowConfigurer().getWindow().getShell();
+ shell.setMaximized(true);
+ }
+
+ @Override
+ public void postWindowOpen() {
+ String defaultPerspective = getWindowConfigurer()
+ .getWorkbenchConfigurer().getWorkbench()
+ .getPerspectiveRegistry().getDefaultPerspective();
+ if (defaultPerspective == null) {
+ IWorkbenchWindow window = getWindowConfigurer().getWindow();
+ if (window == null)
+ return;
+
+ IWorkbenchAction openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
+ .create(window);
+ openPerspectiveDialogAction.run();
+ }
+ }
+
+}
--- /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.security.ui.rap;
+
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/** Eclipse RAP specific workbench advisor */
+public class RapWorkbenchAdvisor extends WorkbenchAdvisor {
+ public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
+ public final static String SAVE_AND_RESTORE_PROPERTY = "org.argeo.security.ui.saveAndRestore";
+
+ private String initialPerspective = System.getProperty(
+ INITIAL_PERSPECTIVE_PROPERTY, null);
+
+ private String username;
+
+ public RapWorkbenchAdvisor(String username) {
+ this.username = username;
+ }
+
+ @Override
+ public void initialize(IWorkbenchConfigurer configurer) {
+ super.initialize(configurer);
+ Boolean saveAndRestore = Boolean.parseBoolean(System.getProperty(
+ SAVE_AND_RESTORE_PROPERTY, "false"));
+ configurer.setSaveAndRestore(saveAndRestore);
+ }
+
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
+ IWorkbenchWindowConfigurer configurer) {
+ return new RapWindowAdvisor(configurer, username);
+ }
+
+ public String getInitialWindowPerspectiveId() {
+ if (initialPerspective != null) {
+ // check whether this user can see the declared perspective
+ // (typically the perspective won't be listed if this user doesn't
+ // have the right to see it)
+ IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
+ .getPerspectiveRegistry()
+ .findPerspectiveWithId(initialPerspective);
+ if (pd == null)
+ return null;
+ }
+ return initialPerspective;
+ }
+}
--- /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.security.ui.rap;
+
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+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.util.LocaleUtils;
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.application.IEntryPoint;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.springframework.security.BadCredentialsException;
+import org.springframework.security.context.SecurityContext;
+import org.springframework.security.context.SecurityContextHolder;
+
+/**
+ * RAP entry point with login capabilities. Once the user has been
+ * authenticated, the workbench is run as a privileged action by the related
+ * subject.
+ */
+public class SecureEntryPoint implements IEntryPoint {
+ private final static Log log = LogFactory.getLog(SecureEntryPoint.class);
+
+ /**
+ * From org.springframework.security.context.
+ * HttpSessionContextIntegrationFilter
+ */
+ protected static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
+
+ /**
+ * How many seconds to wait before invalidating the session if the user has
+ * not yet logged in.
+ */
+ private Integer loginTimeout = 1 * 60;
+ // TODO make it configurable
+ /** Default session timeout is 8 hours (European working day length) */
+ private Integer sessionTimeout = 8 * 60 * 60;
+
+ /** Override to provide an application specific workbench advisor */
+ protected RapWorkbenchAdvisor createRapWorkbenchAdvisor(String username) {
+ return new RapWorkbenchAdvisor(username);
+ }
+
+ @Override
+ public final int createUI() {
+ // Short login timeout so that the modal dialog login doesn't hang
+ // around too long
+ RWT.getRequest().getSession().setMaxInactiveInterval(loginTimeout);
+
+ // Try to load security context thanks to the session processing filter
+ HttpServletRequest httpRequest = RWT.getRequest();
+ HttpSession httpSession = httpRequest.getSession();
+ Object contextFromSessionObject = httpSession
+ .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
+ if (contextFromSessionObject != null)
+ SecurityContextHolder
+ .setContext((SecurityContext) contextFromSessionObject);
+
+// if (log.isDebugEnabled())
+// log.debug("THREAD=" + Thread.currentThread().getId()
+// + ", sessionStore=" + RWT.getSessionStore().getId()
+// + ", remote user=" + httpRequest.getRemoteUser());
+
+ // create display
+ final Display display = PlatformUI.createDisplay();
+
+ // log in
+ final ILoginContext loginContext = SecureRapActivator
+ .createLoginContext(SecureRapActivator.CONTEXT_SPRING);
+ Subject subject = null;
+ tryLogin: while (subject == null && !display.isDisposed()) {
+ try {
+ loginContext.login();
+ subject = loginContext.getSubject();
+
+ // add security context to session
+ if (httpSession.getAttribute(SPRING_SECURITY_CONTEXT_KEY) == null)
+ httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY,
+ SecurityContextHolder.getContext());
+ // add thread locale to RWT session
+ log.info("Locale "+LocaleUtils.threadLocale.get());
+ RWT.setLocale(LocaleUtils.threadLocale.get());
+
+ // Once the user is logged in, she can have a longer session
+ // timeout
+ RWT.getRequest().getSession()
+ .setMaxInactiveInterval(sessionTimeout);
+ if (log.isDebugEnabled())
+ log.debug("Authenticated " + subject);
+ } catch (LoginException e) {
+ BadCredentialsException bce = wasCausedByBadCredentials(e);
+ if (bce != null) {
+ MessageDialog.openInformation(display.getActiveShell(),
+ "Bad Credentials", bce.getMessage());
+ // retry login
+ continue tryLogin;
+ }
+ return processLoginDeath(display, e);
+ }
+ }
+
+ final String username = subject.getPrincipals().iterator().next()
+ .getName();
+ // Logout callback when the display is disposed
+ display.disposeExec(new Runnable() {
+ public void run() {
+ log.debug("Display disposed");
+ logout(loginContext, username);
+ }
+ });
+
+ //
+ // RUN THE WORKBENCH
+ //
+ Integer returnCode = null;
+ try {
+ returnCode = Subject.doAs(subject, new PrivilegedAction<Integer>() {
+ public Integer run() {
+ RapWorkbenchAdvisor workbenchAdvisor = createRapWorkbenchAdvisor(username);
+ int result = PlatformUI.createAndRunWorkbench(display,
+ workbenchAdvisor);
+ return new Integer(result);
+ }
+ });
+ // logout(loginContext, username);
+ } finally {
+ display.dispose();
+ }
+ return returnCode;
+ }
+
+ private Integer processLoginDeath(Display display, LoginException e) {
+ // check thread death
+ ThreadDeath td = wasCausedByThreadDeath(e);
+ if (td != null) {
+ display.dispose();
+ throw td;
+ }
+ if (!display.isDisposed()) {
+ ErrorFeedback.show("Unexpected exception during authentication", e);
+ // this was not just bad credentials or death thread
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ display.dispose();
+ return -1;
+ } else {
+ throw new ArgeoException(
+ "Unexpected exception during authentication", e);
+ }
+
+ }
+
+ /** Recursively look for {@link BadCredentialsException} in the root causes. */
+ private BadCredentialsException wasCausedByBadCredentials(Throwable t) {
+ if (t instanceof BadCredentialsException)
+ return (BadCredentialsException) t;
+
+ if (t.getCause() != null)
+ return wasCausedByBadCredentials(t.getCause());
+ else
+ return null;
+ }
+
+ /**
+ * If there is a {@link ThreadDeath} in the root causes, rethrow it
+ * (important for RAP cleaning mechanism)
+ */
+ protected ThreadDeath wasCausedByThreadDeath(Throwable t) {
+ if (t instanceof ThreadDeath)
+ return (ThreadDeath) t;
+
+ if (t.getCause() != null)
+ return wasCausedByThreadDeath(t.getCause());
+ else
+ return null;
+ }
+
+ protected void logout(ILoginContext secureContext, String username) {
+ try {
+ HttpServletRequest httpRequest = RWT.getRequest();
+ HttpSession httpSession = httpRequest.getSession();
+ httpSession.setAttribute(SPRING_SECURITY_CONTEXT_KEY, null);
+ RWT.getRequest().getSession().setMaxInactiveInterval(1);
+ SecurityContextHolder.clearContext();
+ secureContext.logout();
+ log.info("Logged out " + (username != null ? username : "")
+ + " (THREAD=" + Thread.currentThread().getId() + ")");
+ } catch (LoginException e) {
+ log.error("Erorr when logging out", e);
+ }
+ }
+}
--- /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.security.ui.rap;
+
+import java.net.URL;
+
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.equinox.security.auth.LoginContextFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/** Configure Equinox login context from the bundle context. */
+public class SecureRapActivator implements BundleActivator {
+
+ public final static String ID = "org.argeo.security.ui.rap";
+ public final static String CONTEXT_SPRING = "SPRING";
+ public final static String CONTEXT_SPRING_ANONYMOUS = "SPRING_ANONYMOUS";
+ private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
+
+ private BundleContext bundleContext;
+ private static SecureRapActivator activator = null;
+
+ public void start(BundleContext bundleContext) throws Exception {
+ activator = this;
+ this.bundleContext = bundleContext;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ bundleContext = null;
+ activator = null;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public static SecureRapActivator getActivator() {
+ return activator;
+ }
+
+ static ILoginContext createLoginContext(String contextName) {
+ URL configUrl = getActivator().getBundleContext().getBundle()
+ .getEntry(JAAS_CONFIG_FILE);
+ return LoginContextFactory.createContext(contextName, configUrl);
+ }
+}
--- /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.security.ui.rap.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+
+/** Default action of the user menu */
+public class UserMenu extends AbstractHandler {
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ return null;
+ }
+
+}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
+++ /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.security.ui.rcp;
-
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.OperatingSystem;
-import org.eclipse.equinox.app.IApplication;
-import org.eclipse.equinox.app.IApplicationContext;
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-
-/**
- * RCP workbench initialization
- */
-public abstract class AbstractSecureApplication implements IApplication {
- final static String NODE_REPO_URI = "argeo.node.repo.uri";
-
- private static final Log log = LogFactory
- .getLog(AbstractSecureApplication.class);
-
- protected WorkbenchAdvisor createWorkbenchAdvisor(String username) {
- return new SecureWorkbenchAdvisor(username);
- }
-
- public Object start(IApplicationContext context) throws Exception {
- // wait for the system to be initialized
- // try {
- // Thread.sleep(3000);
- // } catch (Exception e2) {
- // // silent
- // }
-
- boolean remote = System.getProperty(NODE_REPO_URI) != null;
-
- // choose login context
- final ILoginContext loginContext;
- if (remote) {
- loginContext = SecureApplicationActivator
- .createLoginContext(SecureApplicationActivator.CONTEXT_REMOTE);
- } else {
- if (OperatingSystem.os == OperatingSystem.WINDOWS)
- loginContext = SecureApplicationActivator
- .createLoginContext(SecureApplicationActivator.CONTEXT_WINDOWS);
- else
- loginContext = SecureApplicationActivator
- .createLoginContext(SecureApplicationActivator.CONTEXT_NIX);
- }
-
- final Display display = PlatformUI.createDisplay();
-
- // login
- Subject subject = null;
- try {
- loginContext.login();
- subject = loginContext.getSubject();
- } catch (LoginException e) {
- log.error("Error when logging in.", e);
- display.dispose();
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e1) {
- // silent
- }
- return null;
- }
-
- // identify after successful login
- if (log.isDebugEnabled())
- log.debug("subject=" + subject);
- final String username = subject.getPrincipals().iterator().next()
- .getName();
- if (log.isDebugEnabled())
- log.debug(username + " logged in");
-// display.disposeExec(new Runnable() {
-// public void run() {
-// log.debug("Display disposed");
-// logout(loginContext, username);
-// }
-// });
-
- try {
- PrivilegedAction<?> privilegedAction = new PrivilegedAction<Object>() {
- public Object run() {
- int result = PlatformUI.createAndRunWorkbench(display,
- createWorkbenchAdvisor(username));
- return new Integer(result);
- }
- };
-
- Integer returnCode = (Integer) Subject.doAs(subject,
- privilegedAction);
- logout(loginContext, username);
- return processReturnCode(returnCode);
- } catch (Exception e) {
- if (subject != null)
- logout(loginContext, username);
- log.error("Unexpected error", e);
- } finally {
- display.dispose();
- }
- return null;
- }
-
- protected Integer processReturnCode(Integer returnCode) {
- if (returnCode == PlatformUI.RETURN_RESTART)
- return IApplication.EXIT_RESTART;
- else
- return IApplication.EXIT_OK;
- }
-
- static void logout(ILoginContext secureContext, String username) {
- try {
- secureContext.logout();
- log.info("Logged out " + (username != null ? username : "")
- + " (THREAD=" + Thread.currentThread().getId() + ")");
- } catch (LoginException e) {
- log.error("Erorr when logging out", e);
- }
- }
-
- public void stop() {
- final IWorkbench workbench;
- try {
- workbench = PlatformUI.getWorkbench();
- } catch (Exception e) {
- return;
- }
- if (workbench == null)
- return;
- final Display display = workbench.getDisplay();
- if (display != null && !display.isDisposed())
- display.syncExec(new Runnable() {
-
- public void run() {
- if (!display.isDisposed())
- workbench.close();
- }
- });
-
- if (log.isDebugEnabled())
- log.debug("workbench stopped");
- }
-
-}
+++ /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.security.ui.rcp;
-
-import org.eclipse.jface.action.GroupMarker;
-import org.eclipse.jface.action.ICoolBarManager;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-
-public class SecureActionBarAdvisor extends ActionBarAdvisor {
- private IWorkbenchAction exitAction;
- private IWorkbenchAction openPerspectiveDialogAction;
- private IWorkbenchAction showViewMenuAction;
- private IWorkbenchAction preferences;
- private IWorkbenchAction saveAction;
- private IWorkbenchAction saveAsAction;
- private IWorkbenchAction saveAllAction;
- private IWorkbenchAction closeAllAction;
-
- // private final Boolean isRcp;
-
- public SecureActionBarAdvisor(IActionBarConfigurer configurer, Boolean isRcp) {
- super(configurer);
- // this.isRcp = isRcp;
- }
-
- protected void makeActions(IWorkbenchWindow window) {
- preferences = ActionFactory.PREFERENCES.create(window);
- register(preferences);
- openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
- .create(window);
- register(openPerspectiveDialogAction);
- showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
- register(showViewMenuAction);
-
- exitAction = ActionFactory.QUIT.create(window);
- register(exitAction);
-
- // Save semantiocs
- saveAction = ActionFactory.SAVE.create(window);
- register(saveAction);
- saveAsAction = ActionFactory.SAVE_AS.create(window);
- register(saveAsAction);
- saveAllAction = ActionFactory.SAVE_ALL.create(window);
- register(saveAllAction);
- closeAllAction = ActionFactory.CLOSE_ALL.create(window);
- register(closeAllAction);
-
- }
-
- protected void fillMenuBar(IMenuManager menuBar) {
- MenuManager fileMenu = new MenuManager("&File",
- IWorkbenchActionConstants.M_FILE);
- MenuManager editMenu = new MenuManager("&Edit",
- IWorkbenchActionConstants.M_EDIT);
- MenuManager windowMenu = new MenuManager("&Window",
- IWorkbenchActionConstants.M_WINDOW);
-
- menuBar.add(fileMenu);
- menuBar.add(editMenu);
- menuBar.add(windowMenu);
- // Add a group marker indicating where action set menus will appear.
- menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-
- // File
- fileMenu.add(saveAction);
- fileMenu.add(saveAsAction);
- fileMenu.add(saveAllAction);
- fileMenu.add(closeAllAction);
- fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
- fileMenu.add(new Separator());
- fileMenu.add(exitAction);
-
- // Edit
- editMenu.add(preferences);
-
- // Window
- windowMenu.add(openPerspectiveDialogAction);
- windowMenu.add(showViewMenuAction);
- }
-
- @Override
- protected void fillCoolBar(ICoolBarManager coolBar) {
- IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
- saveToolbar.add(saveAction);
- saveToolbar.add(saveAllAction);
- coolBar.add(saveToolbar);
- }
-
-}
+++ /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.security.ui.rcp;
-
-import java.net.URL;
-
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.equinox.security.auth.LoginContextFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-/** Activator able to create {@link ILoginContext} */
-public class SecureApplicationActivator implements BundleActivator {
-
- public final static String CONTEXT_REMOTE = "REMOTE";
- public final static String CONTEXT_NIX = "NIX";
- public final static String CONTEXT_WINDOWS = "WINDOWS";
- private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
-
- private static BundleContext bundleContext;
-
- public void start(BundleContext bundleContext) throws Exception {
- SecureApplicationActivator.bundleContext = bundleContext;
- }
-
- public void stop(BundleContext context) throws Exception {
- }
-
- static ILoginContext createLoginContext(String context) {
- URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE);
- return LoginContextFactory.createContext(context, configUrl);
- }
-}
+++ /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.security.ui.rcp;
-
-
-public class SecureRcp extends AbstractSecureApplication {
-}
+++ /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.security.ui.rcp;
-
-import org.eclipse.ui.IPerspectiveDescriptor;
-import org.eclipse.ui.application.IWorkbenchConfigurer;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-/**
- * Workbench configuration which is aware of the logged in user and can remember
- * workbench state.
- */
-public class SecureWorkbenchAdvisor extends WorkbenchAdvisor {
- public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
- public final static String SAVE_AND_RESTORE_PROPERTY = "org.argeo.security.ui.saveAndRestore";
-
- private String initialPerspective = System.getProperty(
- INITIAL_PERSPECTIVE_PROPERTY, null);
-
- private final String username;
-
- public SecureWorkbenchAdvisor(String username) {
- this.username = username;
- }
-
- @Override
- public void initialize(final IWorkbenchConfigurer configurer) {
- super.initialize(configurer);
- Boolean saveAndRestore = Boolean.parseBoolean(System.getProperty(
- SAVE_AND_RESTORE_PROPERTY, "true"));
- configurer.setSaveAndRestore(saveAndRestore);
- }
-
- public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
- IWorkbenchWindowConfigurer configurer) {
- return new SecureWorkbenchWindowAdvisor(configurer, username);
- }
-
- public String getInitialWindowPerspectiveId() {
- if (initialPerspective != null) {
- // check whether this user can see the declared perspective
- // (typically the perspective won't be listed if this user doesn't
- // have the right to see it)
- IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
- .getPerspectiveRegistry()
- .findPerspectiveWithId(initialPerspective);
- if (pd == null)
- return null;
- }
- return initialPerspective;
- }
-
- protected String getUsername() {
- return username;
- }
-}
+++ /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.security.ui.rcp;
-
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.ui.application.ActionBarAdvisor;
-import org.eclipse.ui.application.IActionBarConfigurer;
-import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
-import org.eclipse.ui.application.WorkbenchWindowAdvisor;
-
-public class SecureWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
- private final String username;
-
- public SecureWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer,
- String username) {
- super(configurer);
- this.username = username;
- }
-
- public ActionBarAdvisor createActionBarAdvisor(
- IActionBarConfigurer configurer) {
- return new SecureActionBarAdvisor(configurer, true);
- }
-
- public void preWindowOpen() {
- IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
- configurer.setInitialSize(new Point(1200, 900));
- configurer.setShowCoolBar(true);
- configurer.setShowMenuBar(true);
- configurer.setShowStatusLine(true);
- configurer.setShowProgressIndicator(true);
-
- configurer.setShowPerspectiveBar(true);
- String remoteUri = System
- .getProperty(AbstractSecureApplication.NODE_REPO_URI);
- if (remoteUri != null)
- configurer
- .setTitle("Argeo UI - " + username + " (" + remoteUri + ")"); //$NON-NLS-1$
- else
- configurer.setTitle("Argeo UI - " + username); //$NON-NLS-1$
-
- }
-}
--- /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.security.ui.rcp;
+
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.OperatingSystem;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+
+/**
+ * RCP workbench initialization
+ */
+public abstract class AbstractSecureApplication implements IApplication {
+ final static String NODE_REPO_URI = "argeo.node.repo.uri";
+
+ private static final Log log = LogFactory
+ .getLog(AbstractSecureApplication.class);
+
+ protected WorkbenchAdvisor createWorkbenchAdvisor(String username) {
+ return new SecureWorkbenchAdvisor(username);
+ }
+
+ public Object start(IApplicationContext context) throws Exception {
+ // wait for the system to be initialized
+ // try {
+ // Thread.sleep(3000);
+ // } catch (Exception e2) {
+ // // silent
+ // }
+
+ boolean remote = System.getProperty(NODE_REPO_URI) != null;
+
+ // choose login context
+ final ILoginContext loginContext;
+ if (remote) {
+ loginContext = SecureApplicationActivator
+ .createLoginContext(SecureApplicationActivator.CONTEXT_REMOTE);
+ } else {
+ if (OperatingSystem.os == OperatingSystem.WINDOWS)
+ loginContext = SecureApplicationActivator
+ .createLoginContext(SecureApplicationActivator.CONTEXT_WINDOWS);
+ else
+ loginContext = SecureApplicationActivator
+ .createLoginContext(SecureApplicationActivator.CONTEXT_NIX);
+ }
+
+ final Display display = PlatformUI.createDisplay();
+
+ // login
+ Subject subject = null;
+ try {
+ loginContext.login();
+ subject = loginContext.getSubject();
+ } catch (LoginException e) {
+ log.error("Error when logging in.", e);
+ display.dispose();
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e1) {
+ // silent
+ }
+ return null;
+ }
+
+ // identify after successful login
+ if (log.isDebugEnabled())
+ log.debug("subject=" + subject);
+ final String username = subject.getPrincipals().iterator().next()
+ .getName();
+ if (log.isDebugEnabled())
+ log.debug(username + " logged in");
+// display.disposeExec(new Runnable() {
+// public void run() {
+// log.debug("Display disposed");
+// logout(loginContext, username);
+// }
+// });
+
+ try {
+ PrivilegedAction<?> privilegedAction = new PrivilegedAction<Object>() {
+ public Object run() {
+ int result = PlatformUI.createAndRunWorkbench(display,
+ createWorkbenchAdvisor(username));
+ return new Integer(result);
+ }
+ };
+
+ Integer returnCode = (Integer) Subject.doAs(subject,
+ privilegedAction);
+ logout(loginContext, username);
+ return processReturnCode(returnCode);
+ } catch (Exception e) {
+ if (subject != null)
+ logout(loginContext, username);
+ log.error("Unexpected error", e);
+ } finally {
+ display.dispose();
+ }
+ return null;
+ }
+
+ protected Integer processReturnCode(Integer returnCode) {
+ if (returnCode == PlatformUI.RETURN_RESTART)
+ return IApplication.EXIT_RESTART;
+ else
+ return IApplication.EXIT_OK;
+ }
+
+ static void logout(ILoginContext secureContext, String username) {
+ try {
+ secureContext.logout();
+ log.info("Logged out " + (username != null ? username : "")
+ + " (THREAD=" + Thread.currentThread().getId() + ")");
+ } catch (LoginException e) {
+ log.error("Erorr when logging out", e);
+ }
+ }
+
+ public void stop() {
+ final IWorkbench workbench;
+ try {
+ workbench = PlatformUI.getWorkbench();
+ } catch (Exception e) {
+ return;
+ }
+ if (workbench == null)
+ return;
+ final Display display = workbench.getDisplay();
+ if (display != null && !display.isDisposed())
+ display.syncExec(new Runnable() {
+
+ public void run() {
+ if (!display.isDisposed())
+ workbench.close();
+ }
+ });
+
+ if (log.isDebugEnabled())
+ log.debug("workbench stopped");
+ }
+
+}
--- /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.security.ui.rcp;
+
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+
+public class SecureActionBarAdvisor extends ActionBarAdvisor {
+ private IWorkbenchAction exitAction;
+ private IWorkbenchAction openPerspectiveDialogAction;
+ private IWorkbenchAction showViewMenuAction;
+ private IWorkbenchAction preferences;
+ private IWorkbenchAction saveAction;
+ private IWorkbenchAction saveAsAction;
+ private IWorkbenchAction saveAllAction;
+ private IWorkbenchAction closeAllAction;
+
+ // private final Boolean isRcp;
+
+ public SecureActionBarAdvisor(IActionBarConfigurer configurer, Boolean isRcp) {
+ super(configurer);
+ // this.isRcp = isRcp;
+ }
+
+ protected void makeActions(IWorkbenchWindow window) {
+ preferences = ActionFactory.PREFERENCES.create(window);
+ register(preferences);
+ openPerspectiveDialogAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG
+ .create(window);
+ register(openPerspectiveDialogAction);
+ showViewMenuAction = ActionFactory.SHOW_VIEW_MENU.create(window);
+ register(showViewMenuAction);
+
+ exitAction = ActionFactory.QUIT.create(window);
+ register(exitAction);
+
+ // Save semantiocs
+ saveAction = ActionFactory.SAVE.create(window);
+ register(saveAction);
+ saveAsAction = ActionFactory.SAVE_AS.create(window);
+ register(saveAsAction);
+ saveAllAction = ActionFactory.SAVE_ALL.create(window);
+ register(saveAllAction);
+ closeAllAction = ActionFactory.CLOSE_ALL.create(window);
+ register(closeAllAction);
+
+ }
+
+ protected void fillMenuBar(IMenuManager menuBar) {
+ MenuManager fileMenu = new MenuManager("&File",
+ IWorkbenchActionConstants.M_FILE);
+ MenuManager editMenu = new MenuManager("&Edit",
+ IWorkbenchActionConstants.M_EDIT);
+ MenuManager windowMenu = new MenuManager("&Window",
+ IWorkbenchActionConstants.M_WINDOW);
+
+ menuBar.add(fileMenu);
+ menuBar.add(editMenu);
+ menuBar.add(windowMenu);
+ // Add a group marker indicating where action set menus will appear.
+ menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+
+ // File
+ fileMenu.add(saveAction);
+ fileMenu.add(saveAsAction);
+ fileMenu.add(saveAllAction);
+ fileMenu.add(closeAllAction);
+ fileMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
+ fileMenu.add(new Separator());
+ fileMenu.add(exitAction);
+
+ // Edit
+ editMenu.add(preferences);
+
+ // Window
+ windowMenu.add(openPerspectiveDialogAction);
+ windowMenu.add(showViewMenuAction);
+ }
+
+ @Override
+ protected void fillCoolBar(ICoolBarManager coolBar) {
+ IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
+ saveToolbar.add(saveAction);
+ saveToolbar.add(saveAllAction);
+ coolBar.add(saveToolbar);
+ }
+
+}
--- /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.security.ui.rcp;
+
+import java.net.URL;
+
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.equinox.security.auth.LoginContextFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/** Activator able to create {@link ILoginContext} */
+public class SecureApplicationActivator implements BundleActivator {
+
+ public final static String CONTEXT_REMOTE = "REMOTE";
+ public final static String CONTEXT_NIX = "NIX";
+ public final static String CONTEXT_WINDOWS = "WINDOWS";
+ private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
+
+ private static BundleContext bundleContext;
+
+ public void start(BundleContext bundleContext) throws Exception {
+ SecureApplicationActivator.bundleContext = bundleContext;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ }
+
+ static ILoginContext createLoginContext(String context) {
+ URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE);
+ return LoginContextFactory.createContext(context, configUrl);
+ }
+}
--- /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.security.ui.rcp;
+
+
+public class SecureRcp extends AbstractSecureApplication {
+}
--- /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.security.ui.rcp;
+
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+/**
+ * Workbench configuration which is aware of the logged in user and can remember
+ * workbench state.
+ */
+public class SecureWorkbenchAdvisor extends WorkbenchAdvisor {
+ public final static String INITIAL_PERSPECTIVE_PROPERTY = "org.argeo.security.ui.initialPerspective";
+ public final static String SAVE_AND_RESTORE_PROPERTY = "org.argeo.security.ui.saveAndRestore";
+
+ private String initialPerspective = System.getProperty(
+ INITIAL_PERSPECTIVE_PROPERTY, null);
+
+ private final String username;
+
+ public SecureWorkbenchAdvisor(String username) {
+ this.username = username;
+ }
+
+ @Override
+ public void initialize(final IWorkbenchConfigurer configurer) {
+ super.initialize(configurer);
+ Boolean saveAndRestore = Boolean.parseBoolean(System.getProperty(
+ SAVE_AND_RESTORE_PROPERTY, "true"));
+ configurer.setSaveAndRestore(saveAndRestore);
+ }
+
+ public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
+ IWorkbenchWindowConfigurer configurer) {
+ return new SecureWorkbenchWindowAdvisor(configurer, username);
+ }
+
+ public String getInitialWindowPerspectiveId() {
+ if (initialPerspective != null) {
+ // check whether this user can see the declared perspective
+ // (typically the perspective won't be listed if this user doesn't
+ // have the right to see it)
+ IPerspectiveDescriptor pd = getWorkbenchConfigurer().getWorkbench()
+ .getPerspectiveRegistry()
+ .findPerspectiveWithId(initialPerspective);
+ if (pd == null)
+ return null;
+ }
+ return initialPerspective;
+ }
+
+ protected String getUsername() {
+ return username;
+ }
+}
--- /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.security.ui.rcp;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.IActionBarConfigurer;
+import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+
+public class SecureWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
+ private final String username;
+
+ public SecureWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer,
+ String username) {
+ super(configurer);
+ this.username = username;
+ }
+
+ public ActionBarAdvisor createActionBarAdvisor(
+ IActionBarConfigurer configurer) {
+ return new SecureActionBarAdvisor(configurer, true);
+ }
+
+ public void preWindowOpen() {
+ IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
+ configurer.setInitialSize(new Point(1200, 900));
+ configurer.setShowCoolBar(true);
+ configurer.setShowMenuBar(true);
+ configurer.setShowStatusLine(true);
+ configurer.setShowProgressIndicator(true);
+
+ configurer.setShowPerspectiveBar(true);
+ String remoteUri = System
+ .getProperty(AbstractSecureApplication.NODE_REPO_URI);
+ if (remoteUri != null)
+ configurer
+ .setTitle("Argeo UI - " + username + " (" + remoteUri + ")"); //$NON-NLS-1$
+ else
+ configurer.setTitle("Argeo UI - " + username); //$NON-NLS-1$
+
+ }
+}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>>>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
-source.. = src/main/java/
-output.. = target/classes/
-bin.includes = META-INF/,\
- .,\
- plugin.xml,\
- icons/
+source.. = src/
+++ /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.security.ui;
-
-import org.argeo.security.ui.views.AdminLogView;
-import org.argeo.security.ui.views.UserProfile;
-import org.eclipse.ui.IFolderLayout;
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-/** Home perspective for the current user */
-public class MaintenancePerspective implements IPerspectiveFactory {
- public final static String ID = SecurityUiPlugin.PLUGIN_ID
- + ".adminMaintenancePerspective";
-
- public void createInitialLayout(IPageLayout layout) {
- String editorArea = layout.getEditorArea();
- layout.setEditorAreaVisible(true);
- layout.setFixed(false);
-
- IFolderLayout bottom = layout.createFolder("bottom",
- IPageLayout.BOTTOM, 0.50f, editorArea);
- bottom.addView(AdminLogView.ID);
-
- IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
- 0.30f, editorArea);
- left.addView(UserProfile.ID);
- // left.addView(RolesView.ID);
-
- }
-
-}
+++ /dev/null
-package org.argeo.security.ui;
-
-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
+++ /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.security.ui;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.argeo.security.ui.internal.CurrentUser;
-import org.eclipse.ui.AbstractSourceProvider;
-
-/**
- * Provides the roles of the current user as a variable to be used for activity
- * binding
- */
-public class RolesSourceProvider extends AbstractSourceProvider {
- public final static String ROLES_VARIABLE = "roles";
- private final static String[] PROVIDED_SOURCE_NAMES = new String[] { ROLES_VARIABLE };
-
- public Map<String, Set<String>> getCurrentState() {
- Map<String, Set<String>> stateMap = new HashMap<String, Set<String>>();
- stateMap.put(ROLES_VARIABLE, CurrentUser.roles());
- return stateMap;
- }
-
- public String[] getProvidedSourceNames() {
- return PROVIDED_SOURCE_NAMES;
- }
-
- public void updateRoles() {
- fireSourceChanged(0, getCurrentState());
- }
-
- public void dispose() {
- }
-}
\ 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.security.ui;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.argeo.ArgeoException;
-import org.argeo.security.ui.dialogs.DefaultLoginDialog;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class SecurityUiPlugin extends AbstractUIPlugin {
-
- // The plug-in ID
- public static final String PLUGIN_ID = "org.argeo.security.ui"; //$NON-NLS-1$
-
- public final static String CONTEXT_KEYRING = "KEYRING";
-
- private CallbackHandler defaultCallbackHandler;
- private ServiceRegistration defaultCallbackHandlerReg;
-
- private static SecurityUiPlugin plugin;
-
- public static InheritableThreadLocal<Display> display = new InheritableThreadLocal<Display>() {
-
- @Override
- protected Display initialValue() {
- return Display.getCurrent();
- }
- };
-
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
-
- defaultCallbackHandler = new DefaultCallbackHandler();
- defaultCallbackHandlerReg = context.registerService(
- CallbackHandler.class.getName(), defaultCallbackHandler, null);
- }
-
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- defaultCallbackHandlerReg.unregister();
- super.stop(context);
- }
-
- /**
- * Returns the shared instance
- *
- * @return the shared instance
- */
- public static SecurityUiPlugin getDefault() {
- return plugin;
- }
-
- public static ImageDescriptor getImageDescriptor(String path) {
- return imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
-
- protected class DefaultCallbackHandler implements CallbackHandler {
- public void handle(final Callback[] callbacks) throws IOException,
- UnsupportedCallbackException {
-
- // if (display != null) // RCP
- Display displayToUse = display.get();
- if (displayToUse == null)// RCP
- displayToUse = Display.getDefault();
- displayToUse.syncExec(new Runnable() {
- public void run() {
- DefaultLoginDialog dialog = new DefaultLoginDialog(display
- .get().getActiveShell());
- try {
- dialog.handle(callbacks);
- } catch (IOException e) {
- throw new ArgeoException("Cannot open dialog", e);
- }
- }
- });
- // else {// RAP
- // DefaultLoginDialog dialog = new DefaultLoginDialog();
- // dialog.handle(callbacks);
- // }
- }
-
- }
-}
+++ /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.security.ui;
-
-import org.argeo.security.ui.views.LogView;
-import org.argeo.security.ui.views.UserProfile;
-import org.eclipse.ui.IFolderLayout;
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-/** Home perspective for the current user */
-public class UserHomePerspective implements IPerspectiveFactory {
- public final static String ID = SecurityUiPlugin.PLUGIN_ID
- + ".userHomePerspective";
-
- public void createInitialLayout(IPageLayout layout) {
- String editorArea = layout.getEditorArea();
- layout.setEditorAreaVisible(true);
- layout.setFixed(false);
-
- IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
- 0.30f, editorArea);
- left.addView(UserProfile.ID);
- left.addView(LogView.ID);
- }
-
-}
+++ /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.security.ui.commands;
-
-import org.argeo.security.ui.dialogs.ChangePasswordDialog;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.ui.handlers.HandlerUtil;
-import org.springframework.security.userdetails.UserDetailsManager;
-
-/** Opens the change password dialog. */
-public class OpenChangePasswordDialog extends AbstractHandler {
- private UserDetailsManager userDetailsManager;
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- ChangePasswordDialog dialog = new ChangePasswordDialog(
- HandlerUtil.getActiveShell(event), userDetailsManager);
- if (dialog.open() == Dialog.OK) {
- MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
- "Password changed", "Password changed.");
- }
- return null;
- }
-
- public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
- this.userDetailsManager = userDetailsManager;
- }
-
-}
+++ /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.security.ui.commands;
-
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.argeo.security.ui.UserHomePerspective;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.ui.WorkbenchException;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-/** Default action of the user menu */
-public class OpenHomePerspective extends AbstractHandler {
-
- public Object execute(ExecutionEvent event) throws ExecutionException {
- try {
- HandlerUtil.getActiveSite(event).getWorkbenchWindow()
- .openPage(UserHomePerspective.ID, null);
- } catch (WorkbenchException e) {
- ErrorFeedback.show("Cannot open home perspective", e);
- }
- return null;
- }
-
-}
+++ /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.security.ui.dialogs;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.security.ui.SecurityUiPlugin;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.TrayDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.operation.ModalContext;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/** Base for login dialogs */
-public abstract class AbstractLoginDialog extends TrayDialog implements
- CallbackHandler {
-
- private final static Log log = LogFactory.getLog(AbstractLoginDialog.class);
-
- private Thread modalContextThread = null;
- boolean processCallbacks = false;
- boolean isCancelled = false;
- Callback[] callbackArray;
-
- protected final Callback[] getCallbacks() {
- return this.callbackArray;
- }
-
- public abstract void internalHandle();
-
- public boolean isCancelled() {
- return isCancelled;
- }
-
- protected AbstractLoginDialog(Shell parentShell) {
- super(parentShell);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * javax.security.auth.callback.CallbackHandler#handle(javax.security.auth
- * .callback.Callback[])
- */
- public void handle(final Callback[] callbacks) throws IOException {
- // clean previous usage
- if (processCallbacks) {
- // this handler was already used
- processCallbacks = false;
- }
-
- if (modalContextThread != null) {
- try {
- modalContextThread.join(1000);
- } catch (InterruptedException e) {
- // silent
- }
- modalContextThread = null;
- }
-
- // initialize
- this.callbackArray = callbacks;
- final Display display = Display.getDefault();
- display.syncExec(new Runnable() {
-
- public void run() {
- isCancelled = false;
- setBlockOnOpen(false);
- open();
-
- final Button okButton = getButton(IDialogConstants.OK_ID);
- okButton.setText("Login");
- okButton.addSelectionListener(new SelectionListener() {
-
- public void widgetSelected(final SelectionEvent event) {
- processCallbacks = true;
- }
-
- public void widgetDefaultSelected(final SelectionEvent event) {
- // nothing to do
- }
- });
- final Button cancel = getButton(IDialogConstants.CANCEL_ID);
- cancel.addSelectionListener(new SelectionListener() {
-
- public void widgetSelected(final SelectionEvent event) {
- isCancelled = true;
- processCallbacks = true;
- }
-
- public void widgetDefaultSelected(final SelectionEvent event) {
- // nothing to do
- }
- });
- }
- });
- try {
- ModalContext.setAllowReadAndDispatch(true); // Works for now.
- ModalContext.run(new IRunnableWithProgress() {
-
- public void run(final IProgressMonitor monitor) {
- modalContextThread = Thread.currentThread();
- // Wait here until OK or cancel is pressed, then let it rip.
- // The event
- // listener
- // is responsible for closing the dialog (in the
- // loginSucceeded
- // event).
- while (!processCallbacks && (modalContextThread != null)
- && (modalContextThread == Thread.currentThread())
- && SecurityUiPlugin.getDefault() != null) {
- // Note: SecurityUiPlugin.getDefault() != null is false
- // when the OSGi runtime is shut down
- try {
- Thread.sleep(100);
- // if (display.isDisposed()) {
- // log.warn("Display is disposed, killing login dialog thread");
- // throw new ThreadDeath();
- // }
- } catch (final Exception e) {
- // do nothing
- }
- }
- processCallbacks = false;
- // Call the adapter to handle the callbacks
- if (!isCancelled())
- internalHandle();
- else
- // clear callbacks are when cancelling
- for (Callback callback : callbacks)
- if (callback instanceof PasswordCallback)
- ((PasswordCallback) callback).setPassword(null);
- else if (callback instanceof NameCallback)
- ((NameCallback) callback).setName(null);
- }
- }, true, new NullProgressMonitor(), Display.getDefault());
- } catch (ThreadDeath e) {
- isCancelled = true;
- log.debug("Thread " + Thread.currentThread().getId() + " died");
- throw e;
- } catch (Exception e) {
- isCancelled = true;
- IOException ioe = new IOException(
- "Unexpected issue in login dialog, see root cause for more details");
- ioe.initCause(e);
- throw ioe;
- } finally {
- // so that the modal thread dies
- processCallbacks = true;
- // try {
- // // wait for the modal context thread to gracefully exit
- // modalContextThread.join();
- // } catch (InterruptedException ie) {
- // // silent
- // }
- modalContextThread = null;
- }
- }
-
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText("Authentication");
- }
-}
+++ /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.security.ui.dialogs;
-
-import org.argeo.ArgeoException;
-import org.argeo.eclipse.ui.ErrorFeedback;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.springframework.security.userdetails.UserDetailsManager;
-
-/** Dialog to change the current user password */
-public class ChangePasswordDialog extends TitleAreaDialog {
- private Text currentPassword, newPassword1, newPassword2;
- private UserDetailsManager userDetailsManager;
-
- public ChangePasswordDialog(Shell parentShell,
- UserDetailsManager securityService) {
- super(parentShell);
- this.userDetailsManager = securityService;
- }
-
- protected Point getInitialSize() {
- return new Point(300, 250);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- currentPassword = createLP(composite, "Current password");
- newPassword1 = createLP(composite, "New password");
- newPassword2 = createLP(composite, "Repeat new password");
-
- setMessage("Change password", IMessageProvider.INFORMATION);
- parent.pack();
- return composite;
- }
-
- @Override
- protected void okPressed() {
- if (!newPassword1.getText().equals(newPassword2.getText()))
- throw new ArgeoException("Passwords are different");
- try {
- userDetailsManager.changePassword(currentPassword.getText(),
- newPassword1.getText());
- close();
- } catch (Exception e) {
- ErrorFeedback.show("Cannot change password", e);
- }
- }
-
- /** Creates label and password. */
- protected Text createLP(Composite parent, String label) {
- new Label(parent, SWT.NONE).setText(label);
- Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD
- | SWT.BORDER);
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- return text;
- }
-
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText("Change password");
- }
-
-}
+++ /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.security.ui.dialogs;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.TextOutputCallback;
-
-import org.argeo.security.ui.SecurityUiPlugin;
-import org.argeo.util.LocaleCallback;
-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.Point;
-import org.eclipse.swt.graphics.Rectangle;
-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.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/** Default authentication dialog, to be used as {@link CallbackHandler}. */
-public class DefaultLoginDialog extends AbstractLoginDialog {
- public DefaultLoginDialog() {
- this(SecurityUiPlugin.display.get().getActiveShell());
- }
-
- public DefaultLoginDialog(Shell parentShell) {
- super(parentShell);
- }
-
- protected Point getInitialSize() {
- return new Point(350, 180);
- }
-
- @Override
- protected Control createContents(Composite parent) {
- Control control = super.createContents(parent);
- parent.pack();
-
- // Move the dialog to the center of the top level shell.
- Rectangle shellBounds;
- if (Display.getCurrent().getActiveShell() != null) // RCP
- shellBounds = Display.getCurrent().getActiveShell().getBounds();
- else
- shellBounds = Display.getCurrent().getBounds();// RAP
- Point dialogSize = parent.getSize();
- int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
- int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
- parent.setLocation(x, y);
- return control;
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
- createCallbackHandlers(composite);
- // parent.pack();
- return composite;
- }
-
- private void createCallbackHandlers(Composite composite) {
- Callback[] callbacks = getCallbacks();
- for (int i = 0; i < callbacks.length; i++) {
- Callback callback = callbacks[i];
- if (callback instanceof TextOutputCallback) {
- createLabelTextoutputHandler(composite,
- (TextOutputCallback) callback);
- } else if (callback instanceof NameCallback) {
- createNameHandler(composite, (NameCallback) callback);
- } else if (callback instanceof PasswordCallback) {
- createPasswordHandler(composite, (PasswordCallback) callback);
- } else if (callback instanceof LocaleCallback) {
- createLocaleHandler(composite, (LocaleCallback) callback);
- }
- }
- }
-
- private void createPasswordHandler(Composite composite,
- final PasswordCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
- final Text passwordText = new Text(composite, SWT.SINGLE | SWT.LEAD
- | SWT.PASSWORD | SWT.BORDER);
- passwordText
- .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- passwordText.addModifyListener(new ModifyListener() {
-
- public void modifyText(ModifyEvent event) {
- // FIXME use getTextChars() in Eclipse 3.7
- callback.setPassword(passwordText.getText().toCharArray());
- }
- });
- }
-
- private void createLocaleHandler(Composite composite,
- final LocaleCallback callback) {
- String[] labels = callback.getSupportedLocalesLabels();
- if (labels.length == 0)
- return;
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
-
- final Combo combo = new Combo(composite, SWT.READ_ONLY);
- combo.setItems(labels);
- combo.select(callback.getDefaultIndex());
- combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- combo.addSelectionListener(new SelectionListener() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- callback.setSelectedIndex(combo.getSelectionIndex());
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
- }
-
- private void createNameHandler(Composite composite,
- final NameCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getPrompt());
- final Text text = new Text(composite, SWT.SINGLE | SWT.LEAD
- | SWT.BORDER);
- if (callback.getDefaultName() != null) {
- // set default value, if provided
- text.setText(callback.getDefaultName());
- callback.setName(callback.getDefaultName());
- }
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- text.addModifyListener(new ModifyListener() {
-
- public void modifyText(ModifyEvent event) {
- callback.setName(text.getText());
- }
- });
- }
-
- private void createLabelTextoutputHandler(Composite composite,
- final TextOutputCallback callback) {
- Label label = new Label(composite, SWT.NONE);
- label.setText(callback.getMessage());
- GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
- data.horizontalSpan = 2;
- label.setLayoutData(data);
- // TODO: find a way to pass this information
- // int messageType = callback.getMessageType();
- // int dialogMessageType = IMessageProvider.NONE;
- // switch (messageType) {
- // case TextOutputCallback.INFORMATION:
- // dialogMessageType = IMessageProvider.INFORMATION;
- // break;
- // case TextOutputCallback.WARNING:
- // dialogMessageType = IMessageProvider.WARNING;
- // break;
- // case TextOutputCallback.ERROR:
- // dialogMessageType = IMessageProvider.ERROR;
- // break;
- // }
- // setMessage(callback.getMessage(), dialogMessageType);
- }
-
- public void internalHandle() {
- }
-}
+++ /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.security.ui.internal;
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-
-import org.argeo.ArgeoException;
-import org.springframework.security.Authentication;
-import org.springframework.security.GrantedAuthority;
-
-/**
- * Retrieves information about the current user. Not an API, can change without
- * notice.
- */
-public class CurrentUser {
- public final static String getUsername() {
- Subject subject = getSubject();
- if (subject == null)
- return null;
- Principal principal = subject.getPrincipals().iterator().next();
- return principal.getName();
-
- }
-
- public final static Set<String> roles() {
- Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
- Authentication authentication = getAuthentication();
- for (GrantedAuthority ga : authentication.getAuthorities()) {
- roles.add(ga.getAuthority());
- }
- return Collections.unmodifiableSet(roles);
- }
-
- public final static Authentication getAuthentication() {
- Set<Authentication> authens = getSubject().getPrincipals(
- Authentication.class);
- if (authens != null && !authens.isEmpty()) {
- Principal principal = authens.iterator().next();
- Authentication authentication = (Authentication) principal;
- return authentication;
- }
- throw new ArgeoException("No authentication found");
- }
-
- public final static Subject getSubject() {
- Subject subject = Subject.getSubject(AccessController.getContext());
- if (subject == null)
- throw new ArgeoException("Not authenticated.");
- return subject;
- }
-}
+++ /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.security.ui.views;
-
-import java.util.ArrayList;
-
-import org.argeo.ArgeoLogger;
-import org.argeo.security.ui.SecurityUiPlugin;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.ui.part.ViewPart;
-
-/**
- * Display log lines for all users with a virtual table.
- */
-public class AdminLogView extends ViewPart {
- public static String ID = SecurityUiPlugin.PLUGIN_ID + ".adminLogView";
-
- private TableViewer viewer;
-
- private LogContentProvider logContentProvider;
- private ArgeoLogger argeoLogger;
-
- @Override
- public void createPartControl(Composite parent) {
- // FIXME doesn't return a monospace font in RAP
- Font font = JFaceResources.getTextFont();
- Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL
- | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
- table.setFont(font);
-
- viewer = new TableViewer(table);
- viewer.setLabelProvider(new LabelProvider());
- logContentProvider = new LogContentProvider(viewer) {
-
- @Override
- protected StringBuffer prefix(String username, Long timestamp,
- String level, String category, String thread) {
- return super
- .prefix(username, timestamp, level, category, thread)
- .append(norm(level, 5))
- .append(' ')
- .append(norm(username != null ? username
- : "<anonymous>", 16)).append(' ');
- }
- };
- viewer.setContentProvider(logContentProvider);
- // viewer.setUseHashlookup(true);
- viewer.setInput(new ArrayList<String>());
-
- if (argeoLogger != null)
- argeoLogger.registerForAll(logContentProvider, 1000, true);
- }
-
- @Override
- public void setFocus() {
- viewer.getTable().setFocus();
- }
-
- @Override
- public void dispose() {
- if (argeoLogger != null)
- argeoLogger.unregisterForAll(logContentProvider);
- }
-
- public void setArgeoLogger(ArgeoLogger argeoLogger) {
- this.argeoLogger = argeoLogger;
- }
-
-}
+++ /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.security.ui.views;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.argeo.ArgeoLogListener;
-import org.eclipse.jface.viewers.ILazyContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-/** A content provider maintaining an array of lines */
-class LogContentProvider implements ILazyContentProvider, ArgeoLogListener {
- private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
-
- private final Long start;
- /** current - start = line number. first line is number '1' */
- private Long current;
-
- // TODO make it configurable
- private final Integer maxLineBufferSize = 10 * 1000;
-
- private final TableViewer viewer;
- private LinkedList<LogLine> lines;
-
- public LogContentProvider(TableViewer viewer) {
- this.viewer = viewer;
- start = System.currentTimeMillis();
- lines = new LinkedList<LogLine>();
- current = start;
- }
-
- public synchronized void dispose() {
- lines.clear();
- lines = null;
- }
-
- @SuppressWarnings("unchecked")
- public synchronized void inputChanged(Viewer viewer, Object oldInput,
- Object newInput) {
- List<String> lin = (List<String>) newInput;
- if (lin == null)
- return;
- for (String line : lin) {
- addLine(line);
- }
- this.viewer.setItemCount(lines.size());
- }
-
- public void updateElement(int index) {
- viewer.replace(lines.get(index), index);
- }
-
- public synchronized void appendLog(String username, Long timestamp,
- String level, String category, String thread, Object msg,
- String[] exception) {
- // check if valid
- if (lines == null)
- return;
-
- String message = msg.toString();
- int count = 0;
- String prefix = prefix(username, timestamp, level, category, thread)
- .toString();
- // String suffix = suffix(username, timestamp, level, category, thread);
- for (String line : message.split("\n")) {
- addLine(count == 0 ? prefix + line : line);
- count++;
- }
-
- if (exception != null) {
- for (String ste : exception) {
- addLine(ste);
- }
- }
-
- viewer.getTable().getDisplay().asyncExec(new Runnable() {
- public void run() {
- if (lines == null)
- return;
- viewer.setItemCount(lines.size());
- // doesn't work with syncExec
- scrollToLastLine();
- }
- });
- }
-
- protected StringBuffer prefix(String username, Long timestamp,
- String level, String category, String thread) {
- StringBuffer buf = new StringBuffer("");
- buf.append(dateFormat.format(new Date(timestamp))).append(" ");
- // buf.append(level).append(" ");
- return buf;
- }
-
- /** Normalize string to the given size */
- protected String norm(String str, Integer size) {
- int length = str.length();
- if (length == size)
- return str;
- else if (length > size)
- return str.substring(0, size);
- else {
- char[] arr = new char[size - length];
- Arrays.fill(arr, ' ');
- return str + new String(arr);
- }
- }
-
- // protected String suffix(String username, Long timestamp, String level,
- // String category, String thread) {
- // return "";
- // }
-
- /** Scroll to the last line */
- protected synchronized void scrollToLastLine() {
- // we try to show last line with two methods
- // viewer.reveal(lines.peekLast());
-
- Table table = viewer.getTable();
- TableItem ti = table.getItem(table.getItemCount() - 1);
- table.showItem(ti);
- }
-
- protected synchronized LogLine addLine(String line) {
- // check for maximal size and purge if necessary
- while (lines.size() >= maxLineBufferSize) {
- for (int i = 0; i < maxLineBufferSize / 10; i++) {
- lines.poll();
- }
- }
-
- current++;
- LogLine logLine = new LogLine(current, line);
- lines.add(logLine);
- return logLine;
- }
-
- private class LogLine {
- private Long linenumber;
- private String message;
-
- public LogLine(Long linenumber, String message) {
- this.linenumber = linenumber;
- this.message = message;
- }
-
- @Override
- public int hashCode() {
- return linenumber.intValue();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof LogLine)
- return ((LogLine) obj).linenumber.equals(linenumber);
- else
- return false;
- }
-
- @Override
- public String toString() {
- return message;
- }
-
- }
-}
\ 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.security.ui.views;
-
-import java.util.ArrayList;
-
-import org.argeo.ArgeoLogListener;
-import org.argeo.ArgeoLogger;
-import org.argeo.security.ui.SecurityUiPlugin;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.ui.part.ViewPart;
-
-/**
- * Display log lines with a virtual table. Register and unregisters a
- * {@link ArgeoLogListener} via OSGi services.
- */
-public class LogView extends ViewPart {
- public static String ID = SecurityUiPlugin.PLUGIN_ID + ".logView";
-
- private TableViewer viewer;
-
- private LogContentProvider logContentProvider;
- private ArgeoLogger argeoLogger;
-
- @Override
- public void createPartControl(Composite parent) {
- Font font = JFaceResources.getTextFont();
- Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL
- | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
- table.setFont(font);
-
- viewer = new TableViewer(table);
- viewer.setLabelProvider(new LabelProvider());
- logContentProvider = new LogContentProvider(viewer);
- viewer.setContentProvider(logContentProvider);
- // viewer.setUseHashlookup(true);
- viewer.setInput(new ArrayList<String>());
-
- if (argeoLogger != null)
- argeoLogger.register(logContentProvider, 1000);
- }
-
- @Override
- public void setFocus() {
- viewer.getTable().setFocus();
- }
-
- @Override
- public void dispose() {
- if (argeoLogger != null)
- argeoLogger.unregister(logContentProvider);
- }
-
- public void setArgeoLogger(ArgeoLogger argeoLogger) {
- this.argeoLogger = argeoLogger;
- }
-
-}
+++ /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.security.ui.views;
-
-import java.util.TreeSet;
-
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.security.ui.SecurityUiPlugin;
-import org.argeo.security.ui.internal.CurrentUser;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-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.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.ui.part.ViewPart;
-import org.springframework.security.Authentication;
-
-/** Information about the currently logged in user */
-public class UserProfile extends ViewPart {
- public static String ID = SecurityUiPlugin.PLUGIN_ID + ".userProfile";
-
- private TableViewer viewer;
-
- @Override
- public void createPartControl(Composite parent) {
- parent.setLayout(new GridLayout(2, false));
-
- Authentication authentication = CurrentUser.getAuthentication();
- EclipseUiUtils.createGridLL(parent, "Name", authentication
- .getPrincipal().toString());
- EclipseUiUtils.createGridLL(parent, "User ID",
- CurrentUser.getUsername());
-
- // roles table
- Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER);
- table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
- table.setLinesVisible(false);
- table.setHeaderVisible(false);
- viewer = new TableViewer(table);
- viewer.setContentProvider(new RolesContentProvider());
- viewer.setLabelProvider(new LabelProvider());
- getViewSite().setSelectionProvider(viewer);
- viewer.setInput(getViewSite());
- }
-
- @Override
- public void setFocus() {
- viewer.getTable();
- }
-
- private class RolesContentProvider implements IStructuredContentProvider {
- public Object[] getElements(Object inputElement) {
- return new TreeSet<String>(CurrentUser.roles()).toArray();
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- }
-
-}
--- /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.security.ui;
+
+import org.argeo.security.ui.views.AdminLogView;
+import org.argeo.security.ui.views.UserProfile;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/** Home perspective for the current user */
+public class MaintenancePerspective implements IPerspectiveFactory {
+ public final static String ID = SecurityUiPlugin.PLUGIN_ID
+ + ".adminMaintenancePerspective";
+
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(true);
+ layout.setFixed(false);
+
+ IFolderLayout bottom = layout.createFolder("bottom",
+ IPageLayout.BOTTOM, 0.50f, editorArea);
+ bottom.addView(AdminLogView.ID);
+
+ IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
+ 0.30f, editorArea);
+ left.addView(UserProfile.ID);
+ // left.addView(RolesView.ID);
+
+ }
+
+}
--- /dev/null
+package org.argeo.security.ui;
+
+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
--- /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.security.ui;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.argeo.security.ui.internal.CurrentUser;
+import org.eclipse.ui.AbstractSourceProvider;
+
+/**
+ * Provides the roles of the current user as a variable to be used for activity
+ * binding
+ */
+public class RolesSourceProvider extends AbstractSourceProvider {
+ public final static String ROLES_VARIABLE = "roles";
+ private final static String[] PROVIDED_SOURCE_NAMES = new String[] { ROLES_VARIABLE };
+
+ public Map<String, Set<String>> getCurrentState() {
+ Map<String, Set<String>> stateMap = new HashMap<String, Set<String>>();
+ stateMap.put(ROLES_VARIABLE, CurrentUser.roles());
+ return stateMap;
+ }
+
+ public String[] getProvidedSourceNames() {
+ return PROVIDED_SOURCE_NAMES;
+ }
+
+ public void updateRoles() {
+ fireSourceChanged(0, getCurrentState());
+ }
+
+ public void dispose() {
+ }
+}
\ 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.security.ui;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.ui.dialogs.DefaultLoginDialog;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class SecurityUiPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.argeo.security.ui"; //$NON-NLS-1$
+
+ public final static String CONTEXT_KEYRING = "KEYRING";
+
+ private CallbackHandler defaultCallbackHandler;
+ private ServiceRegistration defaultCallbackHandlerReg;
+
+ private static SecurityUiPlugin plugin;
+
+ public static InheritableThreadLocal<Display> display = new InheritableThreadLocal<Display>() {
+
+ @Override
+ protected Display initialValue() {
+ return Display.getCurrent();
+ }
+ };
+
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ defaultCallbackHandler = new DefaultCallbackHandler();
+ defaultCallbackHandlerReg = context.registerService(
+ CallbackHandler.class.getName(), defaultCallbackHandler, null);
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ defaultCallbackHandlerReg.unregister();
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static SecurityUiPlugin getDefault() {
+ return plugin;
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+ protected class DefaultCallbackHandler implements CallbackHandler {
+ public void handle(final Callback[] callbacks) throws IOException,
+ UnsupportedCallbackException {
+
+ // if (display != null) // RCP
+ Display displayToUse = display.get();
+ if (displayToUse == null)// RCP
+ displayToUse = Display.getDefault();
+ displayToUse.syncExec(new Runnable() {
+ public void run() {
+ DefaultLoginDialog dialog = new DefaultLoginDialog(display
+ .get().getActiveShell());
+ try {
+ dialog.handle(callbacks);
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot open dialog", e);
+ }
+ }
+ });
+ // else {// RAP
+ // DefaultLoginDialog dialog = new DefaultLoginDialog();
+ // dialog.handle(callbacks);
+ // }
+ }
+
+ }
+}
--- /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.security.ui;
+
+import org.argeo.security.ui.views.LogView;
+import org.argeo.security.ui.views.UserProfile;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/** Home perspective for the current user */
+public class UserHomePerspective implements IPerspectiveFactory {
+ public final static String ID = SecurityUiPlugin.PLUGIN_ID
+ + ".userHomePerspective";
+
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+ layout.setEditorAreaVisible(true);
+ layout.setFixed(false);
+
+ IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
+ 0.30f, editorArea);
+ left.addView(UserProfile.ID);
+ left.addView(LogView.ID);
+ }
+
+}
--- /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.security.ui.commands;
+
+import org.argeo.security.ui.dialogs.ChangePasswordDialog;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.springframework.security.userdetails.UserDetailsManager;
+
+/** Opens the change password dialog. */
+public class OpenChangePasswordDialog extends AbstractHandler {
+ private UserDetailsManager userDetailsManager;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ChangePasswordDialog dialog = new ChangePasswordDialog(
+ HandlerUtil.getActiveShell(event), userDetailsManager);
+ if (dialog.open() == Dialog.OK) {
+ MessageDialog.openInformation(HandlerUtil.getActiveShell(event),
+ "Password changed", "Password changed.");
+ }
+ return null;
+ }
+
+ public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
+ this.userDetailsManager = userDetailsManager;
+ }
+
+}
--- /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.security.ui.commands;
+
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.argeo.security.ui.UserHomePerspective;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Default action of the user menu */
+public class OpenHomePerspective extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ try {
+ HandlerUtil.getActiveSite(event).getWorkbenchWindow()
+ .openPage(UserHomePerspective.ID, null);
+ } catch (WorkbenchException e) {
+ ErrorFeedback.show("Cannot open home perspective", e);
+ }
+ return null;
+ }
+
+}
--- /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.security.ui.dialogs;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** Base for login dialogs */
+public abstract class AbstractLoginDialog extends TrayDialog implements
+ CallbackHandler {
+
+ private final static Log log = LogFactory.getLog(AbstractLoginDialog.class);
+
+ private Thread modalContextThread = null;
+ boolean processCallbacks = false;
+ boolean isCancelled = false;
+ Callback[] callbackArray;
+
+ protected final Callback[] getCallbacks() {
+ return this.callbackArray;
+ }
+
+ public abstract void internalHandle();
+
+ public boolean isCancelled() {
+ return isCancelled;
+ }
+
+ protected AbstractLoginDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.security.auth.callback.CallbackHandler#handle(javax.security.auth
+ * .callback.Callback[])
+ */
+ public void handle(final Callback[] callbacks) throws IOException {
+ // clean previous usage
+ if (processCallbacks) {
+ // this handler was already used
+ processCallbacks = false;
+ }
+
+ if (modalContextThread != null) {
+ try {
+ modalContextThread.join(1000);
+ } catch (InterruptedException e) {
+ // silent
+ }
+ modalContextThread = null;
+ }
+
+ // initialize
+ this.callbackArray = callbacks;
+ final Display display = Display.getDefault();
+ display.syncExec(new Runnable() {
+
+ public void run() {
+ isCancelled = false;
+ setBlockOnOpen(false);
+ open();
+
+ final Button okButton = getButton(IDialogConstants.OK_ID);
+ okButton.setText("Login");
+ okButton.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(final SelectionEvent event) {
+ processCallbacks = true;
+ }
+
+ public void widgetDefaultSelected(final SelectionEvent event) {
+ // nothing to do
+ }
+ });
+ final Button cancel = getButton(IDialogConstants.CANCEL_ID);
+ cancel.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(final SelectionEvent event) {
+ isCancelled = true;
+ processCallbacks = true;
+ }
+
+ public void widgetDefaultSelected(final SelectionEvent event) {
+ // nothing to do
+ }
+ });
+ }
+ });
+ try {
+ ModalContext.setAllowReadAndDispatch(true); // Works for now.
+ ModalContext.run(new IRunnableWithProgress() {
+
+ public void run(final IProgressMonitor monitor) {
+ modalContextThread = Thread.currentThread();
+ // Wait here until OK or cancel is pressed, then let it rip.
+ // The event
+ // listener
+ // is responsible for closing the dialog (in the
+ // loginSucceeded
+ // event).
+ while (!processCallbacks && (modalContextThread != null)
+ && (modalContextThread == Thread.currentThread())
+ && SecurityUiPlugin.getDefault() != null) {
+ // Note: SecurityUiPlugin.getDefault() != null is false
+ // when the OSGi runtime is shut down
+ try {
+ Thread.sleep(100);
+ // if (display.isDisposed()) {
+ // log.warn("Display is disposed, killing login dialog thread");
+ // throw new ThreadDeath();
+ // }
+ } catch (final Exception e) {
+ // do nothing
+ }
+ }
+ processCallbacks = false;
+ // Call the adapter to handle the callbacks
+ if (!isCancelled())
+ internalHandle();
+ else
+ // clear callbacks are when cancelling
+ for (Callback callback : callbacks)
+ if (callback instanceof PasswordCallback)
+ ((PasswordCallback) callback).setPassword(null);
+ else if (callback instanceof NameCallback)
+ ((NameCallback) callback).setName(null);
+ }
+ }, true, new NullProgressMonitor(), Display.getDefault());
+ } catch (ThreadDeath e) {
+ isCancelled = true;
+ log.debug("Thread " + Thread.currentThread().getId() + " died");
+ throw e;
+ } catch (Exception e) {
+ isCancelled = true;
+ IOException ioe = new IOException(
+ "Unexpected issue in login dialog, see root cause for more details");
+ ioe.initCause(e);
+ throw ioe;
+ } finally {
+ // so that the modal thread dies
+ processCallbacks = true;
+ // try {
+ // // wait for the modal context thread to gracefully exit
+ // modalContextThread.join();
+ // } catch (InterruptedException ie) {
+ // // silent
+ // }
+ modalContextThread = null;
+ }
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Authentication");
+ }
+}
--- /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.security.ui.dialogs;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.ErrorFeedback;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.springframework.security.userdetails.UserDetailsManager;
+
+/** Dialog to change the current user password */
+public class ChangePasswordDialog extends TitleAreaDialog {
+ private Text currentPassword, newPassword1, newPassword2;
+ private UserDetailsManager userDetailsManager;
+
+ public ChangePasswordDialog(Shell parentShell,
+ UserDetailsManager securityService) {
+ super(parentShell);
+ this.userDetailsManager = securityService;
+ }
+
+ protected Point getInitialSize() {
+ return new Point(300, 250);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ currentPassword = createLP(composite, "Current password");
+ newPassword1 = createLP(composite, "New password");
+ newPassword2 = createLP(composite, "Repeat new password");
+
+ setMessage("Change password", IMessageProvider.INFORMATION);
+ parent.pack();
+ return composite;
+ }
+
+ @Override
+ protected void okPressed() {
+ if (!newPassword1.getText().equals(newPassword2.getText()))
+ throw new ArgeoException("Passwords are different");
+ try {
+ userDetailsManager.changePassword(currentPassword.getText(),
+ newPassword1.getText());
+ close();
+ } catch (Exception e) {
+ ErrorFeedback.show("Cannot change password", e);
+ }
+ }
+
+ /** Creates label and password. */
+ protected Text createLP(Composite parent, String label) {
+ new Label(parent, SWT.NONE).setText(label);
+ Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.PASSWORD
+ | SWT.BORDER);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ return text;
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Change password");
+ }
+
+}
--- /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.security.ui.dialogs;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.TextOutputCallback;
+
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.argeo.util.LocaleCallback;
+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.Point;
+import org.eclipse.swt.graphics.Rectangle;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/** Default authentication dialog, to be used as {@link CallbackHandler}. */
+public class DefaultLoginDialog extends AbstractLoginDialog {
+ public DefaultLoginDialog() {
+ this(SecurityUiPlugin.display.get().getActiveShell());
+ }
+
+ public DefaultLoginDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ protected Point getInitialSize() {
+ return new Point(350, 180);
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Control control = super.createContents(parent);
+ parent.pack();
+
+ // Move the dialog to the center of the top level shell.
+ Rectangle shellBounds;
+ if (Display.getCurrent().getActiveShell() != null) // RCP
+ shellBounds = Display.getCurrent().getActiveShell().getBounds();
+ else
+ shellBounds = Display.getCurrent().getBounds();// RAP
+ Point dialogSize = parent.getSize();
+ int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+ int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+ parent.setLocation(x, y);
+ return control;
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ createCallbackHandlers(composite);
+ // parent.pack();
+ return composite;
+ }
+
+ private void createCallbackHandlers(Composite composite) {
+ Callback[] callbacks = getCallbacks();
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (callback instanceof TextOutputCallback) {
+ createLabelTextoutputHandler(composite,
+ (TextOutputCallback) callback);
+ } else if (callback instanceof NameCallback) {
+ createNameHandler(composite, (NameCallback) callback);
+ } else if (callback instanceof PasswordCallback) {
+ createPasswordHandler(composite, (PasswordCallback) callback);
+ } else if (callback instanceof LocaleCallback) {
+ createLocaleHandler(composite, (LocaleCallback) callback);
+ }
+ }
+ }
+
+ private void createPasswordHandler(Composite composite,
+ final PasswordCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+ final Text passwordText = new Text(composite, SWT.SINGLE | SWT.LEAD
+ | SWT.PASSWORD | SWT.BORDER);
+ passwordText
+ .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ passwordText.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent event) {
+ // FIXME use getTextChars() in Eclipse 3.7
+ callback.setPassword(passwordText.getText().toCharArray());
+ }
+ });
+ }
+
+ private void createLocaleHandler(Composite composite,
+ final LocaleCallback callback) {
+ String[] labels = callback.getSupportedLocalesLabels();
+ if (labels.length == 0)
+ return;
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+
+ final Combo combo = new Combo(composite, SWT.READ_ONLY);
+ combo.setItems(labels);
+ combo.select(callback.getDefaultIndex());
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ combo.addSelectionListener(new SelectionListener() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ callback.setSelectedIndex(combo.getSelectionIndex());
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+ }
+
+ private void createNameHandler(Composite composite,
+ final NameCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getPrompt());
+ final Text text = new Text(composite, SWT.SINGLE | SWT.LEAD
+ | SWT.BORDER);
+ if (callback.getDefaultName() != null) {
+ // set default value, if provided
+ text.setText(callback.getDefaultName());
+ callback.setName(callback.getDefaultName());
+ }
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ text.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent event) {
+ callback.setName(text.getText());
+ }
+ });
+ }
+
+ private void createLabelTextoutputHandler(Composite composite,
+ final TextOutputCallback callback) {
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(callback.getMessage());
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+ // TODO: find a way to pass this information
+ // int messageType = callback.getMessageType();
+ // int dialogMessageType = IMessageProvider.NONE;
+ // switch (messageType) {
+ // case TextOutputCallback.INFORMATION:
+ // dialogMessageType = IMessageProvider.INFORMATION;
+ // break;
+ // case TextOutputCallback.WARNING:
+ // dialogMessageType = IMessageProvider.WARNING;
+ // break;
+ // case TextOutputCallback.ERROR:
+ // dialogMessageType = IMessageProvider.ERROR;
+ // break;
+ // }
+ // setMessage(callback.getMessage(), dialogMessageType);
+ }
+
+ public void internalHandle() {
+ }
+}
--- /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.security.ui.internal;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.argeo.ArgeoException;
+import org.springframework.security.Authentication;
+import org.springframework.security.GrantedAuthority;
+
+/**
+ * Retrieves information about the current user. Not an API, can change without
+ * notice.
+ */
+public class CurrentUser {
+ public final static String getUsername() {
+ Subject subject = getSubject();
+ if (subject == null)
+ return null;
+ Principal principal = subject.getPrincipals().iterator().next();
+ return principal.getName();
+
+ }
+
+ public final static Set<String> roles() {
+ Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
+ Authentication authentication = getAuthentication();
+ for (GrantedAuthority ga : authentication.getAuthorities()) {
+ roles.add(ga.getAuthority());
+ }
+ return Collections.unmodifiableSet(roles);
+ }
+
+ public final static Authentication getAuthentication() {
+ Set<Authentication> authens = getSubject().getPrincipals(
+ Authentication.class);
+ if (authens != null && !authens.isEmpty()) {
+ Principal principal = authens.iterator().next();
+ Authentication authentication = (Authentication) principal;
+ return authentication;
+ }
+ throw new ArgeoException("No authentication found");
+ }
+
+ public final static Subject getSubject() {
+ Subject subject = Subject.getSubject(AccessController.getContext());
+ if (subject == null)
+ throw new ArgeoException("Not authenticated.");
+ return subject;
+ }
+}
--- /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.security.ui.views;
+
+import java.util.ArrayList;
+
+import org.argeo.ArgeoLogger;
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * Display log lines for all users with a virtual table.
+ */
+public class AdminLogView extends ViewPart {
+ public static String ID = SecurityUiPlugin.PLUGIN_ID + ".adminLogView";
+
+ private TableViewer viewer;
+
+ private LogContentProvider logContentProvider;
+ private ArgeoLogger argeoLogger;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ // FIXME doesn't return a monospace font in RAP
+ Font font = JFaceResources.getTextFont();
+ Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
+ table.setFont(font);
+
+ viewer = new TableViewer(table);
+ viewer.setLabelProvider(new LabelProvider());
+ logContentProvider = new LogContentProvider(viewer) {
+
+ @Override
+ protected StringBuffer prefix(String username, Long timestamp,
+ String level, String category, String thread) {
+ return super
+ .prefix(username, timestamp, level, category, thread)
+ .append(norm(level, 5))
+ .append(' ')
+ .append(norm(username != null ? username
+ : "<anonymous>", 16)).append(' ');
+ }
+ };
+ viewer.setContentProvider(logContentProvider);
+ // viewer.setUseHashlookup(true);
+ viewer.setInput(new ArrayList<String>());
+
+ if (argeoLogger != null)
+ argeoLogger.registerForAll(logContentProvider, 1000, true);
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getTable().setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ if (argeoLogger != null)
+ argeoLogger.unregisterForAll(logContentProvider);
+ }
+
+ public void setArgeoLogger(ArgeoLogger argeoLogger) {
+ this.argeoLogger = argeoLogger;
+ }
+
+}
--- /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.security.ui.views;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.argeo.ArgeoLogListener;
+import org.eclipse.jface.viewers.ILazyContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/** A content provider maintaining an array of lines */
+class LogContentProvider implements ILazyContentProvider, ArgeoLogListener {
+ private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
+
+ private final Long start;
+ /** current - start = line number. first line is number '1' */
+ private Long current;
+
+ // TODO make it configurable
+ private final Integer maxLineBufferSize = 10 * 1000;
+
+ private final TableViewer viewer;
+ private LinkedList<LogLine> lines;
+
+ public LogContentProvider(TableViewer viewer) {
+ this.viewer = viewer;
+ start = System.currentTimeMillis();
+ lines = new LinkedList<LogLine>();
+ current = start;
+ }
+
+ public synchronized void dispose() {
+ lines.clear();
+ lines = null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ List<String> lin = (List<String>) newInput;
+ if (lin == null)
+ return;
+ for (String line : lin) {
+ addLine(line);
+ }
+ this.viewer.setItemCount(lines.size());
+ }
+
+ public void updateElement(int index) {
+ viewer.replace(lines.get(index), index);
+ }
+
+ public synchronized void appendLog(String username, Long timestamp,
+ String level, String category, String thread, Object msg,
+ String[] exception) {
+ // check if valid
+ if (lines == null)
+ return;
+
+ String message = msg.toString();
+ int count = 0;
+ String prefix = prefix(username, timestamp, level, category, thread)
+ .toString();
+ // String suffix = suffix(username, timestamp, level, category, thread);
+ for (String line : message.split("\n")) {
+ addLine(count == 0 ? prefix + line : line);
+ count++;
+ }
+
+ if (exception != null) {
+ for (String ste : exception) {
+ addLine(ste);
+ }
+ }
+
+ viewer.getTable().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (lines == null)
+ return;
+ viewer.setItemCount(lines.size());
+ // doesn't work with syncExec
+ scrollToLastLine();
+ }
+ });
+ }
+
+ protected StringBuffer prefix(String username, Long timestamp,
+ String level, String category, String thread) {
+ StringBuffer buf = new StringBuffer("");
+ buf.append(dateFormat.format(new Date(timestamp))).append(" ");
+ // buf.append(level).append(" ");
+ return buf;
+ }
+
+ /** Normalize string to the given size */
+ protected String norm(String str, Integer size) {
+ int length = str.length();
+ if (length == size)
+ return str;
+ else if (length > size)
+ return str.substring(0, size);
+ else {
+ char[] arr = new char[size - length];
+ Arrays.fill(arr, ' ');
+ return str + new String(arr);
+ }
+ }
+
+ // protected String suffix(String username, Long timestamp, String level,
+ // String category, String thread) {
+ // return "";
+ // }
+
+ /** Scroll to the last line */
+ protected synchronized void scrollToLastLine() {
+ // we try to show last line with two methods
+ // viewer.reveal(lines.peekLast());
+
+ Table table = viewer.getTable();
+ TableItem ti = table.getItem(table.getItemCount() - 1);
+ table.showItem(ti);
+ }
+
+ protected synchronized LogLine addLine(String line) {
+ // check for maximal size and purge if necessary
+ while (lines.size() >= maxLineBufferSize) {
+ for (int i = 0; i < maxLineBufferSize / 10; i++) {
+ lines.poll();
+ }
+ }
+
+ current++;
+ LogLine logLine = new LogLine(current, line);
+ lines.add(logLine);
+ return logLine;
+ }
+
+ private class LogLine {
+ private Long linenumber;
+ private String message;
+
+ public LogLine(Long linenumber, String message) {
+ this.linenumber = linenumber;
+ this.message = message;
+ }
+
+ @Override
+ public int hashCode() {
+ return linenumber.intValue();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof LogLine)
+ return ((LogLine) obj).linenumber.equals(linenumber);
+ else
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return message;
+ }
+
+ }
+}
\ 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.security.ui.views;
+
+import java.util.ArrayList;
+
+import org.argeo.ArgeoLogListener;
+import org.argeo.ArgeoLogger;
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * Display log lines with a virtual table. Register and unregisters a
+ * {@link ArgeoLogListener} via OSGi services.
+ */
+public class LogView extends ViewPart {
+ public static String ID = SecurityUiPlugin.PLUGIN_ID + ".logView";
+
+ private TableViewer viewer;
+
+ private LogContentProvider logContentProvider;
+ private ArgeoLogger argeoLogger;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ Font font = JFaceResources.getTextFont();
+ Table table = new Table(parent, SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
+ table.setFont(font);
+
+ viewer = new TableViewer(table);
+ viewer.setLabelProvider(new LabelProvider());
+ logContentProvider = new LogContentProvider(viewer);
+ viewer.setContentProvider(logContentProvider);
+ // viewer.setUseHashlookup(true);
+ viewer.setInput(new ArrayList<String>());
+
+ if (argeoLogger != null)
+ argeoLogger.register(logContentProvider, 1000);
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getTable().setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ if (argeoLogger != null)
+ argeoLogger.unregister(logContentProvider);
+ }
+
+ public void setArgeoLogger(ArgeoLogger argeoLogger) {
+ this.argeoLogger = argeoLogger;
+ }
+
+}
--- /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.security.ui.views;
+
+import java.util.TreeSet;
+
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.security.ui.SecurityUiPlugin;
+import org.argeo.security.ui.internal.CurrentUser;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+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.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.part.ViewPart;
+import org.springframework.security.Authentication;
+
+/** Information about the currently logged in user */
+public class UserProfile extends ViewPart {
+ public static String ID = SecurityUiPlugin.PLUGIN_ID + ".userProfile";
+
+ private TableViewer viewer;
+
+ @Override
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new GridLayout(2, false));
+
+ Authentication authentication = CurrentUser.getAuthentication();
+ EclipseUiUtils.createGridLL(parent, "Name", authentication
+ .getPrincipal().toString());
+ EclipseUiUtils.createGridLL(parent, "User ID",
+ CurrentUser.getUsername());
+
+ // roles table
+ Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+ table.setLinesVisible(false);
+ table.setHeaderVisible(false);
+ viewer = new TableViewer(table);
+ viewer.setContentProvider(new RolesContentProvider());
+ viewer.setLabelProvider(new LabelProvider());
+ getViewSite().setSelectionProvider(viewer);
+ viewer.setInput(getViewSite());
+ }
+
+ @Override
+ public void setFocus() {
+ viewer.getTable();
+ }
+
+ private class RolesContentProvider implements IStructuredContentProvider {
+ public Object[] getElements(Object inputElement) {
+ return new TreeSet<String>(CurrentUser.roles()).toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+}
--- /dev/null
+Spring-Context: META-INF/spring/*.xml;create-asynchronously:=false
+Import-Package: javax.naming.directory,\
+jdbm,\
+org.apache.directory.server.configuration,\
+org.apache.directory.server.core.authn,\
+org.apache.directory.server.core.authz,\
+org.apache.directory.server.core.collective,\
+org.apache.directory.server.core.configuration,\
+org.apache.directory.server.core.event,\
+org.apache.directory.server.core.exception,\
+org.apache.directory.server.core.normalization,\
+org.apache.directory.server.core.operational,\
+org.apache.directory.server.core.partition.impl.btree,\
+org.apache.directory.server.core.referral,\
+org.apache.directory.server.core.schema,\
+org.apache.directory.server.core.schema.bootstrap,\
+org.apache.directory.server.core.subtree,\
+org.apache.directory.server.jndi,\
+org.apache.directory.server.ldap.support.extended,\
+org.apache.directory.shared.asn1.codec,\
+org.argeo.server.ads,\
+org.springframework.beans.factory.config,\
+*
\ No newline at end of file
</parent>
<artifactId>org.argeo.server.ads.server</artifactId>
<name>Commons Server Default ADS LDAP Server</name>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <!-- Import-Package needs to be specified explicitly since BND doesn't
- deal with custom Spring-Context instructions -->
- <Spring-Context>META-INF/spring/*.xml;create-asynchronously:=false</Spring-Context>
- <Import-Package>
- *,
- javax.naming.directory,
- jdbm,
- org.apache.directory.server.configuration,
- org.apache.directory.server.core.authn,
- org.apache.directory.server.core.authz,
- org.apache.directory.server.core.collective,
- org.apache.directory.server.core.configuration,
- org.apache.directory.server.core.event,
- org.apache.directory.server.core.exception,
- org.apache.directory.server.core.normalization,
- org.apache.directory.server.core.operational,
- org.apache.directory.server.core.partition.impl.btree,
- org.apache.directory.server.core.referral,
- org.apache.directory.server.core.schema,
- org.apache.directory.server.core.schema.bootstrap,
- org.apache.directory.server.core.subtree,
- org.apache.directory.server.jndi,
- org.apache.directory.server.ldap.support.extended,
- org.apache.directory.shared.asn1.codec,
- org.argeo.server.ads,
- org.springframework.beans.factory.config
- </Import-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" output="target/classes" path="src/main/java"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="bin"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
+++ /dev/null
-#Sun Feb 21 11:17:20 CET 2010
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
-org.eclipse.jdt.core.compiler.compliance=1.5
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.5
+++ /dev/null
-#Mon Nov 23 13:34:22 CET 2009
-activeProfiles=
-eclipse.preferences.version=1
-fullBuildGoals=process-test-resources
-includeModules=false
-resolveWorkspaceProjects=true
-resourceFilterGoals=process-resources resources\:testResources
-skipCompilerPlugin=true
-version=1
additional.bundles = org.apache.directory.server.core
-source.. = src/main/java/
+source.. = src/
</parent>
<artifactId>org.argeo.server.ads</artifactId>
<name>Commons Server Apache Directory Server</name>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
-
- <configuration>
- <instructions>
- <Export-Package>
- org.argeo.server.ads.*
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
<dependencies>
<dependency>
<groupId>org.argeo.commons</groupId>
+++ /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.server.ads;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.naming.directory.InitialDirContext;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.directory.server.configuration.MutableServerStartupConfiguration;
-import org.apache.directory.server.core.configuration.ShutdownConfiguration;
-import org.apache.directory.server.jndi.ServerContextFactory;
-import org.argeo.ArgeoException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.Resource;
-import org.springframework.util.Assert;
-
-/** Wraps an Apache Directory Server instance. */
-@SuppressWarnings("restriction")
-public class AdsContainer implements InitializingBean, DisposableBean {
- private final static Log log = LogFactory.getLog(AdsContainer.class);
-
- private MutableServerStartupConfiguration configuration;
- private Properties environment = null;
- private File workingDirectory = new File(
- System.getProperty("java.io.tmpdir") + File.separator
- + "argeo-apacheDirectoryServer");
- private Boolean deleteWorkingDirOnExit = false;
-
- // LDIF
- private List<Resource> ldifs = new ArrayList<Resource>();
- private List<String> ignoredLdifAttributes = new ArrayList<String>();
- /** default is 'demo' */
- private String ldifPassword = "e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9";
- private String ldifPasswordAttribute = "userPassword";
- private File ldifDirectory;
-
- @SuppressWarnings("unchecked")
- public void afterPropertiesSet() throws Exception {
-
- log.info("Starting directory server with id '"
- + configuration.getInstanceId() + "' in directory "
- + workingDirectory.getAbsolutePath());
-
- if (deleteWorkingDirOnExit && workingDirectory.exists()) {
- log.warn("Found existing directory " + workingDirectory
- + " deleting it...");
- FileUtils.deleteDirectory(workingDirectory);
- }
- configuration.setWorkingDirectory(workingDirectory);
- workingDirectory.mkdirs();
-
- if (ldifDirectory != null)
- configuration.setLdifDirectory(ldifDirectory);
- else
- configuration.setLdifDirectory(new File(workingDirectory
- .getAbsolutePath() + File.separator + "ldif"));
-
- if (ignoredLdifAttributes.size() == 0) {
- ignoredLdifAttributes.add("entryUUID");
- ignoredLdifAttributes.add("structuralObjectClass");
- ignoredLdifAttributes.add("creatorsName");
- ignoredLdifAttributes.add("createTimestamp");
- ignoredLdifAttributes.add("entryCSN");
- ignoredLdifAttributes.add("modifiersName");
- ignoredLdifAttributes.add("modifyTimestamp");
- }
-
- // Process provided LDIF files
- if (ldifs.size() > 0)
- configuration.getLdifDirectory().mkdirs();
- for (Resource ldif : ldifs) {
- File targetFile = new File(configuration.getLdifDirectory()
- .getAbsolutePath()
- + File.separator
- + ldif.getFilename().replace(':', '_'));
- processLdif(ldif, targetFile);
- }
-
- Properties env = new Properties();
- env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
- ServerContextFactory.class.getName());
- Assert.notNull(environment);
- env.putAll(environment);
- env.putAll(configuration.toJndiEnvironment());
-
- try {
- new InitialDirContext(env);
- } catch (NamingException e) {
- throw new ArgeoException("Failed to start Apache Directory server",
- e);
- }
- }
-
- /**
- * Processes an LDIF resource, filtering out attributes that cannot be
- * imported in ADS and forcing a password.
- */
- protected void processLdif(Resource ldif, File targetFile) {
- BufferedReader reader = null;
- Writer writer = null;
- try {
- reader = new BufferedReader(new InputStreamReader(
- ldif.getInputStream()));
- writer = new FileWriter(targetFile);
- String line = null;
- lines: while ((line = reader.readLine()) != null) {
- // comment and empty lines
- if (line.trim().equals("") || line.startsWith("#")) {
- writer.write(line);
- writer.write('\n');
- continue lines;
- }
-
- String[] tokens = line.split(":");
- String attribute = null;
- if (tokens != null && tokens.length > 1) {
- attribute = tokens[0].trim();
- if (ignoredLdifAttributes.contains(attribute))
- continue lines;// ignore
-
- if (attribute.equals("bdb_db_open")) {
- log.warn("Ignored OpenLDAP output\n" + line);
- continue lines;
- }
-
- if (ldifPassword != null
- && attribute.equals(ldifPasswordAttribute)) {
- line = ldifPasswordAttribute + ":: " + ldifPassword;
- }
-
- writer.write(line);
- writer.write('\n');
- } else {
- log.warn("Ignored LDIF line\n" + line);
- }
- }
- if (log.isDebugEnabled())
- log.debug("Processed " + ldif + " to LDIF directory "
- + configuration.getLdifDirectory());
- } catch (IOException e) {
- throw new ArgeoException("Cannot process LDIF " + ldif, e);
- } finally {
- IOUtils.closeQuietly(reader);
- IOUtils.closeQuietly(writer);
- }
- }
-
- @SuppressWarnings("unchecked")
- public void destroy() throws Exception {
- ShutdownConfiguration shutdown = new ShutdownConfiguration(
- configuration.getInstanceId());
-
- Properties env = new Properties();
- env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
- ServerContextFactory.class.getName());
- Assert.notNull(environment);
- env.putAll(environment);
- env.putAll(shutdown.toJndiEnvironment());
-
- log.info("Shutting down directory server with id '"
- + configuration.getInstanceId() + "'");
-
- try {
- new InitialContext(env);
- } catch (NamingException e) {
- throw new ArgeoException("Failed to stop Apache Directory server",
- e);
- }
-
- if (workingDirectory.exists() && deleteWorkingDirOnExit) {
- if (log.isDebugEnabled())
- log.debug("Delete Apache DS working dir " + workingDirectory);
- FileUtils.deleteDirectory(workingDirectory);
- }
-
- }
-
- public void setConfiguration(MutableServerStartupConfiguration configuration) {
- this.configuration = configuration;
- }
-
- public void setWorkingDirectory(File workingDirectory) {
- this.workingDirectory = workingDirectory;
- }
-
- public void setEnvironment(Properties environment) {
- this.environment = environment;
- }
-
- public void setLdifs(List<Resource> ldifs) {
- this.ldifs = ldifs;
- }
-
- public void setLdifDirectory(File ldifDirectory) {
- this.ldifDirectory = ldifDirectory;
- }
-
- public void setDeleteWorkingDirOnExit(Boolean deleteWorkingDirOnExit) {
- this.deleteWorkingDirOnExit = deleteWorkingDirOnExit;
- }
-
- public void setIgnoredLdifAttributes(List<String> ignoredLdifAttributes) {
- this.ignoredLdifAttributes = ignoredLdifAttributes;
- }
-
- public void setLdifPassword(String ldifPassword) {
- this.ldifPassword = ldifPassword;
- }
-
- public void setLdifPasswordAttribute(String ldifPasswordAttribute) {
- this.ldifPasswordAttribute = ldifPasswordAttribute;
- }
-
-}
--- /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.server.ads;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.directory.server.configuration.MutableServerStartupConfiguration;
+import org.apache.directory.server.core.configuration.ShutdownConfiguration;
+import org.apache.directory.server.jndi.ServerContextFactory;
+import org.argeo.ArgeoException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+import org.springframework.util.Assert;
+
+/** Wraps an Apache Directory Server instance. */
+@SuppressWarnings("restriction")
+public class AdsContainer implements InitializingBean, DisposableBean {
+ private final static Log log = LogFactory.getLog(AdsContainer.class);
+
+ private MutableServerStartupConfiguration configuration;
+ private Properties environment = null;
+ private File workingDirectory = new File(
+ System.getProperty("java.io.tmpdir") + File.separator
+ + "argeo-apacheDirectoryServer");
+ private Boolean deleteWorkingDirOnExit = false;
+
+ // LDIF
+ private List<Resource> ldifs = new ArrayList<Resource>();
+ private List<String> ignoredLdifAttributes = new ArrayList<String>();
+ /** default is 'demo' */
+ private String ldifPassword = "e1NIQX1pZVNWNTVRYytlUU9hWURSU2hhL0Fqek5USkU9";
+ private String ldifPasswordAttribute = "userPassword";
+ private File ldifDirectory;
+
+ @SuppressWarnings("unchecked")
+ public void afterPropertiesSet() throws Exception {
+
+ log.info("Starting directory server with id '"
+ + configuration.getInstanceId() + "' in directory "
+ + workingDirectory.getAbsolutePath());
+
+ if (deleteWorkingDirOnExit && workingDirectory.exists()) {
+ log.warn("Found existing directory " + workingDirectory
+ + " deleting it...");
+ FileUtils.deleteDirectory(workingDirectory);
+ }
+ configuration.setWorkingDirectory(workingDirectory);
+ workingDirectory.mkdirs();
+
+ if (ldifDirectory != null)
+ configuration.setLdifDirectory(ldifDirectory);
+ else
+ configuration.setLdifDirectory(new File(workingDirectory
+ .getAbsolutePath() + File.separator + "ldif"));
+
+ if (ignoredLdifAttributes.size() == 0) {
+ ignoredLdifAttributes.add("entryUUID");
+ ignoredLdifAttributes.add("structuralObjectClass");
+ ignoredLdifAttributes.add("creatorsName");
+ ignoredLdifAttributes.add("createTimestamp");
+ ignoredLdifAttributes.add("entryCSN");
+ ignoredLdifAttributes.add("modifiersName");
+ ignoredLdifAttributes.add("modifyTimestamp");
+ }
+
+ // Process provided LDIF files
+ if (ldifs.size() > 0)
+ configuration.getLdifDirectory().mkdirs();
+ for (Resource ldif : ldifs) {
+ File targetFile = new File(configuration.getLdifDirectory()
+ .getAbsolutePath()
+ + File.separator
+ + ldif.getFilename().replace(':', '_'));
+ processLdif(ldif, targetFile);
+ }
+
+ Properties env = new Properties();
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ ServerContextFactory.class.getName());
+ Assert.notNull(environment);
+ env.putAll(environment);
+ env.putAll(configuration.toJndiEnvironment());
+
+ try {
+ new InitialDirContext(env);
+ } catch (NamingException e) {
+ throw new ArgeoException("Failed to start Apache Directory server",
+ e);
+ }
+ }
+
+ /**
+ * Processes an LDIF resource, filtering out attributes that cannot be
+ * imported in ADS and forcing a password.
+ */
+ protected void processLdif(Resource ldif, File targetFile) {
+ BufferedReader reader = null;
+ Writer writer = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(
+ ldif.getInputStream()));
+ writer = new FileWriter(targetFile);
+ String line = null;
+ lines: while ((line = reader.readLine()) != null) {
+ // comment and empty lines
+ if (line.trim().equals("") || line.startsWith("#")) {
+ writer.write(line);
+ writer.write('\n');
+ continue lines;
+ }
+
+ String[] tokens = line.split(":");
+ String attribute = null;
+ if (tokens != null && tokens.length > 1) {
+ attribute = tokens[0].trim();
+ if (ignoredLdifAttributes.contains(attribute))
+ continue lines;// ignore
+
+ if (attribute.equals("bdb_db_open")) {
+ log.warn("Ignored OpenLDAP output\n" + line);
+ continue lines;
+ }
+
+ if (ldifPassword != null
+ && attribute.equals(ldifPasswordAttribute)) {
+ line = ldifPasswordAttribute + ":: " + ldifPassword;
+ }
+
+ writer.write(line);
+ writer.write('\n');
+ } else {
+ log.warn("Ignored LDIF line\n" + line);
+ }
+ }
+ if (log.isDebugEnabled())
+ log.debug("Processed " + ldif + " to LDIF directory "
+ + configuration.getLdifDirectory());
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot process LDIF " + ldif, e);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ IOUtils.closeQuietly(writer);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void destroy() throws Exception {
+ ShutdownConfiguration shutdown = new ShutdownConfiguration(
+ configuration.getInstanceId());
+
+ Properties env = new Properties();
+ env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ ServerContextFactory.class.getName());
+ Assert.notNull(environment);
+ env.putAll(environment);
+ env.putAll(shutdown.toJndiEnvironment());
+
+ log.info("Shutting down directory server with id '"
+ + configuration.getInstanceId() + "'");
+
+ try {
+ new InitialContext(env);
+ } catch (NamingException e) {
+ throw new ArgeoException("Failed to stop Apache Directory server",
+ e);
+ }
+
+ if (workingDirectory.exists() && deleteWorkingDirOnExit) {
+ if (log.isDebugEnabled())
+ log.debug("Delete Apache DS working dir " + workingDirectory);
+ FileUtils.deleteDirectory(workingDirectory);
+ }
+
+ }
+
+ public void setConfiguration(MutableServerStartupConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public void setWorkingDirectory(File workingDirectory) {
+ this.workingDirectory = workingDirectory;
+ }
+
+ public void setEnvironment(Properties environment) {
+ this.environment = environment;
+ }
+
+ public void setLdifs(List<Resource> ldifs) {
+ this.ldifs = ldifs;
+ }
+
+ public void setLdifDirectory(File ldifDirectory) {
+ this.ldifDirectory = ldifDirectory;
+ }
+
+ public void setDeleteWorkingDirOnExit(Boolean deleteWorkingDirOnExit) {
+ this.deleteWorkingDirOnExit = deleteWorkingDirOnExit;
+ }
+
+ public void setIgnoredLdifAttributes(List<String> ignoredLdifAttributes) {
+ this.ignoredLdifAttributes = ignoredLdifAttributes;
+ }
+
+ public void setLdifPassword(String ldifPassword) {
+ this.ldifPassword = ldifPassword;
+ }
+
+ public void setLdifPasswordAttribute(String ldifPasswordAttribute) {
+ this.ldifPasswordAttribute = ldifPasswordAttribute;
+ }
+
+}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" output="target/classes" path="src/main/java"/>
- <classpathentry kind="src" output="target/classes" path="src/main/resources"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>>>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="output" path="bin"/>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" />
+ <classpathentry kind="output" path="bin" />
</classpath>
--- /dev/null
+Import-Package: javax.servlet,\
+org.apache.jackrabbit.webdav.server,\
+org.springframework.web.context,\
+org.osgi.framework;version="0.0.0",\
+org.xml.sax;version="0.0.0",\
+org.apache.jackrabbit.webdav.jcr,\
+org.springframework.beans,\
+*
org.h2,\
org.apache.lucene,\
org.springframework.context
-source.. = src/main/java/,\
- src/main/resources/
+source.. = src/
</parent>
<artifactId>org.argeo.server.jackrabbit</artifactId>
<name>Commons Server Jackrabbit</name>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- org.argeo.jackrabbit.*,
- </Export-Package>
- <Import-Package>
- javax.servlet,
- org.apache.jackrabbit.webdav.server,
- org.springframework.web.context,
- org.osgi.framework;version="0.0.0",
- org.xml.sax;version="0.0.0",
- org.apache.jackrabbit.webdav.jcr,
- org.springframework.beans,
- *
- </Import-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
<dependencies>
<dependency>
<groupId>org.argeo.commons</groupId>
+++ /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.jackrabbit;
-
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.security.JcrAuthorizations;
-
-/** Apply authorizations to a Jackrabbit repository. */
-public class JackrabbitAuthorizations extends JcrAuthorizations {
- private final static Log log = LogFactory
- .getLog(JackrabbitAuthorizations.class);
-
- private List<String> groupPrefixes = Arrays
- .asList(new String[] { "ROLE_" });// new ArrayList<String>();
-
- @Override
- protected Principal getOrCreatePrincipal(Session session,
- String principalName) throws RepositoryException {
- UserManager um = ((JackrabbitSession) session).getUserManager();
- synchronized (um) {
- Authorizable authorizable = um.getAuthorizable(principalName);
- if (authorizable == null) {
- groupPrefixes: for (String groupPrefix : groupPrefixes) {
- if (principalName.startsWith(groupPrefix)) {
- authorizable = um.createGroup(principalName);
- log.info("Created group " + principalName);
- break groupPrefixes;
- }
- }
- if (authorizable == null)
- throw new ArgeoException("Authorizable " + principalName
- + " not found");
- }
- return authorizable.getPrincipal();
- }
- }
-
- public void setGroupPrefixes(List<String> groupsToCreate) {
- this.groupPrefixes = groupsToCreate;
- }
-}
+++ /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.jackrabbit;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.UUID;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.JackrabbitRepository;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.MaintainedRepository;
-import org.springframework.core.io.Resource;
-import org.springframework.util.SystemPropertyUtils;
-import org.xml.sax.InputSource;
-
-/**
- * Wrapper around a Jackrabbit repository which allows to configure it in Spring
- * and expose it as a {@link Repository}.
- */
-public class JackrabbitContainer extends JackrabbitWrapper implements
- MaintainedRepository {
- private final static Log log = LogFactory.getLog(JackrabbitContainer.class);
-
- // local
- private Resource configuration;
- private Resource variables;
- private RepositoryConfig repositoryConfig;
- private File homeDirectory;
- private Boolean inMemory = false;
-
- /** Migrations to execute (if not already done) */
- private Set<JackrabbitDataModelMigration> dataModelMigrations = new HashSet<JackrabbitDataModelMigration>();
-
- /**
- * Empty constructor, {@link #init()} should be called after properties have
- * been set
- */
- public JackrabbitContainer() {
- }
-
- public void init() {
- long begin = System.currentTimeMillis();
-
- if (getRepository() != null)
- throw new ArgeoException(
- "Cannot be used to wrap another repository");
- Repository repository = createJackrabbitRepository();
- super.setRepository(repository);
-
- // migrate if needed
- migrate();
-
- // apply new CND files after migration
- prepareDataModel();
-
- double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
- if (log.isDebugEnabled())
- log.debug("Initialized JCR repository wrapper in " + duration
- + " s");
- }
-
- /** Actually creates the new repository. */
- protected Repository createJackrabbitRepository() {
- long begin = System.currentTimeMillis();
- InputStream configurationIn = null;
- Repository repository;
- try {
- // temporary
- if (inMemory && getHomeDirectory().exists()) {
- FileUtils.deleteDirectory(getHomeDirectory());
- log.warn("Deleted Jackrabbit home directory "
- + getHomeDirectory());
- }
-
- // process configuration file
- Properties vars = getConfigurationProperties();
- configurationIn = readConfiguration();
- vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
- getHomeDirectory().getCanonicalPath());
- repositoryConfig = RepositoryConfig.create(new InputSource(
- configurationIn), vars);
-
- //
- // Actual repository creation
- //
- repository = RepositoryImpl.create(repositoryConfig);
-
- double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
- if (log.isTraceEnabled())
- log.trace("Created Jackrabbit repository in " + duration
- + " s, home: " + getHomeDirectory());
-
- return repository;
- } catch (Exception e) {
- throw new ArgeoException("Cannot create Jackrabbit repository "
- + getHomeDirectory(), e);
- } finally {
- IOUtils.closeQuietly(configurationIn);
- }
- }
-
- /** Lazy init. */
- protected File getHomeDirectory() {
- try {
- if (homeDirectory == null) {
- if (inMemory) {
- homeDirectory = new File(
- System.getProperty("java.io.tmpdir")
- + File.separator
- + System.getProperty("user.name")
- + File.separator + "jackrabbit-"
- + UUID.randomUUID());
- homeDirectory.mkdirs();
- // will it work if directory is not empty??
- homeDirectory.deleteOnExit();
- }
- }
-
- return homeDirectory.getCanonicalFile();
- } catch (IOException e) {
- throw new ArgeoException("Cannot get canonical file for "
- + homeDirectory, e);
- }
- }
-
- /** Executes migrations, if needed. */
- protected void migrate() {
- // No migration to perform
- if (dataModelMigrations.size() == 0)
- return;
-
- Boolean restartAndClearCaches = false;
-
- // migrate data
- Session session = null;
- try {
- session = login();
- for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
- dataModelMigrations)) {
- if (dataModelMigration.migrate(session)) {
- restartAndClearCaches = true;
- }
- }
- } catch (ArgeoException e) {
- throw e;
- } catch (Exception e) {
- throw new ArgeoException("Cannot migrate", e);
- } finally {
- JcrUtils.logoutQuietly(session);
- }
-
- // restart repository
- if (restartAndClearCaches) {
- Repository repository = getRepository();
- if (repository instanceof RepositoryImpl) {
- JackrabbitDataModelMigration
- .clearRepositoryCaches(((RepositoryImpl) repository)
- .getConfig());
- }
- ((JackrabbitRepository) repository).shutdown();
- createJackrabbitRepository();
- }
-
- // set data model version
- try {
- session = login();
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot login to migrated repository", e);
- }
-
- for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
- dataModelMigrations)) {
- try {
- if (session.itemExists(dataModelMigration
- .getDataModelNodePath())) {
- Node dataModelNode = session.getNode(dataModelMigration
- .getDataModelNodePath());
- dataModelNode.setProperty(
- ArgeoNames.ARGEO_DATA_MODEL_VERSION,
- dataModelMigration.getTargetVersion());
- session.save();
- }
- } catch (Exception e) {
- log.error("Cannot set model version", e);
- }
- }
- JcrUtils.logoutQuietly(session);
-
- }
-
- /** Shutdown the repository */
- public void destroy() throws Exception {
- Repository repository = getRepository();
- if (repository != null && repository instanceof RepositoryImpl) {
- long begin = System.currentTimeMillis();
- ((RepositoryImpl) repository).shutdown();
- if (inMemory)
- if (getHomeDirectory().exists()) {
- FileUtils.deleteDirectory(getHomeDirectory());
- if (log.isDebugEnabled())
- log.debug("Deleted Jackrabbit home directory "
- + getHomeDirectory());
- }
- double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
- log.info("Destroyed Jackrabbit repository in " + duration
- + " s, home: " + getHomeDirectory());
- }
- repository = null;
- }
-
- public void dispose() {
- throw new IllegalArgumentException(
- "Call destroy() method instead of dispose()");
- }
-
- /*
- * UTILITIES
- */
- /**
- * Reads the configuration which will initialize a {@link RepositoryConfig}.
- */
- protected InputStream readConfiguration() {
- try {
- return configuration != null ? configuration.getInputStream()
- : null;
- } catch (IOException e) {
- throw new ArgeoException("Cannot read Jackrabbit configuration "
- + configuration, e);
- }
- }
-
- /**
- * Reads the variables which will initialize a {@link Properties}. Returns
- * null by default, to be overridden.
- *
- * @return a new stream or null if no variables available
- */
- protected InputStream readVariables() {
- try {
- return variables != null ? variables.getInputStream() : null;
- } catch (IOException e) {
- throw new ArgeoException("Cannot read Jackrabbit variables "
- + variables, e);
- }
- }
-
- /**
- * Resolves ${} placeholders in the provided string. Based on system
- * properties if no map is provided.
- */
- protected String resolvePlaceholders(String string,
- Map<String, String> variables) {
- return SystemPropertyUtils.resolvePlaceholders(string);
- }
-
- /** Generates the properties to use in the configuration. */
- protected Properties getConfigurationProperties() {
- InputStream propsIn = null;
- Properties vars;
- try {
- vars = new Properties();
- propsIn = readVariables();
- if (propsIn != null) {
- vars.load(propsIn);
- }
- // resolve system properties
- for (Object key : vars.keySet()) {
- // TODO: implement a smarter mechanism to resolve nested ${}
- String newValue = resolvePlaceholders(
- vars.getProperty(key.toString()), null);
- vars.put(key, newValue);
- }
- // override with system properties
- vars.putAll(System.getProperties());
-
- if (log.isTraceEnabled()) {
- log.trace("Jackrabbit config variables:");
- for (Object key : new TreeSet<Object>(vars.keySet()))
- log.trace(key + "=" + vars.getProperty(key.toString()));
- }
-
- } catch (IOException e) {
- throw new ArgeoException("Cannot read configuration properties", e);
- } finally {
- IOUtils.closeQuietly(propsIn);
- }
- return vars;
- }
-
- /*
- * FIELDS ACCESS
- */
-
- public void setHomeDirectory(File homeDirectory) {
- this.homeDirectory = homeDirectory;
- }
-
- public void setInMemory(Boolean inMemory) {
- this.inMemory = inMemory;
- }
-
- public void setRepository(Repository repository) {
- throw new ArgeoException("Cannot be used to wrap another repository");
- }
-
- public void setDataModelMigrations(
- Set<JackrabbitDataModelMigration> dataModelMigrations) {
- this.dataModelMigrations = dataModelMigrations;
- }
-
- public void setVariables(Resource variables) {
- this.variables = variables;
- }
-
- public void setConfiguration(Resource configuration) {
- this.configuration = configuration;
- }
-
-}
+++ /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.jackrabbit;
-
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-import javax.jcr.Node;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrCallback;
-import org.argeo.jcr.JcrUtils;
-import org.springframework.core.io.Resource;
-
-/** Migrate the data in a Jackrabbit repository. */
-public class JackrabbitDataModelMigration implements
- Comparable<JackrabbitDataModelMigration> {
- private final static Log log = LogFactory
- .getLog(JackrabbitDataModelMigration.class);
-
- private String dataModelNodePath;
- private String targetVersion;
- private Resource migrationCnd;
- private JcrCallback dataModification;
-
- /**
- * Expects an already started repository with the old data model to migrate.
- * Expects to be run with admin rights (Repository.login() will be used).
- *
- * @return true if a migration was performed and the repository needs to be
- * restarted and its caches cleared.
- */
- public Boolean migrate(Session session) {
- long begin = System.currentTimeMillis();
- Reader reader = null;
- try {
- // check if already migrated
- if (!session.itemExists(dataModelNodePath)) {
- log.warn("Node " + dataModelNodePath
- + " does not exist: nothing to migrate.");
- return false;
- }
- Node dataModelNode = session.getNode(dataModelNodePath);
- if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
- String currentVersion = dataModelNode.getProperty(
- ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
- if (compareVersions(currentVersion, targetVersion) >= 0) {
- log.info("Data model at version " + currentVersion
- + ", no need to migrate.");
- return false;
- }
- }
-
- // apply transitional CND
- if (migrationCnd != null) {
- reader = new InputStreamReader(migrationCnd.getInputStream());
- CndImporter.registerNodeTypes(reader, session, true);
- session.save();
- log.info("Registered migration node types from " + migrationCnd);
- }
-
- // modify data
- dataModification.execute(session);
-
- // apply changes
- session.save();
-
- long duration = System.currentTimeMillis() - begin;
- log.info("Migration of data model " + dataModelNodePath + " to "
- + targetVersion + " performed in " + duration + "ms");
- return true;
- } catch (Exception e) {
- JcrUtils.discardQuietly(session);
- throw new ArgeoException("Migration of data model "
- + dataModelNodePath + " to " + targetVersion + " failed.",
- e);
- } finally {
- JcrUtils.logoutQuietly(session);
- IOUtils.closeQuietly(reader);
- }
- }
-
- protected static int compareVersions(String version1, String version2) {
- // TODO do a proper version analysis and comparison
- return version1.compareTo(version2);
- }
-
- /** To be called on a stopped repository. */
- public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) {
- try {
- String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml";
- repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath);
- if (log.isDebugEnabled())
- log.debug("Cleared " + customeNodeTypesPath);
- } catch (Exception e) {
- throw new ArgeoException("Cannot clear caches", e);
- }
-
- // File customNodeTypes = new File(home.getPath()
- // + "/repository/nodetypes/custom_nodetypes.xml");
- // if (customNodeTypes.exists()) {
- // customNodeTypes.delete();
- // if (log.isDebugEnabled())
- // log.debug("Cleared " + customNodeTypes);
- // } else {
- // log.warn("File " + customNodeTypes + " not found.");
- // }
- }
-
- /*
- * FOR USE IN (SORTED) SETS
- */
-
- public int compareTo(JackrabbitDataModelMigration dataModelMigration) {
- // TODO make ordering smarter
- if (dataModelNodePath.equals(dataModelMigration.dataModelNodePath))
- return compareVersions(targetVersion,
- dataModelMigration.targetVersion);
- else
- return dataModelNodePath
- .compareTo(dataModelMigration.dataModelNodePath);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof JackrabbitDataModelMigration))
- return false;
- JackrabbitDataModelMigration dataModelMigration = (JackrabbitDataModelMigration) obj;
- return dataModelNodePath.equals(dataModelMigration.dataModelNodePath)
- && targetVersion.equals(dataModelMigration.targetVersion);
- }
-
- @Override
- public int hashCode() {
- return targetVersion.hashCode();
- }
-
- public void setDataModelNodePath(String dataModelNodePath) {
- this.dataModelNodePath = dataModelNodePath;
- }
-
- public void setTargetVersion(String targetVersion) {
- this.targetVersion = targetVersion;
- }
-
- public void setMigrationCnd(Resource migrationCnd) {
- this.migrationCnd = migrationCnd;
- }
-
- public void setDataModification(JcrCallback dataModification) {
- this.dataModification = dataModification;
- }
-
- public String getDataModelNodePath() {
- return dataModelNodePath;
- }
-
- public String getTargetVersion() {
- return targetVersion;
- }
-
-}
+++ /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.jackrabbit;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.commons.JcrUtils;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
-import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.DefaultRepositoryFactory;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-import org.xml.sax.InputSource;
-
-/**
- * Repository factory which can create new repositories and access remote
- * Jackrabbit repositories
- */
-public class JackrabbitRepositoryFactory extends DefaultRepositoryFactory
- implements RepositoryFactory, ArgeoJcrConstants {
-
- private final static Log log = LogFactory
- .getLog(JackrabbitRepositoryFactory.class);
-
- private Resource fileRepositoryConfiguration = new ClassPathResource(
- "/org/argeo/jackrabbit/repository-h2.xml");
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Repository getRepository(Map parameters) throws RepositoryException {
- // check if can be found by alias
- Repository repository = super.getRepository(parameters);
- if (repository != null)
- return repository;
-
- // check if remote
- String uri = null;
- if (parameters.containsKey(JCR_REPOSITORY_URI))
- uri = parameters.get(JCR_REPOSITORY_URI).toString();
- else if (parameters.containsKey(JcrUtils.REPOSITORY_URI))
- uri = parameters.get(JcrUtils.REPOSITORY_URI).toString();
-
- if (uri != null) {
- if (uri.startsWith("http"))// http, https
- repository = createRemoteRepository(uri);
- else if (uri.startsWith("file"))// http, https
- repository = createFileRepository(uri, parameters);
- else if (uri.startsWith("vm")) {
- log.warn("URI "
- + uri
- + " should have been managed by generic JCR repository factory");
- repository = getRepositoryByAlias(getAliasFromURI(uri));
- }
- }
-
- // publish under alias
- if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) {
- Properties properties = new Properties();
- properties.putAll(parameters);
- String alias = parameters.get(JCR_REPOSITORY_ALIAS).toString();
- publish(alias, repository, properties);
- log.info("Registered JCR repository under alias '" + alias
- + "' with properties " + properties);
- }
-
- return repository;
- }
-
- protected Repository createRemoteRepository(String uri)
- throws RepositoryException {
- Map<String, String> params = new HashMap<String, String>();
- params.put(JcrUtils.REPOSITORY_URI, uri);
- Repository repository = new Jcr2davRepositoryFactory()
- .getRepository(params);
- if (repository == null)
- throw new ArgeoException("Remote Davex repository " + uri
- + " not found");
- log.info("Initialized remote Jackrabbit repository from uri " + uri);
- return repository;
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected Repository createFileRepository(final String uri, Map parameters)
- throws RepositoryException {
- InputStream configurationIn = null;
- try {
- Properties vars = new Properties();
- vars.putAll(parameters);
- String dirPath = uri.substring("file:".length());
- File homeDir = new File(dirPath);
- if (homeDir.exists() && !homeDir.isDirectory())
- throw new ArgeoException("Repository home " + dirPath
- + " is not a directory");
- if (!homeDir.exists())
- homeDir.mkdirs();
- configurationIn = fileRepositoryConfiguration.getInputStream();
- vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
- homeDir.getCanonicalPath());
- RepositoryConfig repositoryConfig = RepositoryConfig.create(
- new InputSource(configurationIn), vars);
-
- // TransientRepository repository = new
- // TransientRepository(repositoryConfig);
- final RepositoryImpl repository = RepositoryImpl
- .create(repositoryConfig);
- Session session = repository.login();
- // FIXME make it generic
- org.argeo.jcr.JcrUtils.addPrivilege(session, "/", "ROLE_ADMIN",
- "jcr:all");
- org.argeo.jcr.JcrUtils.logoutQuietly(session);
- Runtime.getRuntime().addShutdownHook(
- new Thread("Clean JCR repository " + uri) {
- public void run() {
- repository.shutdown();
- log.info("Destroyed repository " + uri);
- }
- });
- log.info("Initialized file Jackrabbit repository from uri " + uri);
- return repository;
- } catch (Exception e) {
- throw new ArgeoException("Cannot create repository " + uri, e);
- } finally {
- IOUtils.closeQuietly(configurationIn);
- }
- }
-
- /**
- * Called after the repository has been initialised. Does nothing by
- * default.
- */
- @SuppressWarnings("rawtypes")
- protected void postInitialization(Repository repository, Map parameters) {
-
- }
-
- public void setFileRepositoryConfiguration(
- Resource fileRepositoryConfiguration) {
- this.fileRepositoryConfiguration = fileRepositoryConfiguration;
- }
-
-}
+++ /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.jackrabbit;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.util.ArrayList;
-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.Session;
-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.apache.jackrabbit.commons.NamespaceHelper;
-import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrRepositoryWrapper;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.util.security.DigestUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-
-/**
- * Wrapper around a Jackrabbit repository which allows to simplify configuration
- * and intercept some actions. It exposes itself as a {@link Repository}.
- */
-public class JackrabbitWrapper extends JcrRepositoryWrapper implements
- ResourceLoaderAware {
- private final static Log log = LogFactory.getLog(JackrabbitWrapper.class);
- private final static String DIGEST_ALGORITHM = "MD5";
-
- // local
- private ResourceLoader resourceLoader;
-
- // data model
- /** Node type definitions in CND format */
- private List<String> cndFiles = new ArrayList<String>();
- /**
- * Always import CNDs. Useful during development of new data models. In
- * production, explicit migration processes should be used.
- */
- private Boolean forceCndImport = true;
-
- /** Namespaces to register: key is prefix, value namespace */
- private Map<String, String> namespaces = new HashMap<String, String>();
-
- private BundleContext bundleContext;
-
- /**
- * Explicitly set admin credentials used in initialization. Useful for
- * testing, in real applications authentication is rather dealt with
- * externally
- */
- private Credentials adminCredentials = null;
-
- /**
- * Empty constructor, {@link #init()} should be called after properties have
- * been set
- */
- public JackrabbitWrapper() {
- }
-
- @Override
- public void init() {
- prepareDataModel();
- }
-
- /*
- * DATA MODEL
- */
-
- /**
- * Import declared node type definitions and register namespaces. Tries to
- * update the node definitions if they have changed. In case of failures an
- * error will be logged but no exception will be thrown.
- */
- protected void prepareDataModel() {
- if ((cndFiles == null || cndFiles.size() == 0)
- && (namespaces == null || namespaces.size() == 0))
- return;
-
- Session session = null;
- try {
- session = login(adminCredentials);
- // register namespaces
- if (namespaces.size() > 0) {
- NamespaceHelper namespaceHelper = new NamespaceHelper(session);
- namespaceHelper.registerNamespaces(namespaces);
- }
-
- // load CND files from classpath or as URL
- for (String resUrl : cndFiles) {
- processCndFile(session, resUrl);
- }
- } catch (Exception e) {
- JcrUtils.discardQuietly(session);
- throw new ArgeoException("Cannot import node type definitions "
- + cndFiles, e);
- } finally {
- JcrUtils.logoutQuietly(session);
- }
-
- }
-
- protected void processCndFile(Session session, String resUrl) {
- Reader reader = null;
- try {
- // check existing data model nodes
- new NamespaceHelper(session).registerNamespace(ArgeoNames.ARGEO,
- ArgeoNames.ARGEO_NAMESPACE);
- if (!session.itemExists(ArgeoJcrConstants.DATA_MODELS_BASE_PATH))
- JcrUtils.mkdirs(session,
- ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
- Node dataModels = session
- .getNode(ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
- NodeIterator it = dataModels.getNodes();
- Node dataModel = null;
- while (it.hasNext()) {
- Node node = it.nextNode();
- if (node.getProperty(ArgeoNames.ARGEO_URI).getString()
- .equals(resUrl)) {
- dataModel = node;
- break;
- }
- }
-
- byte[] cndContent = readCndContent(resUrl);
- String newDigest = DigestUtils.digest(DIGEST_ALGORITHM, cndContent);
- Bundle bundle = findDataModelBundle(resUrl);
-
- String currentVersion = null;
- if (dataModel != null) {
- currentVersion = dataModel.getProperty(
- ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
- if (dataModel.hasNode(Node.JCR_CONTENT)) {
- String oldDigest = JcrUtils.checksumFile(dataModel,
- DIGEST_ALGORITHM);
- if (oldDigest.equals(newDigest)) {
- if (log.isDebugEnabled())
- log.debug("Data model " + resUrl
- + " hasn't changed, keeping version "
- + currentVersion);
- return;
- }
- }
- }
-
- if (dataModel != null && !forceCndImport) {
- log.info("Data model "
- + resUrl
- + " has changed since version "
- + currentVersion
- + (bundle != null ? ": version " + bundle.getVersion()
- + ", bundle " + bundle.getSymbolicName() : ""));
- return;
- }
-
- reader = new InputStreamReader(new ByteArrayInputStream(cndContent));
- // actually imports the CND
- try {
- CndImporter.registerNodeTypes(reader, session, true);
- } catch (Exception e) {
- log.error("Cannot import data model " + resUrl, e);
- return;
- }
-
- if (dataModel != null && !dataModel.isNodeType(NodeType.NT_FILE)) {
- dataModel.remove();
- dataModel = null;
- }
-
- // FIXME: what if argeo.cnd would not be the first called on
- // a new repo? argeo:dataModel would not be found
- String fileName = FilenameUtils.getName(resUrl);
- if (dataModel == null) {
- dataModel = dataModels.addNode(fileName, NodeType.NT_FILE);
- dataModel.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
- dataModel.addMixin(ArgeoTypes.ARGEO_DATA_MODEL);
- dataModel.setProperty(ArgeoNames.ARGEO_URI, resUrl);
- } else {
- session.getWorkspace().getVersionManager()
- .checkout(dataModel.getPath());
- }
- if (bundle != null)
- dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
- bundle.getVersion().toString());
- else
- dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
- "0.0.0");
- JcrUtils.copyBytesAsFile(dataModel.getParent(), fileName,
- cndContent);
- JcrUtils.updateLastModified(dataModel);
- session.save();
- session.getWorkspace().getVersionManager()
- .checkin(dataModel.getPath());
-
- if (currentVersion == null)
- log.info("Data model "
- + resUrl
- + (bundle != null ? ", version " + bundle.getVersion()
- + ", bundle " + bundle.getSymbolicName() : ""));
- else
- log.info("Data model "
- + resUrl
- + " updated from version "
- + currentVersion
- + (bundle != null ? ", version " + bundle.getVersion()
- + ", bundle " + bundle.getSymbolicName() : ""));
- } catch (Exception e) {
- throw new ArgeoException("Cannot process data model " + resUrl, e);
- } finally {
- IOUtils.closeQuietly(reader);
- }
- }
-
- protected byte[] readCndContent(String resUrl) {
- InputStream in = null;
- try {
- boolean classpath;
- // normalize URL
- if (bundleContext != null && resUrl.startsWith("classpath:")) {
- resUrl = resUrl.substring("classpath:".length());
- classpath = true;
- } else if (resUrl.indexOf(':') < 0) {
- if (!resUrl.startsWith("/")) {
- resUrl = "/" + resUrl;
- log.warn("Classpath should start with '/'");
- }
- classpath = true;
- } else {
- classpath = false;
- }
-
- URL url = null;
- if (classpath) {
- if (bundleContext != null) {
- Bundle currentBundle = bundleContext.getBundle();
- url = currentBundle.getResource(resUrl);
- } else {
- resUrl = "classpath:" + resUrl;
- url = null;
- }
- } else if (!resUrl.startsWith("classpath:")) {
- url = new URL(resUrl);
- }
-
- if (url != null) {
- in = url.openStream();
- } else if (resourceLoader != null) {
- Resource res = resourceLoader.getResource(resUrl);
- in = res.getInputStream();
- url = res.getURL();
- } else {
- throw new ArgeoException("No " + resUrl + " in the classpath,"
- + " make sure the containing" + " package is visible.");
- }
-
- return IOUtils.toByteArray(in);
- } catch (Exception e) {
- throw new ArgeoException("Cannot read CND from " + resUrl, e);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- /*
- * REPOSITORY INTERCEPTOR
- */
-
- /*
- * UTILITIES
- */
- /** Find which OSGi bundle provided the data model resource */
- protected Bundle findDataModelBundle(String resUrl) {
- if (bundleContext == null)
- return null;
-
- if (resUrl.startsWith("/"))
- resUrl = resUrl.substring(1);
- String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/',
- '.');
- ServiceReference paSr = bundleContext
- .getServiceReference(PackageAdmin.class.getName());
- PackageAdmin packageAdmin = (PackageAdmin) bundleContext
- .getService(paSr);
-
- // find exported package
- ExportedPackage exportedPackage = null;
- ExportedPackage[] exportedPackages = packageAdmin
- .getExportedPackages(pkg);
- if (exportedPackages == null)
- throw new ArgeoException("No exported package found for " + pkg);
- for (ExportedPackage ep : exportedPackages) {
- for (Bundle b : ep.getImportingBundles()) {
- if (b.getBundleId() == bundleContext.getBundle().getBundleId()) {
- exportedPackage = ep;
- break;
- }
- }
- }
-
- Bundle exportingBundle = null;
- if (exportedPackage != null) {
- exportingBundle = exportedPackage.getExportingBundle();
- } else {
- // assume this is in the same bundle
- exportingBundle = bundleContext.getBundle();
-// throw new ArgeoException("No OSGi exporting package found for "
-// + resUrl);
- }
- return exportingBundle;
- }
-
- /*
- * FIELDS ACCESS
- */
- public void setNamespaces(Map<String, String> namespaces) {
- this.namespaces = namespaces;
- }
-
- public void setCndFiles(List<String> cndFiles) {
- this.cndFiles = cndFiles;
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
- public void setForceCndImport(Boolean forceCndUpdate) {
- this.forceCndImport = forceCndUpdate;
- }
-
- public void setResourceLoader(ResourceLoader resourceLoader) {
- this.resourceLoader = resourceLoader;
- }
-
- public void setAdminCredentials(Credentials adminCredentials) {
- this.adminCredentials = adminCredentials;
- }
-
-}
+++ /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.jackrabbit;
-
-import java.util.Hashtable;
-import java.util.Properties;
-
-import javax.jcr.Repository;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * OSGi-aware Jackrabbit repository factory which can retrieve/publish
- * {@link Repository} as OSGi services.
- */
-public class OsgiJackrabbitRepositoryFactory extends
- JackrabbitRepositoryFactory {
- private BundleContext bundleContext;
-
- protected void publish(String alias, Repository repository,
- Properties properties) {
- if (bundleContext != null) {
- // do not modify reference
- Hashtable<String, String> props = new Hashtable<String, String>();
- props.putAll(props);
- props.put(JCR_REPOSITORY_ALIAS, alias);
- bundleContext.registerService(Repository.class.getName(),
- repository, props);
- }
- }
-
- public void setBundleContext(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.jcr.mvc.MultipleRepositoryHandlerMapping;
-
-/** Base class for Jackrabbit handler mappings. */
-public abstract class AbstractJackrabbitHandlerMapping extends
- MultipleRepositoryHandlerMapping {
- private SessionProvider sessionProvider;
-
- protected SessionProvider getSessionProvider() {
- return sessionProvider;
- }
-
- public void setSessionProvider(SessionProvider sessionProvider) {
- this.sessionProvider = sessionProvider;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.springframework.web.servlet.DispatcherServlet;
-
-/**
- * Overrides Spring {@link DispatcherServlet}, see
- * http://forum.springsource.org/showthread.php?t=53472.
- */
-public class ExtendedDispatcherServlet extends DispatcherServlet {
- private static final long serialVersionUID = -5584673209855752009L;
-
- private final static Log log = LogFactory
- .getLog(ExtendedDispatcherServlet.class);
-
- protected void service(HttpServletRequest request,
- HttpServletResponse response) throws ServletException,
- java.io.IOException {
- try {
- if (log.isTraceEnabled()) {
- log.trace("SessionID = " + request.getSession().getId());
- log.trace(" ContextPath = " + request.getContextPath());
- log.trace(" ServletPath = " + request.getServletPath());
- log.trace(" PathInfo = " + request.getPathInfo());
- log.trace(" Method = " + request.getMethod());
- log.trace(" User-Agent = " + request.getHeader("User-Agent"));
- }
- doService(request, response);
- } catch (Exception e) {
- throw new ArgeoException("Cannot process request", e);
- }
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.io.IOException;
-
-import org.apache.jackrabbit.server.io.ExportContext;
-import org.apache.jackrabbit.server.io.IOHandler;
-import org.apache.jackrabbit.server.io.IOManager;
-import org.apache.jackrabbit.server.io.ImportContext;
-import org.apache.jackrabbit.webdav.DavResource;
-import org.argeo.ArgeoException;
-
-/** Wraps an IOHandler so that it can be injected a posteriori */
-public class IOHandlerWrapper implements IOHandler {
- private IOManager ioManager = null;
- private IOHandler ioHandler = null;
-
- public void setIOHandler(IOHandler ioHandler) {
- if ((this.ioHandler != null) && (ioHandler != null))
- throw new ArgeoException(
- "There is already an IO Handler registered");
- this.ioHandler = ioHandler;
- if (ioManager != null && this.ioHandler != null)
- ioHandler.setIOManager(ioManager);
- }
-
- public IOHandler getIOHandler() {
- return ioHandler;
- }
-
- public IOManager getIOManager() {
- return ioManager;
- }
-
- public void setIOManager(IOManager ioManager) {
- this.ioManager = ioManager;
- if (ioHandler != null)
- ioHandler.setIOManager(ioManager);
- }
-
- public String getName() {
- if (ioHandler != null)
- return ioHandler.getName();
- else
- return "Empty IOHandler Wrapper";
- }
-
- public boolean canImport(ImportContext context, boolean isCollection) {
- if (ioHandler != null)
- return ioHandler.canImport(context, isCollection);
- return false;
- }
-
- public boolean canImport(ImportContext context, DavResource resource) {
- if (ioHandler != null)
- return ioHandler.canImport(context, resource);
- return false;
- }
-
- public boolean importContent(ImportContext context, boolean isCollection)
- throws IOException {
- if (ioHandler != null)
- ioHandler.importContent(context, isCollection);
- return false;
- }
-
- public boolean importContent(ImportContext context, DavResource resource)
- throws IOException {
- if (ioHandler != null)
- ioHandler.importContent(context, resource);
- return false;
- }
-
- public boolean canExport(ExportContext context, boolean isCollection) {
- if (ioHandler != null)
- ioHandler.canExport(context, isCollection);
- return false;
- }
-
- public boolean canExport(ExportContext context, DavResource resource) {
- if (ioHandler != null)
- ioHandler.canExport(context, resource);
- return false;
- }
-
- public boolean exportContent(ExportContext context, boolean isCollection)
- throws IOException {
- if (ioHandler != null)
- ioHandler.exportContent(context, isCollection);
- return false;
- }
-
- public boolean exportContent(ExportContext context, DavResource resource)
- throws IOException {
- if (ioHandler != null)
- ioHandler.exportContent(context, resource);
- return false;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.jackrabbit.server.io.ExportContext;
-import org.apache.jackrabbit.server.io.IOHandler;
-import org.apache.jackrabbit.server.io.IOManager;
-import org.apache.jackrabbit.server.io.ImportContext;
-import org.apache.jackrabbit.webdav.DavResource;
-import org.apache.tika.detect.Detector;
-
-/** {@link IOManager} that can easily be configured as a bean. */
-public class IOManagerBean implements IOManager {
- private Detector detector = null;
- private List<IOHandler> ioHandlers = new ArrayList<IOHandler>();
-
- public boolean importContent(ImportContext context, boolean isCollection)
- throws IOException {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean importContent(ImportContext context, DavResource resource)
- throws IOException {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean exportContent(ExportContext context, boolean isCollection)
- throws IOException {
- // TODO Auto-generated method stub
- return false;
- }
-
- public boolean exportContent(ExportContext context, DavResource resource)
- throws IOException {
- // TODO Auto-generated method stub
- return false;
- }
-
- public synchronized void addIOHandler(IOHandler ioHandler) {
- ioHandlers.add(ioHandler);
- }
-
- public synchronized IOHandler[] getIOHandlers() {
- return ioHandlers.toArray(new IOHandler[ioHandlers.size()]);
- }
-
- public Detector getDetector() {
- return detector;
- }
-
- public void setDetector(Detector detector) {
- this.detector = detector;
- }
-
- public synchronized List<IOHandler> getIoHandlers() {
- return ioHandlers;
- }
-
- public synchronized void setIoHandlers(List<IOHandler> ioHandlers) {
- this.ioHandlers = ioHandlers;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.util.Properties;
-
-import javax.jcr.Repository;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-
-public class JcrRemotingHandlerMapping extends AbstractJackrabbitHandlerMapping {
-
- protected HttpServlet createServlet(Repository repository, String pathPrefix)
- throws ServletException {
- JcrRemotingServlet servlet = new JcrRemotingServlet(repository,
- getSessionProvider());
- Properties initParameters = new Properties();
- initParameters.setProperty(
- JcrRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, pathPrefix);
- servlet.init(new DelegatingServletConfig(pathPrefix.replace('/', '_'),
- initParameters));
- return servlet;
- }
-}
+++ /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.jackrabbit.remote;
-
-import javax.jcr.Repository;
-
-import org.apache.jackrabbit.server.SessionProvider;
-
-public class JcrRemotingServlet extends
- org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet {
-
- private static final long serialVersionUID = 3131835511468341309L;
-
- private final Repository repository;
- private final SessionProvider sessionProvider;
-
- public JcrRemotingServlet(Repository repository,
- SessionProvider sessionProvider) {
- this.repository = repository;
- this.sessionProvider = sessionProvider;
- }
-
- @Override
- protected Repository getRepository() {
- return repository;
- }
-
- @Override
- protected SessionProvider getSessionProvider() {
- return sessionProvider;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.io.Serializable;
-
-import javax.jcr.LoginException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * Implements an open session in view patter: a new JCR session is created for
- * each request
- */
-public class OpenInViewSessionProvider implements SessionProvider, Serializable {
- private static final long serialVersionUID = 2270957712453841368L;
-
- private final static Log log = LogFactory
- .getLog(OpenInViewSessionProvider.class);
-
- public Session getSession(HttpServletRequest request, Repository rep,
- String workspace) throws LoginException, ServletException,
- RepositoryException {
- return login(request, rep, workspace);
- }
-
- protected Session login(HttpServletRequest request, Repository repository,
- String workspace) throws RepositoryException {
- if (log.isTraceEnabled())
- log.trace("Login to workspace "
- + (workspace == null ? "<default>" : workspace)
- + " in web session " + request.getSession().getId());
- return repository.login(workspace);
- }
-
- public void releaseSession(Session session) {
- JcrUtils.logoutQuietly(session);
- if (log.isTraceEnabled())
- log.trace("Logged out remote JCR session " + session);
- }
-
- public void init() {
- }
-
- public void destroy() {
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.io.Serializable;
-
-import javax.jcr.LoginException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.JcrUtils;
-import org.springframework.security.Authentication;
-import org.springframework.security.context.SecurityContextHolder;
-
-/**
- * Session provider assuming a single workspace and a short life cycle,
- * typically a Spring bean of scope (web) 'session'.
- */
-public class ScopedSessionProvider implements SessionProvider, Serializable {
- private static final long serialVersionUID = 6589775984177317058L;
- private static final Log log = LogFactory
- .getLog(ScopedSessionProvider.class);
- private transient HttpSession httpSession = null;
- private transient Session jcrSession = null;
-
- private transient String currentRepositoryName = null;
- private transient String currentWorkspaceName = null;
- private transient String currentJcrUser = null;
-
- // private transient String anonymousUserId = "anonymous";
-
- public Session getSession(HttpServletRequest request, Repository rep,
- String workspace) throws LoginException, ServletException,
- RepositoryException {
-
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- if (authentication == null)
- throw new ArgeoException(
- "Request not authenticated by Spring Security");
- String springUser = authentication.getName();
-
- // HTTP
- String requestJcrRepository = (String) request
- .getAttribute(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
-
- // HTTP session
- if (httpSession != null
- && !httpSession.getId().equals(request.getSession().getId()))
- throw new ArgeoException(
- "Only session scope is supported in this mode");
- if (httpSession == null)
- httpSession = request.getSession();
-
- // Initializes current values
- if (currentRepositoryName == null)
- currentRepositoryName = requestJcrRepository;
- if (currentWorkspaceName == null)
- currentWorkspaceName = workspace;
- if (currentJcrUser == null)
- currentJcrUser = springUser;
-
- // logout if there was a change in session coordinates
- if (jcrSession != null)
- if (!currentRepositoryName.equals(requestJcrRepository)) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from repository '"
- + currentRepositoryName + "' to '"
- + requestJcrRepository
- + "', logging out cached JCR session.");
- logout();
- } else if (!currentWorkspaceName.equals(workspace)) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from workspace '"
- + currentWorkspaceName + "' to '" + workspace
- + "', logging out cached JCR session.");
- logout();
- } else if (!currentJcrUser.equals(springUser)) {
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " Changed from user '"
- + currentJcrUser + "' to '" + springUser
- + "', logging out cached JCR session.");
- logout();
- }
-
- // login if needed
- if (jcrSession == null)
- try {
- Session session = login(rep, workspace);
- if (!session.getUserID().equals(springUser)) {
- JcrUtils.logoutQuietly(session);
- throw new ArgeoException("Spring Security user '"
- + springUser + "' not in line with JCR user '"
- + session.getUserID() + "'");
- }
- currentRepositoryName = requestJcrRepository;
- // do not use workspace variable which may be null
- currentWorkspaceName = session.getWorkspace().getName();
- currentJcrUser = session.getUserID();
-
- jcrSession = session;
- return jcrSession;
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot open session to workspace "
- + workspace, e);
- }
-
- // returns cached session
- return jcrSession;
- }
-
- protected Session login(Repository repository, String workspace)
- throws RepositoryException {
- Session session = repository.login(workspace);
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId() + " User '" + session.getUserID()
- + "' logged in workspace '"
- + session.getWorkspace().getName() + "' of repository '"
- + currentRepositoryName + "'");
- return session;
- }
-
- public void releaseSession(Session session) {
- if (log.isTraceEnabled())
- log.trace(getHttpSessionId() + " Releasing JCR session " + session);
- }
-
- protected void logout() {
- JcrUtils.logoutQuietly(jcrSession);
- jcrSession = null;
- }
-
- protected final String getHttpSessionId() {
- return httpSession != null ? httpSession.getId() : "<null>";
- }
-
- public void init() {
- }
-
- public void destroy() {
- logout();
- if (getHttpSessionId() != null)
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId()
- + " Cleaned up provider for web session ");
- httpSession = null;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.LoginException;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.user.Group;
-import org.apache.jackrabbit.api.security.user.User;
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-
-/**
- * Implements an open session in view patter: a new JCR session is created for
- * each request
- *
- * @deprecated use {@link ScopedSessionProvider} or
- * {@link OpenInViewSessionProvider}
- */
-@Deprecated
-public class SimpleSessionProvider implements SessionProvider, Serializable {
- private static final long serialVersionUID = 2270957712453841368L;
-
- private final static Log log = LogFactory
- .getLog(SimpleSessionProvider.class);
-
- private transient Map<String, Session> sessions;
-
- private Boolean openSessionInView = true;
-
- private String defaultWorkspace = "default";
-
- private String webSessionId = null;
-
- public Session getSession(HttpServletRequest request, Repository rep,
- String workspace) throws LoginException, ServletException,
- RepositoryException {
-
- if (openSessionInView) {
- JackrabbitSession session = (JackrabbitSession) login(request, rep,
- workspace);
- if (session.getWorkspace().getName().equals(defaultWorkspace))
- writeRemoteRoles(session);
- return session;
- } else {
- if (webSessionId != null
- && !webSessionId.equals(request.getSession().getId()))
- throw new ArgeoException(
- "Only session scope is supported in this mode");
- webSessionId = request.getSession().getId();
-
- // since sessions is transient it can't be restored from the session
- if (sessions == null)
- sessions = Collections
- .synchronizedMap(new HashMap<String, Session>());
-
- if (!sessions.containsKey(workspace)) {
- try {
- // JackrabbitSession session = (JackrabbitSession)
- // rep.login(
- // null, workspace);
- JackrabbitSession session = (JackrabbitSession) login(
- request, rep, workspace);
- if (session.getWorkspace().getName()
- .equals(defaultWorkspace))
- writeRemoteRoles(session);
- if (log.isTraceEnabled())
- log.trace("User " + session.getUserID()
- + " logged into " + request.getServletPath());
- sessions.put(workspace, session);
- return session;
- } catch (Exception e) {
- throw new ArgeoException("Cannot open session", e);
- }
- } else {
- Session session = sessions.get(workspace);
- if (!session.isLive()) {
- sessions.remove(workspace);
- session = login(request, rep, workspace);
- sessions.put(workspace, session);
- }
- return session;
- }
- }
- }
-
- protected Session login(HttpServletRequest request, Repository repository,
- String workspace) throws RepositoryException {
- if (log.isDebugEnabled())
- log.debug("Login to workspace "
- + (workspace == null ? "<default>" : workspace)
- + " in web session " + request.getSession().getId());
- return repository.login(workspace);
- }
-
- protected void writeRemoteRoles(JackrabbitSession session)
- throws RepositoryException {
- // FIXME better deal w/ non node repo
-
- // retrieve roles
- String userId = session.getUserID();
- UserManager userManager = session.getUserManager();
- User user = (User) userManager.getAuthorizable(userId);
- if (user == null) {
- // anonymous
- return;
- }
- List<String> userGroupIds = new ArrayList<String>();
- if (user != null)
- for (Iterator<Group> it = user.memberOf(); it.hasNext();)
- userGroupIds.add(it.next().getID());
-
- // write roles if needed
- Node userHome = UserJcrUtils.getUserHome(session);
- boolean writeRoles = false;
- if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
- Value[] roles = userHome.getProperty(ArgeoNames.ARGEO_REMOTE_ROLES)
- .getValues();
- if (roles.length != userGroupIds.size())
- writeRoles = true;
- else
- for (int i = 0; i < roles.length; i++)
- if (!roles[i].getString().equals(userGroupIds.get(i)))
- writeRoles = true;
- } else
- writeRoles = true;
-
- if (writeRoles) {
- session.getWorkspace().getVersionManager()
- .checkout(userHome.getPath());
- String[] roleIds = userGroupIds.toArray(new String[userGroupIds
- .size()]);
- userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
- JcrUtils.updateLastModified(userHome);
- session.save();
- session.getWorkspace().getVersionManager()
- .checkin(userHome.getPath());
- }
-
- }
-
- public void releaseSession(Session session) {
- if (log.isTraceEnabled())
- log.trace("Releasing JCR session " + session);
- if (openSessionInView) {
- JcrUtils.logoutQuietly(session);
- if (log.isDebugEnabled())
- log.debug("Logged out remote JCR session " + session);
- }
- }
-
- public void init() {
- if (log.isDebugEnabled())
- log.debug("Init session provider for web session " + webSessionId);
- }
-
- public void destroy() {
- if (log.isDebugEnabled())
- log.debug("Destroy session provider for web session "
- + webSessionId);
-
- if (sessions != null)
- for (String workspace : sessions.keySet()) {
- Session session = sessions.get(workspace);
- JcrUtils.logoutQuietly(session);
- }
- }
-
- /**
- * If set to true a new session will be created each time (the default),
- * otherwise a single session is cached by workspace and the object should
- * be of scope session (not supported)
- */
- public void setOpenSessionInView(Boolean openSessionInView) {
- this.openSessionInView = openSessionInView;
- }
-
- public void setSecurityWorkspace(String securityWorkspace) {
- this.defaultWorkspace = securityWorkspace;
- }
-
-}
+++ /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.jackrabbit.remote;
-
-import java.util.Properties;
-
-import javax.jcr.Repository;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-
-/** Handler mapping for WebDav */
-public class SimpleWebdavHandlerMapping extends
- AbstractJackrabbitHandlerMapping {
- private String configuration;
-
- protected HttpServlet createServlet(Repository repository, String pathPrefix)
- throws ServletException {
-
- SimpleWebdavServlet servlet = new SimpleWebdavServlet(repository,
- getSessionProvider());
- Properties initParameters = new Properties();
- initParameters.setProperty(
- SimpleWebdavServlet.INIT_PARAM_RESOURCE_CONFIG, configuration);
- initParameters
- .setProperty(
- SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
- pathPrefix);
- servlet.init(new DelegatingServletConfig(pathPrefix.replace('/', '_'),
- initParameters));
- return servlet;
- }
-
- public void setConfiguration(String configuration) {
- this.configuration = configuration;
- }
-}
+++ /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.jackrabbit.remote;
-
-import java.io.IOException;
-
-import javax.jcr.Repository;
-import javax.servlet.ServletException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.apache.jackrabbit.webdav.DavException;
-import org.apache.jackrabbit.webdav.DavResource;
-import org.apache.jackrabbit.webdav.WebdavRequest;
-import org.apache.jackrabbit.webdav.WebdavResponse;
-
-/** WebDav servlet whose repository is injected */
-public class SimpleWebdavServlet extends
- org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet {
- private static final long serialVersionUID = -369787931175177080L;
-
- private final static Log log = LogFactory.getLog(SimpleWebdavServlet.class);
-
- private final Repository repository;
-
- public SimpleWebdavServlet(Repository repository,
- SessionProvider sessionProvider) {
- this.repository = repository;
- setSessionProvider(sessionProvider);
- }
-
- public Repository getRepository() {
- return repository;
- }
-
- @Override
- protected boolean execute(WebdavRequest request, WebdavResponse response,
- int method, DavResource resource) throws ServletException,
- IOException, DavException {
- if (log.isTraceEnabled())
- log.trace(request.getMethod() + "\t" + request.getPathInfo());
- boolean res = super.execute(request, response, method, resource);
- return res;
- }
-
-}
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
-<Repository>
- <!-- File system and datastore -->
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${rep.home}/fs" />
- </FileSystem>
- <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
- <param name="path" value="${rep.home}/datastore" />
- </DataStore>
-
- <!-- Workspace templates -->
- <Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="${argeo.node.repo.defaultWorkspace}" />
- <Workspace name="${wsp.name}">
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${wsp.home}" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager" />
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${wsp.home}/index" />
- </SearchIndex>
- </Workspace>
-
- <!-- Versioning -->
- <Versioning rootPath="${rep.home}/version">
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${rep.home}/version" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager" />
- </Versioning>
-
- <!-- Indexing -->
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/index" />
- <param name="extractorPoolSize" value="2" />
- <param name="supportHighlighting" value="true" />
- </SearchIndex>
-
- <!-- Security -->
- <Security appName="Jackrabbit">
- <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
- workspaceName="security">
- </SecurityManager>
- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
- </AccessManager>
- <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
- </LoginModule>
- </Security>
-</Repository>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
-<Repository>
- <!-- Shared datasource -->
- <DataSources>
- <DataSource name="dataSource">
- <param name="driver" value="org.h2.Driver" />
- <param name="url" value="jdbc:h2:${rep.home}/h2/repository" />
- <param name="user" value="sa" />
- <param name="password" value="" />
- <param name="databaseType" value="h2" />
- <param name="maxPoolSize" value="10" />
- </DataSource>
- </DataSources>
-
- <!-- File system and datastore -->
- <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
- <param name="dataSourceName" value="dataSource" />
- <param name="schema" value="default" />
- <param name="schemaObjectPrefix" value="fs_" />
- </FileSystem>
- <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
- <param name="path" value="${rep.home}/datastore" />
- </DataStore>
-
- <!-- Workspace templates -->
- <Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="main" />
- <Workspace name="${wsp.name}">
- <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
- <param name="dataSourceName" value="dataSource" />
- <param name="schema" value="default" />
- <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
- <param name="dataSourceName" value="dataSource" />
- <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
- </PersistenceManager>
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${wsp.home}/index" />
- </SearchIndex>
- </Workspace>
-
- <!-- Versioning -->
- <Versioning rootPath="${rep.home}/version">
- <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
- <param name="dataSourceName" value="dataSource" />
- <param name="schema" value="default" />
- <param name="schemaObjectPrefix" value="fs_ver_" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
- <param name="dataSourceName" value="dataSource" />
- <param name="schemaObjectPrefix" value="pm_ver_" />
- </PersistenceManager>
- </Versioning>
-
- <!-- Indexing -->
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/index" />
- <param name="extractorPoolSize" value="2" />
- <param name="supportHighlighting" value="true" />
- </SearchIndex>
-
- <!-- Security -->
- <Security appName="Jackrabbit">
- <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
- workspaceName="security">
- </SecurityManager>
- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
- </AccessManager>
- <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
- </LoginModule>
- </Security>
-</Repository>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<!--
-
- 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.
-
--->
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
-<Repository>
- <!-- File system and datastore -->
- <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-
- <!-- Workspace templates -->
- <Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="main" configRootPath="/workspaces" />
- <Workspace name="${wsp.name}">
- <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
- <param name="blobFSBlockSize" value="1" />
- </PersistenceManager>
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/repository/index" />
- <param name="directoryManagerClass"
- value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
- <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
- </SearchIndex>
- </Workspace>
-
- <!-- Versioning -->
- <Versioning rootPath="${rep.home}/version">
- <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
- <param name="blobFSBlockSize" value="1" />
- </PersistenceManager>
- </Versioning>
-
- <!-- Indexing -->
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/repository/index" />
- <param name="directoryManagerClass"
- value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
- <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
- </SearchIndex>
-
- <!-- Security -->
- <Security appName="Jackrabbit">
- <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
- workspaceName="security">
- </SecurityManager>
- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
- </AccessManager>
- <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
- </LoginModule>
- </Security>
-</Repository>
\ No newline at end of file
+++ /dev/null
-= Titre =\r
-\r
- == Sous Titre ==\r
-\r
-* point1\r
-* point2\r
-\r
- Code (il suffit de mettre un espace en début de ligne\r
-
\ 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.jackrabbit;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.security.JcrAuthorizations;
+
+/** Apply authorizations to a Jackrabbit repository. */
+public class JackrabbitAuthorizations extends JcrAuthorizations {
+ private final static Log log = LogFactory
+ .getLog(JackrabbitAuthorizations.class);
+
+ private List<String> groupPrefixes = Arrays
+ .asList(new String[] { "ROLE_" });// new ArrayList<String>();
+
+ @Override
+ protected Principal getOrCreatePrincipal(Session session,
+ String principalName) throws RepositoryException {
+ UserManager um = ((JackrabbitSession) session).getUserManager();
+ synchronized (um) {
+ Authorizable authorizable = um.getAuthorizable(principalName);
+ if (authorizable == null) {
+ groupPrefixes: for (String groupPrefix : groupPrefixes) {
+ if (principalName.startsWith(groupPrefix)) {
+ authorizable = um.createGroup(principalName);
+ log.info("Created group " + principalName);
+ break groupPrefixes;
+ }
+ }
+ if (authorizable == null)
+ throw new ArgeoException("Authorizable " + principalName
+ + " not found");
+ }
+ return authorizable.getPrincipal();
+ }
+ }
+
+ public void setGroupPrefixes(List<String> groupsToCreate) {
+ this.groupPrefixes = groupsToCreate;
+ }
+}
--- /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.jackrabbit;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.MaintainedRepository;
+import org.springframework.core.io.Resource;
+import org.springframework.util.SystemPropertyUtils;
+import org.xml.sax.InputSource;
+
+/**
+ * Wrapper around a Jackrabbit repository which allows to configure it in Spring
+ * and expose it as a {@link Repository}.
+ */
+public class JackrabbitContainer extends JackrabbitWrapper implements
+ MaintainedRepository {
+ private final static Log log = LogFactory.getLog(JackrabbitContainer.class);
+
+ // local
+ private Resource configuration;
+ private Resource variables;
+ private RepositoryConfig repositoryConfig;
+ private File homeDirectory;
+ private Boolean inMemory = false;
+
+ /** Migrations to execute (if not already done) */
+ private Set<JackrabbitDataModelMigration> dataModelMigrations = new HashSet<JackrabbitDataModelMigration>();
+
+ /**
+ * Empty constructor, {@link #init()} should be called after properties have
+ * been set
+ */
+ public JackrabbitContainer() {
+ }
+
+ public void init() {
+ long begin = System.currentTimeMillis();
+
+ if (getRepository() != null)
+ throw new ArgeoException(
+ "Cannot be used to wrap another repository");
+ Repository repository = createJackrabbitRepository();
+ super.setRepository(repository);
+
+ // migrate if needed
+ migrate();
+
+ // apply new CND files after migration
+ prepareDataModel();
+
+ double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+ if (log.isDebugEnabled())
+ log.debug("Initialized JCR repository wrapper in " + duration
+ + " s");
+ }
+
+ /** Actually creates the new repository. */
+ protected Repository createJackrabbitRepository() {
+ long begin = System.currentTimeMillis();
+ InputStream configurationIn = null;
+ Repository repository;
+ try {
+ // temporary
+ if (inMemory && getHomeDirectory().exists()) {
+ FileUtils.deleteDirectory(getHomeDirectory());
+ log.warn("Deleted Jackrabbit home directory "
+ + getHomeDirectory());
+ }
+
+ // process configuration file
+ Properties vars = getConfigurationProperties();
+ configurationIn = readConfiguration();
+ vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
+ getHomeDirectory().getCanonicalPath());
+ repositoryConfig = RepositoryConfig.create(new InputSource(
+ configurationIn), vars);
+
+ //
+ // Actual repository creation
+ //
+ repository = RepositoryImpl.create(repositoryConfig);
+
+ double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+ if (log.isTraceEnabled())
+ log.trace("Created Jackrabbit repository in " + duration
+ + " s, home: " + getHomeDirectory());
+
+ return repository;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot create Jackrabbit repository "
+ + getHomeDirectory(), e);
+ } finally {
+ IOUtils.closeQuietly(configurationIn);
+ }
+ }
+
+ /** Lazy init. */
+ protected File getHomeDirectory() {
+ try {
+ if (homeDirectory == null) {
+ if (inMemory) {
+ homeDirectory = new File(
+ System.getProperty("java.io.tmpdir")
+ + File.separator
+ + System.getProperty("user.name")
+ + File.separator + "jackrabbit-"
+ + UUID.randomUUID());
+ homeDirectory.mkdirs();
+ // will it work if directory is not empty??
+ homeDirectory.deleteOnExit();
+ }
+ }
+
+ return homeDirectory.getCanonicalFile();
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot get canonical file for "
+ + homeDirectory, e);
+ }
+ }
+
+ /** Executes migrations, if needed. */
+ protected void migrate() {
+ // No migration to perform
+ if (dataModelMigrations.size() == 0)
+ return;
+
+ Boolean restartAndClearCaches = false;
+
+ // migrate data
+ Session session = null;
+ try {
+ session = login();
+ for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
+ dataModelMigrations)) {
+ if (dataModelMigration.migrate(session)) {
+ restartAndClearCaches = true;
+ }
+ }
+ } catch (ArgeoException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot migrate", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+
+ // restart repository
+ if (restartAndClearCaches) {
+ Repository repository = getRepository();
+ if (repository instanceof RepositoryImpl) {
+ JackrabbitDataModelMigration
+ .clearRepositoryCaches(((RepositoryImpl) repository)
+ .getConfig());
+ }
+ ((JackrabbitRepository) repository).shutdown();
+ createJackrabbitRepository();
+ }
+
+ // set data model version
+ try {
+ session = login();
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot login to migrated repository", e);
+ }
+
+ for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
+ dataModelMigrations)) {
+ try {
+ if (session.itemExists(dataModelMigration
+ .getDataModelNodePath())) {
+ Node dataModelNode = session.getNode(dataModelMigration
+ .getDataModelNodePath());
+ dataModelNode.setProperty(
+ ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+ dataModelMigration.getTargetVersion());
+ session.save();
+ }
+ } catch (Exception e) {
+ log.error("Cannot set model version", e);
+ }
+ }
+ JcrUtils.logoutQuietly(session);
+
+ }
+
+ /** Shutdown the repository */
+ public void destroy() throws Exception {
+ Repository repository = getRepository();
+ if (repository != null && repository instanceof RepositoryImpl) {
+ long begin = System.currentTimeMillis();
+ ((RepositoryImpl) repository).shutdown();
+ if (inMemory)
+ if (getHomeDirectory().exists()) {
+ FileUtils.deleteDirectory(getHomeDirectory());
+ if (log.isDebugEnabled())
+ log.debug("Deleted Jackrabbit home directory "
+ + getHomeDirectory());
+ }
+ double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+ log.info("Destroyed Jackrabbit repository in " + duration
+ + " s, home: " + getHomeDirectory());
+ }
+ repository = null;
+ }
+
+ public void dispose() {
+ throw new IllegalArgumentException(
+ "Call destroy() method instead of dispose()");
+ }
+
+ /*
+ * UTILITIES
+ */
+ /**
+ * Reads the configuration which will initialize a {@link RepositoryConfig}.
+ */
+ protected InputStream readConfiguration() {
+ try {
+ return configuration != null ? configuration.getInputStream()
+ : null;
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot read Jackrabbit configuration "
+ + configuration, e);
+ }
+ }
+
+ /**
+ * Reads the variables which will initialize a {@link Properties}. Returns
+ * null by default, to be overridden.
+ *
+ * @return a new stream or null if no variables available
+ */
+ protected InputStream readVariables() {
+ try {
+ return variables != null ? variables.getInputStream() : null;
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot read Jackrabbit variables "
+ + variables, e);
+ }
+ }
+
+ /**
+ * Resolves ${} placeholders in the provided string. Based on system
+ * properties if no map is provided.
+ */
+ protected String resolvePlaceholders(String string,
+ Map<String, String> variables) {
+ return SystemPropertyUtils.resolvePlaceholders(string);
+ }
+
+ /** Generates the properties to use in the configuration. */
+ protected Properties getConfigurationProperties() {
+ InputStream propsIn = null;
+ Properties vars;
+ try {
+ vars = new Properties();
+ propsIn = readVariables();
+ if (propsIn != null) {
+ vars.load(propsIn);
+ }
+ // resolve system properties
+ for (Object key : vars.keySet()) {
+ // TODO: implement a smarter mechanism to resolve nested ${}
+ String newValue = resolvePlaceholders(
+ vars.getProperty(key.toString()), null);
+ vars.put(key, newValue);
+ }
+ // override with system properties
+ vars.putAll(System.getProperties());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Jackrabbit config variables:");
+ for (Object key : new TreeSet<Object>(vars.keySet()))
+ log.trace(key + "=" + vars.getProperty(key.toString()));
+ }
+
+ } catch (IOException e) {
+ throw new ArgeoException("Cannot read configuration properties", e);
+ } finally {
+ IOUtils.closeQuietly(propsIn);
+ }
+ return vars;
+ }
+
+ /*
+ * FIELDS ACCESS
+ */
+
+ public void setHomeDirectory(File homeDirectory) {
+ this.homeDirectory = homeDirectory;
+ }
+
+ public void setInMemory(Boolean inMemory) {
+ this.inMemory = inMemory;
+ }
+
+ public void setRepository(Repository repository) {
+ throw new ArgeoException("Cannot be used to wrap another repository");
+ }
+
+ public void setDataModelMigrations(
+ Set<JackrabbitDataModelMigration> dataModelMigrations) {
+ this.dataModelMigrations = dataModelMigrations;
+ }
+
+ public void setVariables(Resource variables) {
+ this.variables = variables;
+ }
+
+ public void setConfiguration(Resource configuration) {
+ this.configuration = configuration;
+ }
+
+}
--- /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.jackrabbit;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrCallback;
+import org.argeo.jcr.JcrUtils;
+import org.springframework.core.io.Resource;
+
+/** Migrate the data in a Jackrabbit repository. */
+public class JackrabbitDataModelMigration implements
+ Comparable<JackrabbitDataModelMigration> {
+ private final static Log log = LogFactory
+ .getLog(JackrabbitDataModelMigration.class);
+
+ private String dataModelNodePath;
+ private String targetVersion;
+ private Resource migrationCnd;
+ private JcrCallback dataModification;
+
+ /**
+ * Expects an already started repository with the old data model to migrate.
+ * Expects to be run with admin rights (Repository.login() will be used).
+ *
+ * @return true if a migration was performed and the repository needs to be
+ * restarted and its caches cleared.
+ */
+ public Boolean migrate(Session session) {
+ long begin = System.currentTimeMillis();
+ Reader reader = null;
+ try {
+ // check if already migrated
+ if (!session.itemExists(dataModelNodePath)) {
+ log.warn("Node " + dataModelNodePath
+ + " does not exist: nothing to migrate.");
+ return false;
+ }
+ Node dataModelNode = session.getNode(dataModelNodePath);
+ if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
+ String currentVersion = dataModelNode.getProperty(
+ ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
+ if (compareVersions(currentVersion, targetVersion) >= 0) {
+ log.info("Data model at version " + currentVersion
+ + ", no need to migrate.");
+ return false;
+ }
+ }
+
+ // apply transitional CND
+ if (migrationCnd != null) {
+ reader = new InputStreamReader(migrationCnd.getInputStream());
+ CndImporter.registerNodeTypes(reader, session, true);
+ session.save();
+ log.info("Registered migration node types from " + migrationCnd);
+ }
+
+ // modify data
+ dataModification.execute(session);
+
+ // apply changes
+ session.save();
+
+ long duration = System.currentTimeMillis() - begin;
+ log.info("Migration of data model " + dataModelNodePath + " to "
+ + targetVersion + " performed in " + duration + "ms");
+ return true;
+ } catch (Exception e) {
+ JcrUtils.discardQuietly(session);
+ throw new ArgeoException("Migration of data model "
+ + dataModelNodePath + " to " + targetVersion + " failed.",
+ e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ IOUtils.closeQuietly(reader);
+ }
+ }
+
+ protected static int compareVersions(String version1, String version2) {
+ // TODO do a proper version analysis and comparison
+ return version1.compareTo(version2);
+ }
+
+ /** To be called on a stopped repository. */
+ public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) {
+ try {
+ String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml";
+ repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath);
+ if (log.isDebugEnabled())
+ log.debug("Cleared " + customeNodeTypesPath);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot clear caches", e);
+ }
+
+ // File customNodeTypes = new File(home.getPath()
+ // + "/repository/nodetypes/custom_nodetypes.xml");
+ // if (customNodeTypes.exists()) {
+ // customNodeTypes.delete();
+ // if (log.isDebugEnabled())
+ // log.debug("Cleared " + customNodeTypes);
+ // } else {
+ // log.warn("File " + customNodeTypes + " not found.");
+ // }
+ }
+
+ /*
+ * FOR USE IN (SORTED) SETS
+ */
+
+ public int compareTo(JackrabbitDataModelMigration dataModelMigration) {
+ // TODO make ordering smarter
+ if (dataModelNodePath.equals(dataModelMigration.dataModelNodePath))
+ return compareVersions(targetVersion,
+ dataModelMigration.targetVersion);
+ else
+ return dataModelNodePath
+ .compareTo(dataModelMigration.dataModelNodePath);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof JackrabbitDataModelMigration))
+ return false;
+ JackrabbitDataModelMigration dataModelMigration = (JackrabbitDataModelMigration) obj;
+ return dataModelNodePath.equals(dataModelMigration.dataModelNodePath)
+ && targetVersion.equals(dataModelMigration.targetVersion);
+ }
+
+ @Override
+ public int hashCode() {
+ return targetVersion.hashCode();
+ }
+
+ public void setDataModelNodePath(String dataModelNodePath) {
+ this.dataModelNodePath = dataModelNodePath;
+ }
+
+ public void setTargetVersion(String targetVersion) {
+ this.targetVersion = targetVersion;
+ }
+
+ public void setMigrationCnd(Resource migrationCnd) {
+ this.migrationCnd = migrationCnd;
+ }
+
+ public void setDataModification(JcrCallback dataModification) {
+ this.dataModification = dataModification;
+ }
+
+ public String getDataModelNodePath() {
+ return dataModelNodePath;
+ }
+
+ public String getTargetVersion() {
+ return targetVersion;
+ }
+
+}
--- /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.jackrabbit;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.DefaultRepositoryFactory;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.xml.sax.InputSource;
+
+/**
+ * Repository factory which can create new repositories and access remote
+ * Jackrabbit repositories
+ */
+public class JackrabbitRepositoryFactory extends DefaultRepositoryFactory
+ implements RepositoryFactory, ArgeoJcrConstants {
+
+ private final static Log log = LogFactory
+ .getLog(JackrabbitRepositoryFactory.class);
+
+ private Resource fileRepositoryConfiguration = new ClassPathResource(
+ "/org/argeo/jackrabbit/repository-h2.xml");
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Repository getRepository(Map parameters) throws RepositoryException {
+ // check if can be found by alias
+ Repository repository = super.getRepository(parameters);
+ if (repository != null)
+ return repository;
+
+ // check if remote
+ String uri = null;
+ if (parameters.containsKey(JCR_REPOSITORY_URI))
+ uri = parameters.get(JCR_REPOSITORY_URI).toString();
+ else if (parameters.containsKey(JcrUtils.REPOSITORY_URI))
+ uri = parameters.get(JcrUtils.REPOSITORY_URI).toString();
+
+ if (uri != null) {
+ if (uri.startsWith("http"))// http, https
+ repository = createRemoteRepository(uri);
+ else if (uri.startsWith("file"))// http, https
+ repository = createFileRepository(uri, parameters);
+ else if (uri.startsWith("vm")) {
+ log.warn("URI "
+ + uri
+ + " should have been managed by generic JCR repository factory");
+ repository = getRepositoryByAlias(getAliasFromURI(uri));
+ }
+ }
+
+ // publish under alias
+ if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) {
+ Properties properties = new Properties();
+ properties.putAll(parameters);
+ String alias = parameters.get(JCR_REPOSITORY_ALIAS).toString();
+ publish(alias, repository, properties);
+ log.info("Registered JCR repository under alias '" + alias
+ + "' with properties " + properties);
+ }
+
+ return repository;
+ }
+
+ protected Repository createRemoteRepository(String uri)
+ throws RepositoryException {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(JcrUtils.REPOSITORY_URI, uri);
+ Repository repository = new Jcr2davRepositoryFactory()
+ .getRepository(params);
+ if (repository == null)
+ throw new ArgeoException("Remote Davex repository " + uri
+ + " not found");
+ log.info("Initialized remote Jackrabbit repository from uri " + uri);
+ return repository;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected Repository createFileRepository(final String uri, Map parameters)
+ throws RepositoryException {
+ InputStream configurationIn = null;
+ try {
+ Properties vars = new Properties();
+ vars.putAll(parameters);
+ String dirPath = uri.substring("file:".length());
+ File homeDir = new File(dirPath);
+ if (homeDir.exists() && !homeDir.isDirectory())
+ throw new ArgeoException("Repository home " + dirPath
+ + " is not a directory");
+ if (!homeDir.exists())
+ homeDir.mkdirs();
+ configurationIn = fileRepositoryConfiguration.getInputStream();
+ vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
+ homeDir.getCanonicalPath());
+ RepositoryConfig repositoryConfig = RepositoryConfig.create(
+ new InputSource(configurationIn), vars);
+
+ // TransientRepository repository = new
+ // TransientRepository(repositoryConfig);
+ final RepositoryImpl repository = RepositoryImpl
+ .create(repositoryConfig);
+ Session session = repository.login();
+ // FIXME make it generic
+ org.argeo.jcr.JcrUtils.addPrivilege(session, "/", "ROLE_ADMIN",
+ "jcr:all");
+ org.argeo.jcr.JcrUtils.logoutQuietly(session);
+ Runtime.getRuntime().addShutdownHook(
+ new Thread("Clean JCR repository " + uri) {
+ public void run() {
+ repository.shutdown();
+ log.info("Destroyed repository " + uri);
+ }
+ });
+ log.info("Initialized file Jackrabbit repository from uri " + uri);
+ return repository;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot create repository " + uri, e);
+ } finally {
+ IOUtils.closeQuietly(configurationIn);
+ }
+ }
+
+ /**
+ * Called after the repository has been initialised. Does nothing by
+ * default.
+ */
+ @SuppressWarnings("rawtypes")
+ protected void postInitialization(Repository repository, Map parameters) {
+
+ }
+
+ public void setFileRepositoryConfiguration(
+ Resource fileRepositoryConfiguration) {
+ this.fileRepositoryConfiguration = fileRepositoryConfiguration;
+ }
+
+}
--- /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.jackrabbit;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+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.Session;
+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.apache.jackrabbit.commons.NamespaceHelper;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrRepositoryWrapper;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.util.security.DigestUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+/**
+ * Wrapper around a Jackrabbit repository which allows to simplify configuration
+ * and intercept some actions. It exposes itself as a {@link Repository}.
+ */
+public class JackrabbitWrapper extends JcrRepositoryWrapper implements
+ ResourceLoaderAware {
+ private final static Log log = LogFactory.getLog(JackrabbitWrapper.class);
+ private final static String DIGEST_ALGORITHM = "MD5";
+
+ // local
+ private ResourceLoader resourceLoader;
+
+ // data model
+ /** Node type definitions in CND format */
+ private List<String> cndFiles = new ArrayList<String>();
+ /**
+ * Always import CNDs. Useful during development of new data models. In
+ * production, explicit migration processes should be used.
+ */
+ private Boolean forceCndImport = true;
+
+ /** Namespaces to register: key is prefix, value namespace */
+ private Map<String, String> namespaces = new HashMap<String, String>();
+
+ private BundleContext bundleContext;
+
+ /**
+ * Explicitly set admin credentials used in initialization. Useful for
+ * testing, in real applications authentication is rather dealt with
+ * externally
+ */
+ private Credentials adminCredentials = null;
+
+ /**
+ * Empty constructor, {@link #init()} should be called after properties have
+ * been set
+ */
+ public JackrabbitWrapper() {
+ }
+
+ @Override
+ public void init() {
+ prepareDataModel();
+ }
+
+ /*
+ * DATA MODEL
+ */
+
+ /**
+ * Import declared node type definitions and register namespaces. Tries to
+ * update the node definitions if they have changed. In case of failures an
+ * error will be logged but no exception will be thrown.
+ */
+ protected void prepareDataModel() {
+ if ((cndFiles == null || cndFiles.size() == 0)
+ && (namespaces == null || namespaces.size() == 0))
+ return;
+
+ Session session = null;
+ try {
+ session = login(adminCredentials);
+ // register namespaces
+ if (namespaces.size() > 0) {
+ NamespaceHelper namespaceHelper = new NamespaceHelper(session);
+ namespaceHelper.registerNamespaces(namespaces);
+ }
+
+ // load CND files from classpath or as URL
+ for (String resUrl : cndFiles) {
+ processCndFile(session, resUrl);
+ }
+ } catch (Exception e) {
+ JcrUtils.discardQuietly(session);
+ throw new ArgeoException("Cannot import node type definitions "
+ + cndFiles, e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+
+ }
+
+ protected void processCndFile(Session session, String resUrl) {
+ Reader reader = null;
+ try {
+ // check existing data model nodes
+ new NamespaceHelper(session).registerNamespace(ArgeoNames.ARGEO,
+ ArgeoNames.ARGEO_NAMESPACE);
+ if (!session.itemExists(ArgeoJcrConstants.DATA_MODELS_BASE_PATH))
+ JcrUtils.mkdirs(session,
+ ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
+ Node dataModels = session
+ .getNode(ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
+ NodeIterator it = dataModels.getNodes();
+ Node dataModel = null;
+ while (it.hasNext()) {
+ Node node = it.nextNode();
+ if (node.getProperty(ArgeoNames.ARGEO_URI).getString()
+ .equals(resUrl)) {
+ dataModel = node;
+ break;
+ }
+ }
+
+ byte[] cndContent = readCndContent(resUrl);
+ String newDigest = DigestUtils.digest(DIGEST_ALGORITHM, cndContent);
+ Bundle bundle = findDataModelBundle(resUrl);
+
+ String currentVersion = null;
+ if (dataModel != null) {
+ currentVersion = dataModel.getProperty(
+ ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
+ if (dataModel.hasNode(Node.JCR_CONTENT)) {
+ String oldDigest = JcrUtils.checksumFile(dataModel,
+ DIGEST_ALGORITHM);
+ if (oldDigest.equals(newDigest)) {
+ if (log.isDebugEnabled())
+ log.debug("Data model " + resUrl
+ + " hasn't changed, keeping version "
+ + currentVersion);
+ return;
+ }
+ }
+ }
+
+ if (dataModel != null && !forceCndImport) {
+ log.info("Data model "
+ + resUrl
+ + " has changed since version "
+ + currentVersion
+ + (bundle != null ? ": version " + bundle.getVersion()
+ + ", bundle " + bundle.getSymbolicName() : ""));
+ return;
+ }
+
+ reader = new InputStreamReader(new ByteArrayInputStream(cndContent));
+ // actually imports the CND
+ try {
+ CndImporter.registerNodeTypes(reader, session, true);
+ } catch (Exception e) {
+ log.error("Cannot import data model " + resUrl, e);
+ return;
+ }
+
+ if (dataModel != null && !dataModel.isNodeType(NodeType.NT_FILE)) {
+ dataModel.remove();
+ dataModel = null;
+ }
+
+ // FIXME: what if argeo.cnd would not be the first called on
+ // a new repo? argeo:dataModel would not be found
+ String fileName = FilenameUtils.getName(resUrl);
+ if (dataModel == null) {
+ dataModel = dataModels.addNode(fileName, NodeType.NT_FILE);
+ dataModel.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
+ dataModel.addMixin(ArgeoTypes.ARGEO_DATA_MODEL);
+ dataModel.setProperty(ArgeoNames.ARGEO_URI, resUrl);
+ } else {
+ session.getWorkspace().getVersionManager()
+ .checkout(dataModel.getPath());
+ }
+ if (bundle != null)
+ dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+ bundle.getVersion().toString());
+ else
+ dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+ "0.0.0");
+ JcrUtils.copyBytesAsFile(dataModel.getParent(), fileName,
+ cndContent);
+ JcrUtils.updateLastModified(dataModel);
+ session.save();
+ session.getWorkspace().getVersionManager()
+ .checkin(dataModel.getPath());
+
+ if (currentVersion == null)
+ log.info("Data model "
+ + resUrl
+ + (bundle != null ? ", version " + bundle.getVersion()
+ + ", bundle " + bundle.getSymbolicName() : ""));
+ else
+ log.info("Data model "
+ + resUrl
+ + " updated from version "
+ + currentVersion
+ + (bundle != null ? ", version " + bundle.getVersion()
+ + ", bundle " + bundle.getSymbolicName() : ""));
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot process data model " + resUrl, e);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+ }
+
+ protected byte[] readCndContent(String resUrl) {
+ InputStream in = null;
+ try {
+ boolean classpath;
+ // normalize URL
+ if (bundleContext != null && resUrl.startsWith("classpath:")) {
+ resUrl = resUrl.substring("classpath:".length());
+ classpath = true;
+ } else if (resUrl.indexOf(':') < 0) {
+ if (!resUrl.startsWith("/")) {
+ resUrl = "/" + resUrl;
+ log.warn("Classpath should start with '/'");
+ }
+ classpath = true;
+ } else {
+ classpath = false;
+ }
+
+ URL url = null;
+ if (classpath) {
+ if (bundleContext != null) {
+ Bundle currentBundle = bundleContext.getBundle();
+ url = currentBundle.getResource(resUrl);
+ } else {
+ resUrl = "classpath:" + resUrl;
+ url = null;
+ }
+ } else if (!resUrl.startsWith("classpath:")) {
+ url = new URL(resUrl);
+ }
+
+ if (url != null) {
+ in = url.openStream();
+ } else if (resourceLoader != null) {
+ Resource res = resourceLoader.getResource(resUrl);
+ in = res.getInputStream();
+ url = res.getURL();
+ } else {
+ throw new ArgeoException("No " + resUrl + " in the classpath,"
+ + " make sure the containing" + " package is visible.");
+ }
+
+ return IOUtils.toByteArray(in);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot read CND from " + resUrl, e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ /*
+ * REPOSITORY INTERCEPTOR
+ */
+
+ /*
+ * UTILITIES
+ */
+ /** Find which OSGi bundle provided the data model resource */
+ protected Bundle findDataModelBundle(String resUrl) {
+ if (bundleContext == null)
+ return null;
+
+ if (resUrl.startsWith("/"))
+ resUrl = resUrl.substring(1);
+ String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/',
+ '.');
+ ServiceReference paSr = bundleContext
+ .getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) bundleContext
+ .getService(paSr);
+
+ // find exported package
+ ExportedPackage exportedPackage = null;
+ ExportedPackage[] exportedPackages = packageAdmin
+ .getExportedPackages(pkg);
+ if (exportedPackages == null)
+ throw new ArgeoException("No exported package found for " + pkg);
+ for (ExportedPackage ep : exportedPackages) {
+ for (Bundle b : ep.getImportingBundles()) {
+ if (b.getBundleId() == bundleContext.getBundle().getBundleId()) {
+ exportedPackage = ep;
+ break;
+ }
+ }
+ }
+
+ Bundle exportingBundle = null;
+ if (exportedPackage != null) {
+ exportingBundle = exportedPackage.getExportingBundle();
+ } else {
+ // assume this is in the same bundle
+ exportingBundle = bundleContext.getBundle();
+// throw new ArgeoException("No OSGi exporting package found for "
+// + resUrl);
+ }
+ return exportingBundle;
+ }
+
+ /*
+ * FIELDS ACCESS
+ */
+ public void setNamespaces(Map<String, String> namespaces) {
+ this.namespaces = namespaces;
+ }
+
+ public void setCndFiles(List<String> cndFiles) {
+ this.cndFiles = cndFiles;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void setForceCndImport(Boolean forceCndUpdate) {
+ this.forceCndImport = forceCndUpdate;
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ public void setAdminCredentials(Credentials adminCredentials) {
+ this.adminCredentials = adminCredentials;
+ }
+
+}
--- /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.jackrabbit;
+
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * OSGi-aware Jackrabbit repository factory which can retrieve/publish
+ * {@link Repository} as OSGi services.
+ */
+public class OsgiJackrabbitRepositoryFactory extends
+ JackrabbitRepositoryFactory {
+ private BundleContext bundleContext;
+
+ protected void publish(String alias, Repository repository,
+ Properties properties) {
+ if (bundleContext != null) {
+ // do not modify reference
+ Hashtable<String, String> props = new Hashtable<String, String>();
+ props.putAll(props);
+ props.put(JCR_REPOSITORY_ALIAS, alias);
+ bundleContext.registerService(Repository.class.getName(),
+ repository, props);
+ }
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import org.apache.jackrabbit.server.SessionProvider;
+import org.argeo.jcr.mvc.MultipleRepositoryHandlerMapping;
+
+/** Base class for Jackrabbit handler mappings. */
+public abstract class AbstractJackrabbitHandlerMapping extends
+ MultipleRepositoryHandlerMapping {
+ private SessionProvider sessionProvider;
+
+ protected SessionProvider getSessionProvider() {
+ return sessionProvider;
+ }
+
+ public void setSessionProvider(SessionProvider sessionProvider) {
+ this.sessionProvider = sessionProvider;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.springframework.web.servlet.DispatcherServlet;
+
+/**
+ * Overrides Spring {@link DispatcherServlet}, see
+ * http://forum.springsource.org/showthread.php?t=53472.
+ */
+public class ExtendedDispatcherServlet extends DispatcherServlet {
+ private static final long serialVersionUID = -5584673209855752009L;
+
+ private final static Log log = LogFactory
+ .getLog(ExtendedDispatcherServlet.class);
+
+ protected void service(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException,
+ java.io.IOException {
+ try {
+ if (log.isTraceEnabled()) {
+ log.trace("SessionID = " + request.getSession().getId());
+ log.trace(" ContextPath = " + request.getContextPath());
+ log.trace(" ServletPath = " + request.getServletPath());
+ log.trace(" PathInfo = " + request.getPathInfo());
+ log.trace(" Method = " + request.getMethod());
+ log.trace(" User-Agent = " + request.getHeader("User-Agent"));
+ }
+ doService(request, response);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot process request", e);
+ }
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.io.IOException;
+
+import org.apache.jackrabbit.server.io.ExportContext;
+import org.apache.jackrabbit.server.io.IOHandler;
+import org.apache.jackrabbit.server.io.IOManager;
+import org.apache.jackrabbit.server.io.ImportContext;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.argeo.ArgeoException;
+
+/** Wraps an IOHandler so that it can be injected a posteriori */
+public class IOHandlerWrapper implements IOHandler {
+ private IOManager ioManager = null;
+ private IOHandler ioHandler = null;
+
+ public void setIOHandler(IOHandler ioHandler) {
+ if ((this.ioHandler != null) && (ioHandler != null))
+ throw new ArgeoException(
+ "There is already an IO Handler registered");
+ this.ioHandler = ioHandler;
+ if (ioManager != null && this.ioHandler != null)
+ ioHandler.setIOManager(ioManager);
+ }
+
+ public IOHandler getIOHandler() {
+ return ioHandler;
+ }
+
+ public IOManager getIOManager() {
+ return ioManager;
+ }
+
+ public void setIOManager(IOManager ioManager) {
+ this.ioManager = ioManager;
+ if (ioHandler != null)
+ ioHandler.setIOManager(ioManager);
+ }
+
+ public String getName() {
+ if (ioHandler != null)
+ return ioHandler.getName();
+ else
+ return "Empty IOHandler Wrapper";
+ }
+
+ public boolean canImport(ImportContext context, boolean isCollection) {
+ if (ioHandler != null)
+ return ioHandler.canImport(context, isCollection);
+ return false;
+ }
+
+ public boolean canImport(ImportContext context, DavResource resource) {
+ if (ioHandler != null)
+ return ioHandler.canImport(context, resource);
+ return false;
+ }
+
+ public boolean importContent(ImportContext context, boolean isCollection)
+ throws IOException {
+ if (ioHandler != null)
+ ioHandler.importContent(context, isCollection);
+ return false;
+ }
+
+ public boolean importContent(ImportContext context, DavResource resource)
+ throws IOException {
+ if (ioHandler != null)
+ ioHandler.importContent(context, resource);
+ return false;
+ }
+
+ public boolean canExport(ExportContext context, boolean isCollection) {
+ if (ioHandler != null)
+ ioHandler.canExport(context, isCollection);
+ return false;
+ }
+
+ public boolean canExport(ExportContext context, DavResource resource) {
+ if (ioHandler != null)
+ ioHandler.canExport(context, resource);
+ return false;
+ }
+
+ public boolean exportContent(ExportContext context, boolean isCollection)
+ throws IOException {
+ if (ioHandler != null)
+ ioHandler.exportContent(context, isCollection);
+ return false;
+ }
+
+ public boolean exportContent(ExportContext context, DavResource resource)
+ throws IOException {
+ if (ioHandler != null)
+ ioHandler.exportContent(context, resource);
+ return false;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jackrabbit.server.io.ExportContext;
+import org.apache.jackrabbit.server.io.IOHandler;
+import org.apache.jackrabbit.server.io.IOManager;
+import org.apache.jackrabbit.server.io.ImportContext;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.tika.detect.Detector;
+
+/** {@link IOManager} that can easily be configured as a bean. */
+public class IOManagerBean implements IOManager {
+ private Detector detector = null;
+ private List<IOHandler> ioHandlers = new ArrayList<IOHandler>();
+
+ public boolean importContent(ImportContext context, boolean isCollection)
+ throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean importContent(ImportContext context, DavResource resource)
+ throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean exportContent(ExportContext context, boolean isCollection)
+ throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean exportContent(ExportContext context, DavResource resource)
+ throws IOException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public synchronized void addIOHandler(IOHandler ioHandler) {
+ ioHandlers.add(ioHandler);
+ }
+
+ public synchronized IOHandler[] getIOHandlers() {
+ return ioHandlers.toArray(new IOHandler[ioHandlers.size()]);
+ }
+
+ public Detector getDetector() {
+ return detector;
+ }
+
+ public void setDetector(Detector detector) {
+ this.detector = detector;
+ }
+
+ public synchronized List<IOHandler> getIoHandlers() {
+ return ioHandlers;
+ }
+
+ public synchronized void setIoHandlers(List<IOHandler> ioHandlers) {
+ this.ioHandlers = ioHandlers;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+public class JcrRemotingHandlerMapping extends AbstractJackrabbitHandlerMapping {
+
+ protected HttpServlet createServlet(Repository repository, String pathPrefix)
+ throws ServletException {
+ JcrRemotingServlet servlet = new JcrRemotingServlet(repository,
+ getSessionProvider());
+ Properties initParameters = new Properties();
+ initParameters.setProperty(
+ JcrRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, pathPrefix);
+ servlet.init(new DelegatingServletConfig(pathPrefix.replace('/', '_'),
+ initParameters));
+ return servlet;
+ }
+}
--- /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.jackrabbit.remote;
+
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.server.SessionProvider;
+
+public class JcrRemotingServlet extends
+ org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet {
+
+ private static final long serialVersionUID = 3131835511468341309L;
+
+ private final Repository repository;
+ private final SessionProvider sessionProvider;
+
+ public JcrRemotingServlet(Repository repository,
+ SessionProvider sessionProvider) {
+ this.repository = repository;
+ this.sessionProvider = sessionProvider;
+ }
+
+ @Override
+ protected Repository getRepository() {
+ return repository;
+ }
+
+ @Override
+ protected SessionProvider getSessionProvider() {
+ return sessionProvider;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.io.Serializable;
+
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.server.SessionProvider;
+import org.argeo.jcr.JcrUtils;
+
+/**
+ * Implements an open session in view patter: a new JCR session is created for
+ * each request
+ */
+public class OpenInViewSessionProvider implements SessionProvider, Serializable {
+ private static final long serialVersionUID = 2270957712453841368L;
+
+ private final static Log log = LogFactory
+ .getLog(OpenInViewSessionProvider.class);
+
+ public Session getSession(HttpServletRequest request, Repository rep,
+ String workspace) throws LoginException, ServletException,
+ RepositoryException {
+ return login(request, rep, workspace);
+ }
+
+ protected Session login(HttpServletRequest request, Repository repository,
+ String workspace) throws RepositoryException {
+ if (log.isTraceEnabled())
+ log.trace("Login to workspace "
+ + (workspace == null ? "<default>" : workspace)
+ + " in web session " + request.getSession().getId());
+ return repository.login(workspace);
+ }
+
+ public void releaseSession(Session session) {
+ JcrUtils.logoutQuietly(session);
+ if (log.isTraceEnabled())
+ log.trace("Logged out remote JCR session " + session);
+ }
+
+ public void init() {
+ }
+
+ public void destroy() {
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.io.Serializable;
+
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.server.SessionProvider;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.JcrUtils;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
+
+/**
+ * Session provider assuming a single workspace and a short life cycle,
+ * typically a Spring bean of scope (web) 'session'.
+ */
+public class ScopedSessionProvider implements SessionProvider, Serializable {
+ private static final long serialVersionUID = 6589775984177317058L;
+ private static final Log log = LogFactory
+ .getLog(ScopedSessionProvider.class);
+ private transient HttpSession httpSession = null;
+ private transient Session jcrSession = null;
+
+ private transient String currentRepositoryName = null;
+ private transient String currentWorkspaceName = null;
+ private transient String currentJcrUser = null;
+
+ // private transient String anonymousUserId = "anonymous";
+
+ public Session getSession(HttpServletRequest request, Repository rep,
+ String workspace) throws LoginException, ServletException,
+ RepositoryException {
+
+ Authentication authentication = SecurityContextHolder.getContext()
+ .getAuthentication();
+ if (authentication == null)
+ throw new ArgeoException(
+ "Request not authenticated by Spring Security");
+ String springUser = authentication.getName();
+
+ // HTTP
+ String requestJcrRepository = (String) request
+ .getAttribute(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
+
+ // HTTP session
+ if (httpSession != null
+ && !httpSession.getId().equals(request.getSession().getId()))
+ throw new ArgeoException(
+ "Only session scope is supported in this mode");
+ if (httpSession == null)
+ httpSession = request.getSession();
+
+ // Initializes current values
+ if (currentRepositoryName == null)
+ currentRepositoryName = requestJcrRepository;
+ if (currentWorkspaceName == null)
+ currentWorkspaceName = workspace;
+ if (currentJcrUser == null)
+ currentJcrUser = springUser;
+
+ // logout if there was a change in session coordinates
+ if (jcrSession != null)
+ if (!currentRepositoryName.equals(requestJcrRepository)) {
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " Changed from repository '"
+ + currentRepositoryName + "' to '"
+ + requestJcrRepository
+ + "', logging out cached JCR session.");
+ logout();
+ } else if (!currentWorkspaceName.equals(workspace)) {
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " Changed from workspace '"
+ + currentWorkspaceName + "' to '" + workspace
+ + "', logging out cached JCR session.");
+ logout();
+ } else if (!currentJcrUser.equals(springUser)) {
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " Changed from user '"
+ + currentJcrUser + "' to '" + springUser
+ + "', logging out cached JCR session.");
+ logout();
+ }
+
+ // login if needed
+ if (jcrSession == null)
+ try {
+ Session session = login(rep, workspace);
+ if (!session.getUserID().equals(springUser)) {
+ JcrUtils.logoutQuietly(session);
+ throw new ArgeoException("Spring Security user '"
+ + springUser + "' not in line with JCR user '"
+ + session.getUserID() + "'");
+ }
+ currentRepositoryName = requestJcrRepository;
+ // do not use workspace variable which may be null
+ currentWorkspaceName = session.getWorkspace().getName();
+ currentJcrUser = session.getUserID();
+
+ jcrSession = session;
+ return jcrSession;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot open session to workspace "
+ + workspace, e);
+ }
+
+ // returns cached session
+ return jcrSession;
+ }
+
+ protected Session login(Repository repository, String workspace)
+ throws RepositoryException {
+ Session session = repository.login(workspace);
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " User '" + session.getUserID()
+ + "' logged in workspace '"
+ + session.getWorkspace().getName() + "' of repository '"
+ + currentRepositoryName + "'");
+ return session;
+ }
+
+ public void releaseSession(Session session) {
+ if (log.isTraceEnabled())
+ log.trace(getHttpSessionId() + " Releasing JCR session " + session);
+ }
+
+ protected void logout() {
+ JcrUtils.logoutQuietly(jcrSession);
+ jcrSession = null;
+ }
+
+ protected final String getHttpSessionId() {
+ return httpSession != null ? httpSession.getId() : "<null>";
+ }
+
+ public void init() {
+ }
+
+ public void destroy() {
+ logout();
+ if (getHttpSessionId() != null)
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId()
+ + " Cleaned up provider for web session ");
+ httpSession = null;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.LoginException;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.server.SessionProvider;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+
+/**
+ * Implements an open session in view patter: a new JCR session is created for
+ * each request
+ *
+ * @deprecated use {@link ScopedSessionProvider} or
+ * {@link OpenInViewSessionProvider}
+ */
+@Deprecated
+public class SimpleSessionProvider implements SessionProvider, Serializable {
+ private static final long serialVersionUID = 2270957712453841368L;
+
+ private final static Log log = LogFactory
+ .getLog(SimpleSessionProvider.class);
+
+ private transient Map<String, Session> sessions;
+
+ private Boolean openSessionInView = true;
+
+ private String defaultWorkspace = "default";
+
+ private String webSessionId = null;
+
+ public Session getSession(HttpServletRequest request, Repository rep,
+ String workspace) throws LoginException, ServletException,
+ RepositoryException {
+
+ if (openSessionInView) {
+ JackrabbitSession session = (JackrabbitSession) login(request, rep,
+ workspace);
+ if (session.getWorkspace().getName().equals(defaultWorkspace))
+ writeRemoteRoles(session);
+ return session;
+ } else {
+ if (webSessionId != null
+ && !webSessionId.equals(request.getSession().getId()))
+ throw new ArgeoException(
+ "Only session scope is supported in this mode");
+ webSessionId = request.getSession().getId();
+
+ // since sessions is transient it can't be restored from the session
+ if (sessions == null)
+ sessions = Collections
+ .synchronizedMap(new HashMap<String, Session>());
+
+ if (!sessions.containsKey(workspace)) {
+ try {
+ // JackrabbitSession session = (JackrabbitSession)
+ // rep.login(
+ // null, workspace);
+ JackrabbitSession session = (JackrabbitSession) login(
+ request, rep, workspace);
+ if (session.getWorkspace().getName()
+ .equals(defaultWorkspace))
+ writeRemoteRoles(session);
+ if (log.isTraceEnabled())
+ log.trace("User " + session.getUserID()
+ + " logged into " + request.getServletPath());
+ sessions.put(workspace, session);
+ return session;
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot open session", e);
+ }
+ } else {
+ Session session = sessions.get(workspace);
+ if (!session.isLive()) {
+ sessions.remove(workspace);
+ session = login(request, rep, workspace);
+ sessions.put(workspace, session);
+ }
+ return session;
+ }
+ }
+ }
+
+ protected Session login(HttpServletRequest request, Repository repository,
+ String workspace) throws RepositoryException {
+ if (log.isDebugEnabled())
+ log.debug("Login to workspace "
+ + (workspace == null ? "<default>" : workspace)
+ + " in web session " + request.getSession().getId());
+ return repository.login(workspace);
+ }
+
+ protected void writeRemoteRoles(JackrabbitSession session)
+ throws RepositoryException {
+ // FIXME better deal w/ non node repo
+
+ // retrieve roles
+ String userId = session.getUserID();
+ UserManager userManager = session.getUserManager();
+ User user = (User) userManager.getAuthorizable(userId);
+ if (user == null) {
+ // anonymous
+ return;
+ }
+ List<String> userGroupIds = new ArrayList<String>();
+ if (user != null)
+ for (Iterator<Group> it = user.memberOf(); it.hasNext();)
+ userGroupIds.add(it.next().getID());
+
+ // write roles if needed
+ Node userHome = UserJcrUtils.getUserHome(session);
+ boolean writeRoles = false;
+ if (userHome.hasProperty(ArgeoNames.ARGEO_REMOTE_ROLES)) {
+ Value[] roles = userHome.getProperty(ArgeoNames.ARGEO_REMOTE_ROLES)
+ .getValues();
+ if (roles.length != userGroupIds.size())
+ writeRoles = true;
+ else
+ for (int i = 0; i < roles.length; i++)
+ if (!roles[i].getString().equals(userGroupIds.get(i)))
+ writeRoles = true;
+ } else
+ writeRoles = true;
+
+ if (writeRoles) {
+ session.getWorkspace().getVersionManager()
+ .checkout(userHome.getPath());
+ String[] roleIds = userGroupIds.toArray(new String[userGroupIds
+ .size()]);
+ userHome.setProperty(ArgeoNames.ARGEO_REMOTE_ROLES, roleIds);
+ JcrUtils.updateLastModified(userHome);
+ session.save();
+ session.getWorkspace().getVersionManager()
+ .checkin(userHome.getPath());
+ }
+
+ }
+
+ public void releaseSession(Session session) {
+ if (log.isTraceEnabled())
+ log.trace("Releasing JCR session " + session);
+ if (openSessionInView) {
+ JcrUtils.logoutQuietly(session);
+ if (log.isDebugEnabled())
+ log.debug("Logged out remote JCR session " + session);
+ }
+ }
+
+ public void init() {
+ if (log.isDebugEnabled())
+ log.debug("Init session provider for web session " + webSessionId);
+ }
+
+ public void destroy() {
+ if (log.isDebugEnabled())
+ log.debug("Destroy session provider for web session "
+ + webSessionId);
+
+ if (sessions != null)
+ for (String workspace : sessions.keySet()) {
+ Session session = sessions.get(workspace);
+ JcrUtils.logoutQuietly(session);
+ }
+ }
+
+ /**
+ * If set to true a new session will be created each time (the default),
+ * otherwise a single session is cached by workspace and the object should
+ * be of scope session (not supported)
+ */
+ public void setOpenSessionInView(Boolean openSessionInView) {
+ this.openSessionInView = openSessionInView;
+ }
+
+ public void setSecurityWorkspace(String securityWorkspace) {
+ this.defaultWorkspace = securityWorkspace;
+ }
+
+}
--- /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.jackrabbit.remote;
+
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+/** Handler mapping for WebDav */
+public class SimpleWebdavHandlerMapping extends
+ AbstractJackrabbitHandlerMapping {
+ private String configuration;
+
+ protected HttpServlet createServlet(Repository repository, String pathPrefix)
+ throws ServletException {
+
+ SimpleWebdavServlet servlet = new SimpleWebdavServlet(repository,
+ getSessionProvider());
+ Properties initParameters = new Properties();
+ initParameters.setProperty(
+ SimpleWebdavServlet.INIT_PARAM_RESOURCE_CONFIG, configuration);
+ initParameters
+ .setProperty(
+ SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
+ pathPrefix);
+ servlet.init(new DelegatingServletConfig(pathPrefix.replace('/', '_'),
+ initParameters));
+ return servlet;
+ }
+
+ public void setConfiguration(String configuration) {
+ this.configuration = configuration;
+ }
+}
--- /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.jackrabbit.remote;
+
+import java.io.IOException;
+
+import javax.jcr.Repository;
+import javax.servlet.ServletException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.server.SessionProvider;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.WebdavRequest;
+import org.apache.jackrabbit.webdav.WebdavResponse;
+
+/** WebDav servlet whose repository is injected */
+public class SimpleWebdavServlet extends
+ org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet {
+ private static final long serialVersionUID = -369787931175177080L;
+
+ private final static Log log = LogFactory.getLog(SimpleWebdavServlet.class);
+
+ private final Repository repository;
+
+ public SimpleWebdavServlet(Repository repository,
+ SessionProvider sessionProvider) {
+ this.repository = repository;
+ setSessionProvider(sessionProvider);
+ }
+
+ public Repository getRepository() {
+ return repository;
+ }
+
+ @Override
+ protected boolean execute(WebdavRequest request, WebdavResponse response,
+ int method, DavResource resource) throws ServletException,
+ IOException, DavException {
+ if (log.isTraceEnabled())
+ log.trace(request.getMethod() + "\t" + request.getPathInfo());
+ boolean res = super.execute(request, response, method, resource);
+ return res;
+ }
+
+}
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
+ "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<Repository>
+ <!-- File system and datastore -->
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/fs" />
+ </FileSystem>
+ <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
+ <param name="path" value="${rep.home}/datastore" />
+ </DataStore>
+
+ <!-- Workspace templates -->
+ <Workspaces rootPath="${rep.home}/workspaces"
+ defaultWorkspace="${argeo.node.repo.defaultWorkspace}" />
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${wsp.home}" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager" />
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index" />
+ </SearchIndex>
+ </Workspace>
+
+ <!-- Versioning -->
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/version" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager" />
+ </Versioning>
+
+ <!-- Indexing -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/index" />
+ <param name="extractorPoolSize" value="2" />
+ <param name="supportHighlighting" value="true" />
+ </SearchIndex>
+
+ <!-- Security -->
+ <Security appName="Jackrabbit">
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+ workspaceName="security">
+ </SecurityManager>
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
+ </AccessManager>
+ <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
+ </LoginModule>
+ </Security>
+</Repository>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
+ "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<Repository>
+ <!-- Shared datasource -->
+ <DataSources>
+ <DataSource name="dataSource">
+ <param name="driver" value="org.h2.Driver" />
+ <param name="url" value="jdbc:h2:${rep.home}/h2/repository" />
+ <param name="user" value="sa" />
+ <param name="password" value="" />
+ <param name="databaseType" value="h2" />
+ <param name="maxPoolSize" value="10" />
+ </DataSource>
+ </DataSources>
+
+ <!-- File system and datastore -->
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="default" />
+ <param name="schemaObjectPrefix" value="fs_" />
+ </FileSystem>
+ <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
+ <param name="path" value="${rep.home}/datastore" />
+ </DataStore>
+
+ <!-- Workspace templates -->
+ <Workspaces rootPath="${rep.home}/workspaces"
+ defaultWorkspace="main" />
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="default" />
+ <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
+ </PersistenceManager>
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index" />
+ </SearchIndex>
+ </Workspace>
+
+ <!-- Versioning -->
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="default" />
+ <param name="schemaObjectPrefix" value="fs_ver_" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schemaObjectPrefix" value="pm_ver_" />
+ </PersistenceManager>
+ </Versioning>
+
+ <!-- Indexing -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/index" />
+ <param name="extractorPoolSize" value="2" />
+ <param name="supportHighlighting" value="true" />
+ </SearchIndex>
+
+ <!-- Security -->
+ <Security appName="Jackrabbit">
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+ workspaceName="security">
+ </SecurityManager>
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
+ </AccessManager>
+ <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
+ </LoginModule>
+ </Security>
+</Repository>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
+ "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<Repository>
+ <!-- File system and datastore -->
+ <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+
+ <!-- Workspace templates -->
+ <Workspaces rootPath="${rep.home}/workspaces"
+ defaultWorkspace="main" configRootPath="/workspaces" />
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+ <param name="blobFSBlockSize" value="1" />
+ </PersistenceManager>
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/repository/index" />
+ <param name="directoryManagerClass"
+ value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+ <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+ </SearchIndex>
+ </Workspace>
+
+ <!-- Versioning -->
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+ <param name="blobFSBlockSize" value="1" />
+ </PersistenceManager>
+ </Versioning>
+
+ <!-- Indexing -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/repository/index" />
+ <param name="directoryManagerClass"
+ value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+ <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+ </SearchIndex>
+
+ <!-- Security -->
+ <Security appName="Jackrabbit">
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+ workspaceName="security">
+ </SecurityManager>
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
+ </AccessManager>
+ <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
+ </LoginModule>
+ </Security>
+</Repository>
\ No newline at end of file
--- /dev/null
+Web-ContextPath: ui
+Import-Package: org.springframework.beans.factory.config,\
+org.eclipse.equinox.http.servlet,\
+org.springframework.osgi.web.context.support,\
+org.springframework.security,\
+org.springframework.security.context,\
+org.springframework.security.intercept.web,\
+org.springframework.security.providers.anonymous,\
+org.springframework.security.ui,\
+org.springframework.security.ui.basicauth,\
+org.springframework.security.ui.logout,\
+org.springframework.security.ui.rememberme,\
+org.springframework.security.ui.webapp,\
+org.springframework.security.ui.preauth.x509,\
+org.springframework.security.userdetails,\
+org.springframework.security.util,\
+org.springframework.security.vote,\
+org.springframework.security.wrapper,\
+org.springframework.web.context,\
+org.springframework.web.filter,\
+org.springframework.web.servlet,\
+org.springframework.web.servlet.handler,\
+org.springframework.web.servlet.mvc,\
+*
\ No newline at end of file
<artifactId>org.argeo.server.rap.webapp</artifactId>
<name>Commons Server RAP Webapp</name>
<description>Integrates into OSGi HTTP registry</description>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Web-ContextPath>ui</Web-ContextPath>
- <Import-Package>
- *,
-
- org.springframework.beans.factory.config,
-
- org.eclipse.equinox.http.servlet,
- org.springframework.osgi.web.context.support,
- org.springframework.security,
- org.springframework.security.context,
- org.springframework.security.intercept.web,
- org.springframework.security.providers.anonymous,
- org.springframework.security.ui,
- org.springframework.security.ui.basicauth,
- org.springframework.security.ui.logout,
- org.springframework.security.ui.rememberme,
- org.springframework.security.ui.webapp,
- org.springframework.security.ui.preauth.x509,
- org.springframework.security.userdetails,
- org.springframework.security.util,
- org.springframework.security.vote,
- org.springframework.security.wrapper,
- org.springframework.web.context,
- org.springframework.web.filter,
- org.springframework.web.servlet,
- org.springframework.web.servlet.handler,
- org.springframework.web.servlet.mvc,
-
-
- </Import-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
</project>
\ No newline at end of file