]> git.argeo.org Git - lgpl/argeo-commons.git/blob - security/plugins/org.argeo.security.ui.admin/src/main/java/org/argeo/security/ui/admin/UserTableComposite.java
Fix a trivial null pointer exception while working on user management for connect...
[lgpl/argeo-commons.git] / security / plugins / org.argeo.security.ui.admin / src / main / java / org / argeo / security / ui / admin / UserTableComposite.java
1 package org.argeo.security.ui.admin;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.jcr.Node;
7 import javax.jcr.NodeIterator;
8 import javax.jcr.Property;
9 import javax.jcr.PropertyType;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.query.QueryManager;
13 import javax.jcr.query.QueryResult;
14 import javax.jcr.query.qom.Constraint;
15 import javax.jcr.query.qom.Ordering;
16 import javax.jcr.query.qom.QueryObjectModel;
17 import javax.jcr.query.qom.QueryObjectModelFactory;
18 import javax.jcr.query.qom.Selector;
19 import javax.jcr.query.qom.StaticOperand;
20
21 import org.argeo.ArgeoException;
22 import org.argeo.eclipse.ui.EclipseUiUtils;
23 import org.argeo.eclipse.ui.jcr.JcrUiUtils;
24 import org.argeo.eclipse.ui.jcr.lists.ColumnDefinition;
25 import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
26 import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider;
27 import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
28 import org.argeo.eclipse.ui.utils.ViewerUtils;
29 import org.argeo.jcr.ArgeoNames;
30 import org.argeo.jcr.ArgeoTypes;
31 import org.argeo.jcr.JcrUtils;
32 import org.eclipse.jface.viewers.CheckboxTableViewer;
33 import org.eclipse.jface.viewers.ColumnLabelProvider;
34 import org.eclipse.jface.viewers.IStructuredContentProvider;
35 import org.eclipse.jface.viewers.TableViewer;
36 import org.eclipse.jface.viewers.TableViewerColumn;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.events.ModifyEvent;
40 import org.eclipse.swt.events.ModifyListener;
41 import org.eclipse.swt.events.SelectionAdapter;
42 import org.eclipse.swt.events.SelectionEvent;
43 import org.eclipse.swt.graphics.Font;
44 import org.eclipse.swt.layout.GridData;
45 import org.eclipse.swt.layout.GridLayout;
46 import org.eclipse.swt.widgets.Composite;
47 import org.eclipse.swt.widgets.Table;
48 import org.eclipse.swt.widgets.Text;
49
50 public class UserTableComposite extends Composite implements ArgeoNames {
51 // private final static Log log =
52 // LogFactory.getLog(UserTableComposite.class);
53
54 private static final long serialVersionUID = -7385959046279360420L;
55
56 private TableViewer usersViewer;
57 private Text filterTxt;
58 private final static String FILTER_HELP_MSG = "Type filter criterion "
59 + "separated by a space";
60 private Session session;
61
62 private Font italic;
63 private Font bold;
64
65 private boolean hasFilter;
66 private boolean hasSelectionColumn;
67
68 // private List<Node> selectedItems = new ArrayList<Node>();
69
70 /**
71 * Overwrite to display other columns
72 */
73 public List<ColumnDefinition> getColumnsDef() {
74 List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
75
76 // User ID
77 columnDefs.add(new ColumnDefinition(null, ARGEO_USER_ID,
78 PropertyType.STRING, "User ID", 100));
79 // Displayed name
80 columnDefs.add(new ColumnDefinition(null, Property.JCR_TITLE,
81 PropertyType.STRING, "Name", 150));
82
83 // E-mail
84 columnDefs.add(new ColumnDefinition(null, ARGEO_PRIMARY_EMAIL,
85 PropertyType.STRING, "E-mail", 150));
86
87 // Description
88 columnDefs.add(new ColumnDefinition(null, Property.JCR_DESCRIPTION,
89 PropertyType.STRING, "Description", 200));
90
91 return columnDefs;
92 }
93
94 public UserTableComposite(Composite parent, int style, Session session) {
95 super(parent, style);
96 this.session = session;
97 }
98
99 /**
100 *
101 * @param addFilter
102 * choose to add a field to filter results or not
103 * @param addSelection
104 * choose to add a column to select some of the displayed results
105 * or not
106 */
107 public void populate(boolean addFilter, boolean addSelection) {
108 // initialization
109 Composite parent = this;
110 italic = EclipseUiUtils.getItalicFont(parent);
111 bold = EclipseUiUtils.getBoldFont(parent);
112 hasFilter = addFilter;
113 hasSelectionColumn = addSelection;
114
115 // Main Layout
116 this.setLayout(new GridLayout(1, false));
117 if (hasFilter)
118 createFilterPart(parent);
119 usersViewer = createTableViewer(parent);
120 EclipseUiSpecificUtils.enableToolTipSupport(usersViewer);
121 usersViewer.setContentProvider(new UsersContentProvider());
122 refreshFilteredList();
123 }
124
125 public List<Node> getSelectedUsers() {
126 if (hasSelectionColumn) {
127 Object[] elements = ((CheckboxTableViewer) usersViewer)
128 .getCheckedElements();
129
130 List<Node> result = new ArrayList<Node>();
131 for (Object obj : elements) {
132 result.add((Node) obj);
133 }
134 return result;
135 } else
136 throw new ArgeoException("Unvalid request: no selection column "
137 + "has been created for the current table");
138 }
139
140 /** Returns the User table viewer, typically to add doubleclick listener */
141 public TableViewer getTableViewer() {
142 return usersViewer;
143 }
144
145 /** Returns filter String or null*/
146 protected String getFilterString() {
147 return hasFilter ? filterTxt.getText() : null;
148 }
149
150
151
152 private TableViewer createTableViewer(final Composite parent) {
153 int style = SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
154 if (hasSelectionColumn)
155 style = style | SWT.CHECK;
156
157 Table table = new Table(parent, style);
158 table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
159
160 TableViewer viewer;
161 if (hasSelectionColumn)
162 viewer = new CheckboxTableViewer(table);
163 else
164 viewer = new TableViewer(table);
165 table.setLinesVisible(true);
166 table.setHeaderVisible(true);
167
168 // pass a mapping between col index and property name to the comparator.
169 // List<String> propertiesList = new ArrayList<String>();
170
171 TableViewerColumn column;
172 int offset = 0;
173 if (hasSelectionColumn) {
174 offset = 1;
175 column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE,
176 25);
177 column.setLabelProvider(new ColumnLabelProvider() {
178 private static final long serialVersionUID = 1L;
179
180 @Override
181 public String getText(Object element) {
182 return null;
183 }
184 });
185 SelectionAdapter selectionAdapter = new SelectionAdapter() {
186 private static final long serialVersionUID = 1L;
187
188 boolean allSelected = false;
189
190 @Override
191 public void widgetSelected(SelectionEvent e) {
192 allSelected = !allSelected;
193 ((CheckboxTableViewer) usersViewer)
194 .setAllChecked(allSelected);
195 }
196 };
197 column.getColumn().addSelectionListener(selectionAdapter);
198 }
199
200 // Create other columns
201 List<ColumnDefinition> colDefs = getColumnsDef();
202
203 NodeViewerComparator comparator = new NodeViewerComparator();
204 int i = offset;
205 for (ColumnDefinition colDef : colDefs) {
206 column = ViewerUtils.createTableViewerColumn(viewer,
207 colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
208 column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
209 column.getColumn().addSelectionListener(
210 JcrUiUtils.getNodeSelectionAdapter(i,
211 colDef.getPropertyType(), colDef.getPropertyName(),
212 comparator, viewer));
213 i++;
214 }
215
216 // IMPORTANT: initialize comparator before setting it
217 ColumnDefinition firstCol = colDefs.get(0);
218 comparator.setColumn(firstCol.getPropertyType(),
219 firstCol.getPropertyName());
220 viewer.setComparator(comparator);
221
222 return viewer;
223 }
224
225 private class CLProvider extends SimpleJcrNodeLabelProvider {
226
227 private static final long serialVersionUID = 1L;
228
229 public CLProvider(String propertyName) {
230 super(propertyName);
231 }
232
233 public String getToolTipText(Object element) {
234 return getText(element);
235 }
236
237 @Override
238 public Font getFont(Object elem) {
239 // self
240 String username = getProperty(elem, ARGEO_USER_ID);
241 if (username.equals(session.getUserID()))
242 return bold;
243
244 // disabled
245 try {
246 Node userProfile = (Node) elem;
247 // Node userProfile = userHome.getNode(ARGEO_PROFILE);
248 if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean())
249 return italic;
250 else
251 return null;
252 } catch (RepositoryException e) {
253 throw new ArgeoException("Cannot get font for " + username, e);
254 }
255 }
256 }
257
258 @Override
259 public boolean setFocus() {
260 usersViewer.getTable().setFocus();
261 return true;
262 }
263
264 @Override
265 public void dispose() {
266 super.dispose();
267 }
268
269 public void refresh() {
270 refreshFilteredList();
271 }
272
273 private String getProperty(Object element, String name) {
274 try {
275 Node userProfile = (Node) element;
276 return userProfile.hasProperty(name) ? userProfile
277 .getProperty(name).getString() : "";
278 } catch (RepositoryException e) {
279 throw new ArgeoException("Cannot get property " + name, e);
280 }
281 }
282
283 private class UsersContentProvider implements IStructuredContentProvider {
284 private static final long serialVersionUID = 1L;
285
286 public Object[] getElements(Object inputElement) {
287 return (Object[]) inputElement;
288 }
289
290 public void dispose() {
291 }
292
293 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
294 }
295 }
296
297 /* MANAGE FILTER */
298 private void createFilterPart(Composite parent) {
299 // Text Area for the filter
300 filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH
301 | SWT.ICON_CANCEL);
302 filterTxt.setMessage(FILTER_HELP_MSG);
303 filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
304 | GridData.HORIZONTAL_ALIGN_FILL));
305 filterTxt.addModifyListener(new ModifyListener() {
306 private static final long serialVersionUID = 1L;
307
308 public void modifyText(ModifyEvent event) {
309 refreshFilteredList();
310 }
311 });
312 }
313
314 /**
315 * Refresh the user list: caller might overwrite in order to display a
316 * subset of all users, typically to remove current user from the list
317 */
318 protected void refreshFilteredList() {
319 List<Node> nodes;
320 try {
321 nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session,
322 hasFilter ? filterTxt.getText() : null));
323 usersViewer.setInput(nodes.toArray());
324 } catch (RepositoryException e) {
325 throw new ArgeoException("Unable to list users", e);
326 }
327 }
328
329 /**
330 * Build repository request : caller might overwrite in order to display a
331 * subset of all users
332 */
333 protected NodeIterator listFilteredElements(Session session, String filter)
334 throws RepositoryException {
335 QueryManager queryManager = session.getWorkspace().getQueryManager();
336 QueryObjectModelFactory factory = queryManager.getQOMFactory();
337
338 Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE,
339 ArgeoTypes.ARGEO_USER_PROFILE);
340
341 // Dynamically build constraint depending on the filter String
342 Constraint defaultC = null;
343 if (filter != null && !"".equals(filter.trim())) {
344 String[] strs = filter.trim().split(" ");
345 for (String token : strs) {
346 StaticOperand so = factory.literal(session.getValueFactory()
347 .createValue("*" + token + "*"));
348 Constraint currC = factory.fullTextSearch(
349 source.getSelectorName(), null, so);
350 if (defaultC == null)
351 defaultC = currC;
352 else
353 defaultC = factory.and(defaultC, currC);
354 }
355 }
356
357 Ordering order = factory.ascending(factory.propertyValue(
358 source.getSelectorName(), ARGEO_USER_ID));
359 Ordering[] orderings = { order };
360
361 QueryObjectModel query = factory.createQuery(source, defaultC,
362 orderings, null);
363
364 QueryResult result = query.execute();
365 return result.getNodes();
366 }
367 }