--- /dev/null
+package org.argeo.eclipse.ui.jcr;
+
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
+import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
+import org.argeo.eclipse.ui.jcr.lists.RowViewerComparator;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Table;
+
+/** Utility methods to simplify UI development using eclipse and JCR. */
+public class JcrUiUtils {
+
+ /**
+ * Centralizes management of updating property value. Among other to avoid
+ * infinite loop when the new value is the same as the ones that is already
+ * stored in JCR.
+ *
+ * @return true if the value as changed
+ */
+ public static boolean setJcrProperty(Node node, String propName,
+ int propertyType, Object value) {
+ try {
+ // int propertyType = getPic().getProperty(propName).getType();
+ switch (propertyType) {
+ case PropertyType.STRING:
+ if ("".equals((String) value)
+ && (!node.hasProperty(propName) || node
+ .hasProperty(propName)
+ && "".equals(node.getProperty(propName)
+ .getString())))
+ // workaround the fact that the Text widget value cannot be
+ // set to null
+ return false;
+ else if (node.hasProperty(propName)
+ && node.getProperty(propName).getString()
+ .equals((String) value))
+ // nothing changed yet
+ return false;
+ else {
+ node.setProperty(propName, (String) value);
+ return true;
+ }
+ case PropertyType.BOOLEAN:
+ if (node.hasProperty(propName)
+ && node.getProperty(propName).getBoolean() == (Boolean) value)
+ // nothing changed yet
+ return false;
+ else {
+ node.setProperty(propName, (Boolean) value);
+ return true;
+ }
+ case PropertyType.DATE:
+ if (node.hasProperty(propName)
+ && node.getProperty(propName).getDate()
+ .equals((Calendar) value))
+ // nothing changed yet
+ return false;
+ else {
+ node.setProperty(propName, (Calendar) value);
+ return true;
+ }
+ case PropertyType.LONG:
+ Long lgValue = (Long) value;
+
+ if (lgValue == null)
+ lgValue = 0L;
+
+ if (node.hasProperty(propName)
+ && node.getProperty(propName).getLong() == lgValue)
+ // nothing changed yet
+ return false;
+ else {
+ node.setProperty(propName, lgValue);
+ return true;
+ }
+
+ default:
+ throw new ArgeoException("Unimplemented property save");
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unexpected error while setting property",
+ re);
+ }
+ }
+
+ /**
+ * Creates a new selection adapter in order to provide sorting abitily on a
+ * swt table that display a row list
+ **/
+ public static SelectionAdapter getRowSelectionAdapter(final int index,
+ final int propertyType, final String selectorName,
+ final String propertyName, final RowViewerComparator comparator,
+ final TableViewer viewer) {
+ SelectionAdapter selectionAdapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Table table = viewer.getTable();
+ comparator.setColumn(propertyType, selectorName, propertyName);
+ int dir = table.getSortDirection();
+ if (table.getSortColumn() == table.getColumn(index)) {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ } else {
+ dir = SWT.DOWN;
+ }
+ table.setSortDirection(dir);
+ table.setSortColumn(table.getColumn(index));
+ viewer.refresh();
+ }
+ };
+ return selectionAdapter;
+ }
+
+ /**
+ * Creates a new selection adapter in order to provide sorting abitily on a
+ * swt table that display a row list
+ **/
+ public static SelectionAdapter getNodeSelectionAdapter(final int index,
+ final int propertyType, final String propertyName,
+ final NodeViewerComparator comparator, final TableViewer viewer) {
+ SelectionAdapter selectionAdapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Table table = viewer.getTable();
+ comparator.setColumn(propertyType, propertyName);
+ int dir = table.getSortDirection();
+ if (table.getSortColumn() == table.getColumn(index)) {
+ dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
+ } else {
+ dir = SWT.DOWN;
+ }
+ table.setSortDirection(dir);
+ table.setSortColumn(table.getColumn(index));
+ viewer.refresh();
+ }
+ };
+ return selectionAdapter;
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.jcr.lists;
+
+/**
+ * Utility object to manage column in various tables and extracts displaying
+ * data from JCR
+ */
+public class ColumnDefinition {
+ private final static int DEFAULT_COLUMN_SIZE = 120;
+
+ private String selectorName;
+ private String propertyName;
+ private String headerLabel;
+ private int propertyType;
+ private int columnSize = DEFAULT_COLUMN_SIZE;
+
+ /**
+ * new column using default width
+ *
+ * @param selectorName
+ * @param propertyName
+ * @param propertyType
+ * @param headerLabel
+ */
+ public ColumnDefinition(String selectorName, String propertyName,
+ int propertyType, String headerLabel) {
+ this.selectorName = selectorName;
+ this.propertyName = propertyName;
+ this.propertyType = propertyType;
+ this.headerLabel = headerLabel;
+ }
+
+ /**
+ *
+ * @param selectorName
+ * @param propertyName
+ * @param propertyType
+ * @param headerLabel
+ * @param columnSize
+ */
+ public ColumnDefinition(String selectorName, String propertyName,
+ int propertyType, String headerLabel, int columnSize) {
+ this.selectorName = selectorName;
+ this.propertyName = propertyName;
+ this.propertyType = propertyType;
+ this.headerLabel = headerLabel;
+ this.columnSize = columnSize;
+ }
+
+ public String getSelectorName() {
+ return selectorName;
+ }
+
+ public void setSelectorName(String selectorName) {
+ this.selectorName = selectorName;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public String getHeaderLabel() {
+ return headerLabel;
+ }
+
+ public void setHeaderLabel(String headerLabel) {
+ this.headerLabel = headerLabel;
+ }
+
+ public int getPropertyType() {
+ return propertyType;
+ }
+
+ public void setPropertyType(int propertyType) {
+ this.propertyType = propertyType;
+ }
+
+ public int getColumnSize() {
+ return columnSize;
+ }
+
+ public void setColumnSize(int columnSize) {
+ this.columnSize = columnSize;
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.jcr.lists;
+
+import java.util.List;
+
+/**
+ * Views and editors can implement this interface so that one of the row list
+ * that is displayed in the part (For instance in a Table or a Tree Viewer) can
+ * be rebuilt externally. typically to generate csv or calc extract.
+ */
+public interface IListProvider {
+ /**
+ * Returns an array of current and relevant elements
+ */
+ public Object[] getElements(String extractId);
+
+ /**
+ * Returns the column definition for passed ID
+ */
+ public List<ColumnDefinition> getColumnDefinition(String extractId);
+}
--- /dev/null
+package org.argeo.eclipse.ui.jcr.lists;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * Base comparator to enable ordering on Table or Tree viewer that display Jcr
+ * Nodes.
+ *
+ * Note that the following snippet must be added before setting the comparator
+ * to the corresponding control: <code>
+ * // IMPORTANT: initialize comparator before setting it
+ * ColumnDefinition firstCol = colDefs.get(0);
+ * comparator.setColumn(firstCol.getPropertyType(),
+ * firstCol.getPropertyName());
+ * viewer.setComparator(comparator); </code>
+ */
+public class NodeViewerComparator extends ViewerComparator {
+
+ protected String propertyName;
+
+ protected int propertyType;
+ public static final int ASCENDING = 0, DESCENDING = 1;
+ protected int direction = DESCENDING;
+
+ public NodeViewerComparator() {
+ }
+
+ /**
+ * e1 and e2 must both be Jcr nodes.
+ *
+ * @param viewer
+ * @param e1
+ * @param e2
+ * @return
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ int rc = 0;
+ long lc = 0;
+
+ try {
+
+ Node n1 = (Node) e1;
+ Node n2 = (Node) e2;
+
+ Value v1 = null;
+ Value v2 = null;
+ if (n1.hasProperty(propertyName))
+ v1 = n1.getProperty(propertyName).getValue();
+ if (n2.hasProperty(propertyName))
+ v2 = n2.getProperty(propertyName).getValue();
+
+ if (v2 == null && v1 == null)
+ return 0;
+ else if (v2 == null)
+ return -1;
+ else if (v1 == null)
+ return 1;
+
+ switch (propertyType) {
+ case PropertyType.STRING:
+ rc = v1.getString().compareTo(v2.getString());
+ break;
+ case PropertyType.BOOLEAN:
+ boolean b1 = v1.getBoolean();
+ boolean b2 = v2.getBoolean();
+ if (b1 == b2)
+ rc = 0;
+ else
+ // we assume true is greater than false
+ rc = b1 ? 1 : -1;
+ break;
+ case PropertyType.DATE:
+ Calendar c1 = v1.getDate();
+ Calendar c2 = v2.getDate();
+ if (c1 == null || c2 == null)
+ // log.trace("undefined date");
+ ;
+ lc = c1.getTimeInMillis() - c2.getTimeInMillis();
+ if (lc < Integer.MIN_VALUE)
+ // rc = Integer.MIN_VALUE;
+ rc = -1;
+ else if (lc > Integer.MAX_VALUE)
+ // rc = Integer.MAX_VALUE;
+ rc = 1;
+ else
+ rc = (int) lc;
+ break;
+ case PropertyType.LONG:
+ long l1;
+ long l2;
+ // FIXME sometimes an empty string is set instead of a long
+ try {
+ l1 = v1.getLong();
+ } catch (ValueFormatException ve) {
+ l1 = 0;
+ }
+ try {
+ l2 = v2.getLong();
+ } catch (ValueFormatException ve) {
+ l2 = 0;
+ }
+
+ lc = l1 - l2;
+ if (lc < Integer.MIN_VALUE)
+ rc = -1;
+ else if (lc > Integer.MAX_VALUE)
+ rc = 1;
+ else
+ rc = (int) lc;
+ break;
+ case PropertyType.DECIMAL:
+ BigDecimal bd1 = v1.getDecimal();
+ BigDecimal bd2 = v2.getDecimal();
+ rc = bd1.compareTo(bd2);
+ break;
+ case PropertyType.DOUBLE:
+ Double d1 = v1.getDouble();
+ Double d2 = v2.getDouble();
+ rc = d1.compareTo(d2);
+ break;
+ default:
+ throw new ArgeoException(
+ "Unimplemented comparaison for PropertyType "
+ + propertyType);
+ }
+ // If descending order, flip the direction
+ if (direction == DESCENDING) {
+ rc = -rc;
+ }
+
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unexpected error "
+ + "while comparing nodes", re);
+ }
+ return rc;
+ }
+
+ /**
+ * @param propertyType
+ * Corresponding JCR type
+ * @param propertyName
+ * name of the property to use.
+ */
+ public void setColumn(int propertyType, String propertyName) {
+ if (this.propertyName != null && this.propertyName.equals(propertyName)) {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ } else {
+ // New column; do an ascending sort
+ this.propertyType = propertyType;
+ this.propertyName = propertyName;
+ direction = ASCENDING;
+ }
+ }
+
+ // Getters and setters
+ protected String getPropertyName() {
+ return propertyName;
+ }
+
+ protected void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ protected int getPropertyType() {
+ return propertyType;
+ }
+
+ protected void setPropertyType(int propertyType) {
+ this.propertyType = propertyType;
+ }
+
+ protected int getDirection() {
+ return direction;
+ }
+
+ protected void setDirection(int direction) {
+ this.direction = direction;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.jcr.lists;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.query.Row;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Base comparator to enable ordering on Table or Tree viewer that display Jcr
+ * rows
+ */
+public class RowViewerComparator extends NodeViewerComparator {
+
+ protected String selectorName;
+
+ public RowViewerComparator() {
+ }
+
+ /**
+ * e1 and e2 must both be Jcr rows.
+ *
+ * @param viewer
+ * @param e1
+ * @param e2
+ * @return
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ try {
+ Node n1 = ((Row) e1).getNode(selectorName);
+ Node n2 = ((Row) e2).getNode(selectorName);
+ return super.compare(viewer, n1, n2);
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unexpected error "
+ + "while comparing nodes", re);
+ }
+ }
+
+ /**
+ * @param propertyType
+ * Corresponding JCR type
+ * @param propertyName
+ * name of the property to use.
+ */
+ public void setColumn(int propertyType, String selectorName,
+ String propertyName) {
+ if (this.selectorName != null && getPropertyName() != null
+ && this.selectorName.equals(selectorName)
+ && this.getPropertyName().equals(propertyName)) {
+ // Same column as last sort; toggle the direction
+ setDirection(1 - getDirection());
+ } else {
+ // New column; do a descending sort
+ setPropertyType(propertyType);
+ setPropertyName(propertyName);
+ this.selectorName = selectorName;
+ setDirection(NodeViewerComparator.ASCENDING);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.jcr.lists;
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.argeo.ArgeoException;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+/**
+ * Base implementation of a label provider for widgets that display JCR Rows.
+ */
+public class SimpleJcrNodeLabelProvider extends ColumnLabelProvider {
+
+ private final static String DEFAULT_DATE_FORMAT = "EEE, dd MMM yyyy";
+ private final static String DEFAULT_NUMBER_FORMAT = "#,##0.0";
+
+ private DateFormat dateFormat;
+ private NumberFormat numberFormat;
+
+ final private String propertyName;
+
+ /**
+ * Default Label provider for a given property of a node. Using default
+ * pattern for date and number formating
+ */
+ public SimpleJcrNodeLabelProvider(String propertyName) {
+ this.propertyName = propertyName;
+ dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
+ numberFormat = DecimalFormat.getInstance();
+ ((DecimalFormat) numberFormat).applyPattern(DEFAULT_NUMBER_FORMAT);
+ }
+
+ /**
+ * Label provider for a given property of a node optionally precising date
+ * and/or number format patterns
+ */
+ public SimpleJcrNodeLabelProvider(String propertyName,
+ String dateFormatPattern, String numberFormatPattern) {
+ this.propertyName = propertyName;
+ dateFormat = new SimpleDateFormat(
+ dateFormatPattern == null ? DEFAULT_DATE_FORMAT
+ : dateFormatPattern);
+ numberFormat = DecimalFormat.getInstance();
+ ((DecimalFormat) numberFormat)
+ .applyPattern(numberFormatPattern == null ? DEFAULT_NUMBER_FORMAT
+ : numberFormatPattern);
+ }
+
+ @Override
+ public String getText(Object element) {
+ try {
+ Node currNode = (Node) element;
+
+ Value value = null;
+ if (currNode.hasProperty(propertyName))
+ value = currNode.getProperty(propertyName).getValue();
+ else
+ return "";
+
+ switch (value.getType()) {
+ case PropertyType.STRING:
+ return value.getString();
+ case PropertyType.BOOLEAN:
+ return "" + value.getBoolean();
+ case PropertyType.DATE:
+ return dateFormat.format(value.getDate().getTime());
+ case PropertyType.LONG:
+ return "" + value.getLong();
+ case PropertyType.DECIMAL:
+ return numberFormat.format(value.getDecimal());
+ case PropertyType.DOUBLE:
+ return numberFormat.format(value.getDouble());
+ default:
+ throw new ArgeoException("Unimplemented label provider "
+ + "for property type " + value.getType());
+ }
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unable to get text from row", re);
+ }
+ }
+
+ public void setDateFormat(String dateFormatPattern) {
+ dateFormat = new SimpleDateFormat(dateFormatPattern);
+ }
+
+ public void setNumberFormat(String numberFormatPattern) {
+ ((DecimalFormat) numberFormat).applyPattern(numberFormatPattern);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.jcr.lists;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.query.Row;
+
+import org.argeo.ArgeoException;
+
+/**
+ * Base implementation of a label provider for widgets that display JCR Rows.
+ */
+public class SimpleJcrRowLabelProvider extends SimpleJcrNodeLabelProvider {
+
+ final private String selectorName;
+
+ /**
+ * Default Label provider for a given property of a row. Using default
+ * pattern for date and number formating
+ */
+ public SimpleJcrRowLabelProvider(String selectorName, String propertyName) {
+ super(propertyName);
+ this.selectorName = selectorName;
+ }
+
+ /**
+ * Label provider for a given property of a node optionally precising date
+ * and/or number format patterns
+ */
+ public SimpleJcrRowLabelProvider(String selectorName, String propertyName,
+ String dateFormatPattern, String numberFormatPattern) {
+ super(propertyName, dateFormatPattern, numberFormatPattern);
+ this.selectorName = selectorName;
+ }
+
+ @Override
+ public String getText(Object element) {
+ try {
+ Row currRow = (Row) element;
+ Node currNode = currRow.getNode(selectorName);
+ return super.getText(currNode);
+ } catch (RepositoryException re) {
+ throw new ArgeoException("Unable to get text from row", re);
+ }
+ }
+}
\ No newline at end of file
#log4j.logger.org.apache.commons.exec=DEBUG
#log4j.logger.org.apache.jackrabbit.webdav=DEBUG
#log4j.logger.org.apache.jackrabbit.remote=DEBUG
+#log4j.logger.org.apache.jackrabbit.core.observation=DEBUG
log4j.logger.org.apache.catalina=INFO
log4j.logger.org.apache.coyote=INFO
scope="prototype">
<property name="userAdminService" ref="userAdminService" />
</bean>
+
+ <bean id="userBatchUpdate" class="org.argeo.security.ui.admin.commands.UserBatchUpdate"
+ scope="prototype">
+ <property name="repository" ref="nodeRepository" />
+ <property name="userAdminService" ref="userAdminService" />
+ <property name="jcrSecurityModel" ref="jcrSecurityModel" />
+ </bean>
+
<!-- ROLES -->
<bean id="refreshRoles" class="org.argeo.security.ui.admin.commands.RefreshRoles"
id="org.argeo.security.ui.admin.deleteRole"
name="deleteRole">
</command>
+ <command
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ id="org.argeo.security.ui.admin.userBatchUpdate"
+ name="User batch update">
+ </command>
</extension>
<extension
point="org.eclipse.ui.menus">
</menuContribution>
<menuContribution
locationURI="toolbar:org.argeo.security.ui.admin.adminUsersView">
+ <command
+ commandId="org.argeo.security.ui.admin.refreshUsersList"
+ icon="icons/refresh.png"
+ label="Refresh list"
+ tooltip="Force the full refresh of the user list">
+ </command>
<command
commandId="org.argeo.security.ui.admin.deleteUser"
icon="icons/remove.gif"
label="Add User"
tooltip="Add new user">
</command>
+ <command
+ commandId="org.argeo.security.ui.admin.userBatchUpdate"
+ icon="icons/batch.gif"
+ label="Update users"
+ tooltip="Perform maintenance activities on a list of chosen users">
+ </command>
<command
commandId="org.argeo.security.ui.admin.refreshUsersList"
icon="icons/sync.gif"
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.argeo.commons.security</groupId>
</build>
<dependencies>
<!-- Argeo Security -->
+ <dependency>
+ <groupId>org.argeo.commons.security</groupId>
+ <artifactId>org.argeo.security.ui</artifactId>
+ <version>2.1.3-SNAPSHOT</version>
+ </dependency>
+
<dependency>
<groupId>org.argeo.commons.security</groupId>
<artifactId>org.argeo.security.core</artifactId>
</dependency>
<!-- Argeo Eclipse -->
+ <dependency>
+ <groupId>org.argeo.commons.base</groupId>
+ <artifactId>org.argeo.eclipse.ui.jcr</artifactId>
+ <version>2.1.3-SNAPSHOT</version>
+ </dependency>
+
<dependency>
<groupId>org.argeo.commons.base</groupId>
<artifactId>org.argeo.eclipse.ui</artifactId>
--- /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
+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 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;
+ }
+
+ 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) {
+ if (hasSelectionColumn) {
+ offset = 1;
+ column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE,
+ 25);
+ // column.setEditingSupport(new SelectedEditingSupport(viewer));
+ column.setLabelProvider(new ColumnLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ return null;
+ }
+ });
+ SelectionAdapter selectionAdapter = new SelectionAdapter() {
+ 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 SelectedEditingSupport extends EditingSupport {
+ // private final TableViewer viewer;
+ //
+ // public SelectedEditingSupport(TableViewer viewer) {
+ // super(viewer);
+ // this.viewer = viewer;
+ // }
+ //
+ // @Override
+ // protected CellEditor getCellEditor(Object element) {
+ // return new CheckboxCellEditor(viewer.getTable());
+ // }
+ //
+ // @Override
+ // protected boolean canEdit(Object element) {
+ // return true;
+ // }
+ //
+ // @Override
+ // protected Object getValue(Object element) {
+ // return selectedItems.contains(element);
+ // }
+ //
+ // @Override
+ // protected void setValue(Object element, Object value) {
+ // if ((Boolean) value && !selectedItems.contains(element))
+ // selectedItems.add((Node) element);
+ // else if (!(Boolean) value && selectedItems.contains(element))
+ // selectedItems.remove((Node) element);
+ // viewer.update(element, null);
+ // }
+ // }
+
+ private class CLProvider extends SimpleJcrNodeLabelProvider {
+
+ 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 {
+
+ 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() {
+
+ public void modifyText(ModifyEvent event) {
+ refreshFilteredList();
+ }
+ });
+ }
+
+ /**
+ * Refresh the user list: caller might overwrite in order to display a
+ * subset of all users
+ */
+ protected void refreshFilteredList() {
+ // if (hasSelectionColumn)
+ // selectedItems.clear();
+
+ 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);
+ }
+ }
+
+ // /**
+ // * Enable a children class to directly set an array of users to the
+ // viewer,
+ // * when such a behaviour cannot be achieved by overwriting the
+ // * refreshFilteredList() method
+ // */
+ // protected void setFilteredList(Object[] nodes) {
+ // // if (hasSelectionColumn)
+ // // selectedItems.clear();
+ // usersViewer.setInput(nodes);
+ // }
+
+ /**
+ * 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);
+
+ // // Create a dynamic operand for each property on which we want to
+ // filter
+ // DynamicOperand userIdDO = factory.propertyValue(
+ // source.getSelectorName(), ARGEO_USER_ID);
+ // DynamicOperand fullNameDO = factory.propertyValue(
+ // source.getSelectorName(), Property.JCR_TITLE);
+ // DynamicOperand mailDO =
+ // factory.propertyValue(source.getSelectorName(),
+ // ARGEO_PRIMARY_EMAIL);
+
+ // Default Constraint: no source artifacts
+ Constraint defaultC = null;
+ // Build constraints based the textArea content
+ if (filter != null && !"".equals(filter.trim())) {
+ // Parse the String
+ 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
import org.argeo.jcr.ArgeoNames;
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.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
-/** Deletes the select user nodes */
+/** Deletes the selected user nodes */
public class DeleteUser extends AbstractHandler {
private final static Log log = LogFactory.getLog(DeleteUser.class);
}
userAdminService.synchronize();
- UsersView view = (UsersView) HandlerUtil
- .getActiveWorkbenchWindow(event).getActivePage()
- .findView(UsersView.ID);
- view.refresh();
+ // UsersView view = (UsersView) HandlerUtil
+ // .getActiveWorkbenchWindow(event).getActivePage()
+ // .findView(UsersView.ID);
+ // view.refresh();
return null;
}
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.handlers.HandlerUtil;
-/** Command handler to set visible or open a Argeo user. */
+/** Launch a wizard that enables creation of a new user. */
public class NewUser extends AbstractHandler {
private Repository repository;
private UserAdminService userAdminService;
import org.eclipse.ui.handlers.HandlerUtil;
/**
- * Refreshes the main EBI list, removing nodes which are not referenced by user
+ * Refreshes the main user list, removing nodes which are not referenced by user
* admin service.
*/
public class RefreshUsersList extends AbstractHandler {
--- /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;
+ }
+
+}
*/
package org.argeo.security.ui.admin.views;
-import java.util.ArrayList;
-import java.util.List;
-
import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
-import javax.jcr.query.QueryManager;
-import javax.jcr.query.QueryResult;
-import javax.jcr.query.qom.Constraint;
-import javax.jcr.query.qom.DynamicOperand;
-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.specific.EclipseUiSpecificUtils;
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.ColumnLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
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.events.SelectionListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;
-/** List all users. */
+/** List all users with filter. */
public class UsersView extends ViewPart implements ArgeoNames {
public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+ ".adminUsersView";
- private TableViewer viewer;
- private Text filterTxt;
- private final static String FILTER_HELP_MSG = "Type filter criterion "
- + "separated by a space (on user ID, name and E-mail)";
- private final static Image FILTER_RESET = SecurityAdminPlugin
- .getImageDescriptor("icons/clear.gif").createImage();
-
+ private UserTableComposite userTableCmp;
private Session session;
-
- private UserStructureListener userStructureListener;
- private UserPropertiesListener userPropertiesListener;
-
- private Font italic;
- private Font bold;
+ private JcrUserListener userStructureListener;
+ private JcrUserListener userPropertiesListener;
@Override
public void createPartControl(Composite parent) {
- italic = EclipseUiUtils.getItalicFont(parent);
- bold = EclipseUiUtils.getBoldFont(parent);
+ parent.setLayout(new FillLayout());
- // Main Layout
- GridLayout layout = new GridLayout(1, false);
- parent.setLayout(layout);
- createFilterPart(parent);
+ // Create the composite that displays the list and a filter
+ userTableCmp = new UserTableComposite(parent, SWT.NO_FOCUS, session);
+ userTableCmp.populate(true, false);
- viewer = createTableViewer(parent);
- EclipseUiSpecificUtils.enableToolTipSupport(viewer);
- viewer.setContentProvider(new UsersContentProvider());
- viewer.addDoubleClickListener(new ViewDoubleClickListener());
- getViewSite().setSelectionProvider(viewer);
+ // Configure
+ userTableCmp.getTableViewer().addDoubleClickListener(
+ new ViewDoubleClickListener());
+ getViewSite().setSelectionProvider(userTableCmp.getTableViewer());
- userStructureListener = new UserStructureListener();
+ // 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 UserPropertiesListener();
+ 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);
-
- refreshFilteredList();
- }
-
- protected TableViewer createTableViewer(final Composite parent) {
-
- Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
- GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false);
- gd.grabExcessHorizontalSpace = true;
- gd.grabExcessVerticalSpace = true;
- table.setLayoutData(gd);
-
- TableViewer 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>();
-
- // User ID
- TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setText("User ID");
- column.getColumn().setWidth(100);
- column.getColumn().addSelectionListener(getSelectionAdapter(0));
- propertiesList.add(ARGEO_USER_ID);
- column.setLabelProvider(new CLProvider() {
- public String getText(Object elem) {
- return getProperty(elem, ARGEO_USER_ID);
- // if (username.equals(session.getUserID()))
- // return "[" + username + "]";
- // else
- // return username;
- }
- });
-
- // Displayed name
- column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setText("Name");
- column.getColumn().setWidth(150);
- column.getColumn().addSelectionListener(getSelectionAdapter(1));
- propertiesList.add(Property.JCR_TITLE);
- column.setLabelProvider(new CLProvider() {
- public String getText(Object elem) {
- return getProperty(elem, Property.JCR_TITLE);
- }
- });
-
- // E-mail
- column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setText("E-mail");
- column.getColumn().setWidth(150);
- column.getColumn().addSelectionListener(getSelectionAdapter(2));
- propertiesList.add(ARGEO_PRIMARY_EMAIL);
- column.setLabelProvider(new CLProvider() {
- public String getText(Object elem) {
- return getProperty(elem, ARGEO_PRIMARY_EMAIL);
- }
- });
-
- // Description
- column = new TableViewerColumn(viewer, SWT.NONE);
- column.getColumn().setText("Description");
- column.getColumn().setWidth(200);
- column.getColumn().addSelectionListener(getSelectionAdapter(3));
- propertiesList.add(Property.JCR_DESCRIPTION);
- column.setLabelProvider(new CLProvider() {
- public String getText(Object elem) {
- return getProperty(elem, Property.JCR_DESCRIPTION);
- }
- });
-
- viewer.setComparator(new UsersViewerComparator(propertiesList));
-
- return viewer;
- }
-
- private class CLProvider extends ColumnLabelProvider {
-
- 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);
- }
- }
-
- }
-
- private SelectionAdapter getSelectionAdapter(final int index) {
- SelectionAdapter selectionAdapter = new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- UsersViewerComparator comparator = (UsersViewerComparator) viewer
- .getComparator();
-
- if (index == comparator.getSortColumn()) {
- comparator.setAscending(!comparator.isAscending());
- }
- comparator.setSortColumn(index);
- viewer.getTable().setSortColumn(
- viewer.getTable().getColumn(index));
- viewer.getTable().setSortDirection(
- comparator.isAscending() ? SWT.UP : SWT.DOWN);
- viewer.refresh(false);
- }
- };
- return selectionAdapter;
- }
-
- private class UsersViewerComparator extends ViewerComparator {
-
- private List<String> propertyList;
- private int sortColumn = 0;
- private boolean ascending = true;
- // use this to enable two levels sort
- @SuppressWarnings("unused")
- private int lastSortColumn = 0;
- @SuppressWarnings("unused")
- private boolean lastAscending = true;
-
- public UsersViewerComparator(List<String> propertyList) {
- super();
- this.propertyList = propertyList;
- }
-
- public int compare(Viewer viewer, Object e1, Object e2) {
- String s1 = getProperty(e1, propertyList.get(sortColumn));
- String s2 = getProperty(e2, propertyList.get(sortColumn));
- int result = super.compare(viewer, s1, s2);
- return ascending ? result : (-1) * result;
- }
-
- /**
- * @return Returns the sortColumn.
- */
- public int getSortColumn() {
- return sortColumn;
- }
-
- /**
- * @param sortColumn
- * The sortColumn to set.
- */
- public void setSortColumn(int sortColumn) {
- if (this.sortColumn != sortColumn) {
- lastSortColumn = this.sortColumn;
- lastAscending = this.ascending;
- this.sortColumn = sortColumn;
- }
- }
-
- /**
- * @return Returns the ascending.
- */
- public boolean isAscending() {
- return ascending;
- }
-
- /**
- * @param ascending
- * The ascending to set.
- */
- public void setAscending(boolean ascending) {
- this.ascending = ascending;
- }
}
@Override
public void setFocus() {
- viewer.getTable().setFocus();
+ userTableCmp.setFocus();
}
@Override
}
public void refresh() {
- // viewer.refresh();
- refreshFilteredList();
- }
-
- protected String getProperty(Node userProfile, String name)
- throws RepositoryException {
- return userProfile.hasProperty(name) ? userProfile.getProperty(name)
- .getString() : "";
- }
-
- protected String getProperty(Object element, String name) {
- try {
- Node userProfile = (Node) element;
- // Node userProfile = userHome.getNode(ARGEO_PROFILE);
- return userProfile.hasProperty(name) ? userProfile
- .getProperty(name).getString() : "";
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot get property " + name, e);
- }
+ this.getSite().getShell().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ userTableCmp.refresh();
+ }
+ });
}
- private class UserStructureListener implements EventListener {
+ private class JcrUserListener implements EventListener {
+ private final Display display;
- @Override
- public void onEvent(EventIterator events) {
- // viewer.refresh();
- refreshFilteredList();
+ public JcrUserListener(Display display) {
+ super();
+ this.display = display;
}
- }
-
- private class UserPropertiesListener implements EventListener {
@Override
public void onEvent(EventIterator events) {
- // viewer.refresh();
- refreshFilteredList();
- }
- }
-
- private class UsersContentProvider implements IStructuredContentProvider {
-
- public Object[] getElements(Object inputElement) {
- return (Object[]) inputElement;
-
- // try {
- // Query query = session
- // .getWorkspace()
- // .getQueryManager()
- // .createQuery(
- // "select * from ["
- // + ArgeoTypes.ARGEO_USER_PROFILE + "]",
- // Query.JCR_SQL2);
- // NodeIterator nit = query.execute().getNodes();
- // List<Node> userProfiles = new ArrayList<Node>();
- // while (nit.hasNext()) {
- // userProfiles.add(nit.nextNode());
- // }
- // return userProfiles.toArray();
- // } catch (RepositoryException e) {
- // throw new ArgeoException("Cannot list users", e);
- // }
- // // return userAdminService.listUsers().toArray();
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ userTableCmp.refresh();
+ }
+ });
}
-
}
class ViewDoubleClickListener implements IDoubleClickListener {
}
}
}
-
- /* MANAGE FILTER */
- private void createFilterPart(Composite parent) {
- Composite header = new Composite(parent, SWT.FILL);
- header.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- header.setLayout(new GridLayout(2, false));
-
- // Text Area to filter
- filterTxt = new Text(header, SWT.BORDER | SWT.SINGLE);
- filterTxt.setMessage(FILTER_HELP_MSG);
- GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false);
- gd.grabExcessHorizontalSpace = true;
- filterTxt.setLayoutData(gd);
- filterTxt.addModifyListener(new ModifyListener() {
- public void modifyText(ModifyEvent event) {
- refreshFilteredList();
- }
- });
-
- Button resetBtn = new Button(header, SWT.PUSH);
- resetBtn.setImage(FILTER_RESET);
- resetBtn.addSelectionListener(new SelectionListener() {
- public void widgetSelected(SelectionEvent e) {
- resetFilter();
- }
-
- public void widgetDefaultSelected(SelectionEvent e) {
- }
- });
-
- }
-
- private void resetFilter() {
- filterTxt.setText("");
- filterTxt.setMessage(FILTER_HELP_MSG);
- }
-
- private void refreshFilteredList() {
- List<Node> nodes;
- try {
- nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session,
- filterTxt.getText()));
- viewer.setInput(nodes.toArray());
- } catch (RepositoryException e) {
- throw new ArgeoException("Unable to list users", e);
- }
- }
-
- /** Build repository request */
- private NodeIterator listFilteredElements(Session session, String filter)
- throws RepositoryException {
- QueryManager queryManager = session.getWorkspace().getQueryManager();
- QueryObjectModelFactory factory = queryManager.getQOMFactory();
-
- final String bundleArtifactsSelector = "userProfiles";
- Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE,
- bundleArtifactsSelector);
-
- // Create a dynamic operand for each property on which we want to filter
- DynamicOperand userIdDO = factory.propertyValue(
- source.getSelectorName(), ARGEO_USER_ID);
- DynamicOperand fullNameDO = factory.propertyValue(
- source.getSelectorName(), Property.JCR_TITLE);
- DynamicOperand mailDO = factory.propertyValue(source.getSelectorName(),
- ARGEO_PRIMARY_EMAIL);
-
- // Default Constraint: no source artifacts
- Constraint defaultC = null;
-
- // Build constraints based the textArea content
- if (filter != null && !"".equals(filter.trim())) {
- // Parse the String
- String[] strs = filter.trim().split(" ");
- for (String token : strs) {
- token = token.replace('*', '%');
- StaticOperand so = factory.literal(session.getValueFactory()
- .createValue("%" + token + "%"));
-
- Constraint currC = factory.comparison(userIdDO,
- QueryObjectModelFactory.JCR_OPERATOR_LIKE, so);
- currC = factory.or(currC, factory.comparison(fullNameDO,
- QueryObjectModelFactory.JCR_OPERATOR_LIKE, so));
- currC = factory.or(currC, factory.comparison(mailDO,
- QueryObjectModelFactory.JCR_OPERATOR_LIKE, so));
-
- if (defaultC == null)
- defaultC = currC;
- else
- defaultC = factory.and(defaultC, currC);
- }
- }
-
- Ordering order = factory.ascending(factory.propertyValue(
- bundleArtifactsSelector, ARGEO_USER_ID));
- // Ordering order2 = factory.ascending(factory.propertyValue(
- // bundleArtifactsSelector, ARGEO_PRIMARY_EMAIL));
- // Ordering[] orderings = { order, order2 };
- 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.wizards;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+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 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() {
+ @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 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 UserTableComposite(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();
+ }
+ }
+
+ /**
+ * Recapitulation of input data before running real update
+ */
+ private class ValidateAndLaunchWizardPage extends WizardPage implements
+ IPageChangedListener {
+ 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
+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