]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - security/plugins/org.argeo.security.ui.admin/src/main/java/org/argeo/security/ui/admin/views/UsersView.java
Merge Add sorting to user list table
[lgpl/argeo-commons.git] / security / plugins / org.argeo.security.ui.admin / src / main / java / org / argeo / security / ui / admin / views / UsersView.java
index 8ddba7683ab8be9ebb869c5f200d14fe84f7f3c3..41d8ed036bae2cb18a17246f8b9b7c899efca8ad 100644 (file)
@@ -1,3 +1,18 @@
+/*
+ * 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 java.util.ArrayList;
@@ -5,79 +20,278 @@ 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.Query;
+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.dialogs.Error;
+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.security.ArgeoUser;
+import org.argeo.jcr.JcrUtils;
 import org.argeo.security.ui.admin.SecurityAdminPlugin;
 import org.argeo.security.ui.admin.commands.OpenArgeoUserEditor;
-import org.argeo.security.ui.admin.editors.ArgeoUserEditor;
-import org.argeo.security.ui.admin.editors.ArgeoUserEditorInput;
-import org.eclipse.core.commands.Command;
-import org.eclipse.core.commands.IParameter;
-import org.eclipse.core.commands.Parameterization;
-import org.eclipse.core.commands.ParameterizedCommand;
+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.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
 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.widgets.Composite;
 import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.commands.ICommandService;
-import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.part.ViewPart;
 
 /** List all users. */
-public class UsersView extends ViewPart implements ArgeoNames, ArgeoTypes,
-               EventListener {
-       public final static String ID = "org.argeo.security.ui.admin.adminUsersView";
+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 = "Enter filter criterion "
+                       + "separated by a space (on user ID, name and E-mail";
+       private final static Image FILTER_RESET = SecurityAdminPlugin
+                       .getImageDescriptor("icons/users.gif").createImage();
+
        private Session session;
 
+       private UserStructureListener userStructureListener;
+       private UserPropertiesListener userPropertiesListener;
+
+       private Font italic;
+       private Font bold;
+
        @Override
        public void createPartControl(Composite parent) {
-               viewer = new TableViewer(createTable(parent));
+               italic = EclipseUiUtils.getItalicFont(parent);
+               bold = EclipseUiUtils.getBoldFont(parent);
+
+               // Main Layout
+               GridLayout layout = new GridLayout(1, false);
+               parent.setLayout(layout);
+               createFilterPart(parent);
+
+               viewer = createTableViewer(parent);
+               EclipseUiSpecificUtils.enableToolTipSupport(viewer);
                viewer.setContentProvider(new UsersContentProvider());
-               viewer.setLabelProvider(new UsersLabelProvider());
                viewer.addDoubleClickListener(new ViewDoubleClickListener());
-               viewer.setInput(getViewSite());
+               getViewSite().setSelectionProvider(viewer);
+
+               userStructureListener = new UserStructureListener();
+               JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED
+                               | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null);
+               userPropertiesListener = new UserPropertiesListener();
+               JcrUtils.addListener(session, userStructureListener,
+                               Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED
+                                               | Event.PROPERTY_REMOVED,
+                               ArgeoJcrConstants.PEOPLE_BASE_PATH,
+                               ArgeoTypes.ARGEO_USER_PROFILE);
+
+               refreshFilteredList();
        }
 
-       protected Table createTable(Composite parent) {
+       protected TableViewer createTableViewer(final Composite parent) {
+
                Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+               TableViewer viewer = new TableViewer(table);
                table.setLinesVisible(true);
                table.setHeaderVisible(true);
-               TableColumn column = new TableColumn(table, SWT.LEFT, 0);
-               column.setText("User");
-               column.setWidth(50);
-               column = new TableColumn(table, SWT.LEFT, 1);
-               column.setText("First Name");
-               column.setWidth(100);
-               column = new TableColumn(table, SWT.LEFT, 2);
-               column.setText("Last Name");
-               column.setWidth(100);
-               column = new TableColumn(table, SWT.LEFT, 3);
-               column.setText("E-mail");
-               column.setWidth(100);
-               return table;
+
+               // 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
@@ -85,6 +299,13 @@ public class UsersView extends ViewPart implements ArgeoNames, ArgeoTypes,
                viewer.getTable().setFocus();
        }
 
+       @Override
+       public void dispose() {
+               JcrUtils.removeListenerQuietly(session, userStructureListener);
+               JcrUtils.removeListenerQuietly(session, userPropertiesListener);
+               super.dispose();
+       }
+
        public void setSession(Session session) {
                this.session = session;
        }
@@ -93,95 +314,68 @@ public class UsersView extends ViewPart implements ArgeoNames, ArgeoTypes,
                viewer.refresh();
        }
 
-       @Override
-       public void onEvent(EventIterator events) {
-               viewer.refresh();
+       protected String getProperty(Node userProfile, String name)
+                       throws RepositoryException {
+               return userProfile.hasProperty(name) ? userProfile.getProperty(name)
+                               .getString() : "";
        }
 
-       private class UsersContentProvider implements IStructuredContentProvider {
-
-               public Object[] getElements(Object inputElement) {
-                       try {
-                               Query query = session
-                                               .getWorkspace()
-                                               .getQueryManager()
-                                               .createQuery(
-                                                               "select [" + ARGEO_PROFILE + "] from ["
-                                                                               + ARGEO_USER_HOME + "]", 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();
+       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);
                }
+       }
 
-               public void dispose() {
-               }
+       private class UserStructureListener implements EventListener {
 
-               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               @Override
+               public void onEvent(EventIterator events) {
+                       viewer.refresh();
                }
+       }
 
+       private class UserPropertiesListener implements EventListener {
+
+               @Override
+               public void onEvent(EventIterator events) {
+                       viewer.refresh();
+               }
        }
 
-       private class UsersLabelProvider extends LabelProvider implements
-                       ITableLabelProvider {
-               public String getColumnText(Object element, int columnIndex) {
-                       try {
-                               Node userHome = (Node) element;
-                               switch (columnIndex) {
-                               case 0:
-                                       String userName = userHome.getProperty(ARGEO_USER_ID)
-                                                       .getString();
-                                       if (userName.equals(session.getUserID()))
-                                               return "[" + userName + "]";
-                                       else
-                                               return userName;
-                               case 1:
-                                       return userHome.getNode(ARGEO_PROFILE)
-                                                       .getProperty(ARGEO_FIRST_NAME).getString();
-                               case 2:
-                                       return userHome.getNode(ARGEO_PROFILE)
-                                                       .getProperty(ARGEO_LAST_NAME).getString();
-                               case 3:
-                                       return userHome.getNode(ARGEO_PROFILE)
-                                                       .getProperty(ARGEO_PRIMARY_EMAIL).getString();
-                               default:
-                                       throw new ArgeoException("Unmanaged column " + columnIndex);
-                               }
-                       } catch (RepositoryException e) {
-                               throw new ArgeoException("Cannot get text", e);
-                       }
+       private class UsersContentProvider implements IStructuredContentProvider {
+
+               public Object[] getElements(Object inputElement) {
+                       return (Object[]) inputElement;
 
-                       // String currentUsername = CurrentUser.getUsername();
-                       // String currentUsername = "";
-                       // ArgeoUser user = (ArgeoUser) element;
-                       // SimpleUserNature simpleNature = SimpleUserNature
-                       // .findSimpleUserNature(user, simpleNatureType);
-                       // switch (columnIndex) {
-                       // case 0:
-                       // String userName = user.getUsername();
-                       // if (userName.equals(currentUsername))
-                       // userName = userName + "*";
-                       // return userName;
-                       // case 1:
-                       // return simpleNature.getFirstName();
-                       // case 2:
-                       // return simpleNature.getLastName();
-                       // case 3:
-                       // return simpleNature.getEmail();
-                       // default:
-                       // throw new ArgeoException("Unmanaged column " + columnIndex);
+                       // 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 Image getColumnImage(Object element, int columnIndex) {
-                       // TODO Auto-generated method stub
-                       return null;
+               public void dispose() {
+               }
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
                }
 
        }
@@ -195,48 +389,120 @@ public class UsersView extends ViewPart implements ArgeoNames, ArgeoTypes,
                                        .getFirstElement();
                        if (obj instanceof Node) {
                                try {
-                                       IWorkbench iw = SecurityAdminPlugin.getDefault()
-                                                       .getWorkbench();
-                                       iw.getActiveWorkbenchWindow()
-                                                       .getActivePage()
-                                                       .openEditor(new ArgeoUserEditorInput((Node) obj),
-                                                                       ArgeoUserEditor.ID);
-                               } catch (PartInitException e) {
-                                       Error.show("Cannot open user editor for " + obj, e);
-                               }
-                       } else if (obj instanceof ArgeoUser) {
-                               ArgeoUser argeoUser = (ArgeoUser) obj;
-
-                               IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
-                               IHandlerService handlerService = (IHandlerService) iw
-                                               .getService(IHandlerService.class);
-                               try {
+                                       String username = ((Node) obj).getProperty(ARGEO_USER_ID)
+                                                       .getString();
                                        String commandId = OpenArgeoUserEditor.COMMAND_ID;
                                        String paramName = OpenArgeoUserEditor.PARAM_USERNAME;
-
-                                       // TODO: factorize this
-                                       // execute related command
-                                       IWorkbenchWindow window = iw.getActiveWorkbenchWindow();
-                                       ICommandService cmdService = (ICommandService) window
-                                                       .getService(ICommandService.class);
-                                       Command cmd = cmdService.getCommand(commandId);
-                                       ArrayList<Parameterization> parameters = new ArrayList<Parameterization>();
-                                       IParameter iparam = cmd.getParameter(paramName);
-                                       Parameterization param = new Parameterization(iparam,
-                                                       argeoUser.getUsername());
-                                       parameters.add(param);
-                                       ParameterizedCommand pc = new ParameterizedCommand(cmd,
-                                                       parameters.toArray(new Parameterization[parameters
-                                                                       .size()]));
-                                       handlerService = (IHandlerService) window
-                                                       .getService(IHandlerService.class);
-                                       handlerService.executeCommand(pc, null);
-                               } catch (Exception e) {
-                                       throw new ArgeoException("Cannot open editor", e);
+                                       CommandUtils.callCommand(commandId, paramName, username);
+                               } catch (RepositoryException e) {
+                                       throw new ArgeoException("Cannot open user editor", e);
                                }
+                       }
+               }
+       }
+
+       /* 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.descending(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