diff --git a/source/java/org/alfresco/web/bean/groups/GroupsDialog.java b/source/java/org/alfresco/web/bean/groups/GroupsDialog.java index f872d80fee..c9120af3d6 100644 --- a/source/java/org/alfresco/web/bean/groups/GroupsDialog.java +++ b/source/java/org/alfresco/web/bean/groups/GroupsDialog.java @@ -36,6 +36,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.namespace.QName; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; @@ -43,6 +44,7 @@ import org.alfresco.web.bean.dialog.BaseDialogBean; import org.alfresco.web.bean.dialog.ChangeViewSupport; import org.alfresco.web.bean.dialog.FilterViewSupport; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.data.DynamicResolver; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.IBreadcrumbHandler; import org.alfresco.web.ui.common.component.UIActionLink; @@ -333,191 +335,182 @@ public class GroupsDialog extends BaseDialogBean return this.location; } - /** - * @return true if user is in the root group - */ - public boolean isAllowSearchGroups() - { - return this.group == null; - } + /** + * @return true if user is in the root group + */ + public boolean isAllowSearchGroups() + { + return this.group == null; + } - /** - * @return The list of group objects to display. Returns the list of root groups or the list of sub-groups for the current group if set. - */ - public List> getGroups() - { - if (this.group == null) - { - if (this.groups == null) - { - searchGroups(); - } - } - else - { - if (this.groups == null) - { - showAllGroups(); - } - } - return this.groups; - } - - /** - * @return Returns the groups search criteria - */ - public String getGroupsSearchCriteria() - { - return groupsSearchCriteria; - } + /** + * @return The list of group objects to display. Returns the list of root groups or the list of sub-groups for the current group if set. + */ + public List> getGroups() + { + if (this.group == null) + { + if (this.groups == null) + { + searchGroups(); + } + } + else + { + if (this.groups == null) + { + showAllGroups(); + } + } + return this.groups; + } - /** - * Event handler called when the user wishes to search for a group - * - * @return The outcome - */ - public String searchGroups() - { - searchGroups(false); - // return null to stay on the same page - return null; - } + /** + * @return Returns the groups search criteria + */ + public String getGroupsSearchCriteria() + { + return groupsSearchCriteria; + } - /** - * Action handler to show all the sub-groups in the group - * - * @return The outcome - */ - public String showAllGroups() - { - searchGroups(true); - // return null to stay on the same page - return null; - } + /** + * Event handler called when the user wishes to search for a group + * + * @return The outcome + */ + public String searchGroups() + { + searchGroups(false); + // return null to stay on the same page + return null; + } - /** - * Searches groups - * - * @param all if true searches all groups and doesn't take account of search term - */ - private void searchGroups(boolean all) - { - groupsRichList.setValue(null); - String search = null; + /** + * Action handler to show all the sub-groups in the group + * + * @return The outcome + */ + public String showAllGroups() + { + searchGroups(true); + // return null to stay on the same page + return null; + } - // Use the search criteria if we are not searching for everything - if (!all) - { - if (this.groupsSearchCriteria == null) - { - search = null; + /** + * Searches groups + * + * @param all if true searches all groups and doesn't take account of search term + */ + private void searchGroups(boolean all) + { + groupsRichList.setValue(null); + String search = null; + + // Use the search criteria if we are not searching for everything + if (!all) + { + if (this.groupsSearchCriteria == null) + { + search = null; + } + else + { + search = groupsSearchCriteria.trim(); + if (search.length() == 0) + { + search = null; } else { - search = groupsSearchCriteria.trim(); - if (search.length() == 0) - { - search = null; - } - else - { - // Let's make it search on the short name/display name prefix - search = search + "*"; - } + // Let's make it search on the short name/display name prefix + search = search + "*"; } - } + } + } + + if (!all && search == null) + { + // Do not allow empty searches + this.groups = Collections.> emptyList(); + } + else + { + boolean immediate = (this.filterMode.equals(FILTER_CHILDREN)); + Set authorities = this.authService.findAuthorities(AuthorityType.GROUP, this.group, immediate, search, AuthorityService.ZONE_APP_DEFAULT); + groups = new ArrayList>(authorities.size()); + for (String authority : authorities) + { + Map authMap = new HashMap(11); - if (!all && search == null) - { - // Do not allow empty searches - this.groups = Collections.> emptyList(); - } - else - { - boolean immediate = (this.filterMode.equals(FILTER_CHILDREN)); - Set authorities = this.authService.findAuthorities(AuthorityType.GROUP, this.group, immediate, search, AuthorityService.ZONE_APP_DEFAULT); - groups = new ArrayList>(authorities.size()); - for (String authority : authorities) + String name = this.authService.getAuthorityDisplayName(authority); + if (name == null) { - Map authMap = new HashMap(11); - - String name = this.authService.getAuthorityDisplayName(authority); - if (name == null) - { - name = this.authService.getShortName(name); - } - authMap.put("name", name); - authMap.put("id", authority); - authMap.put("group", authority); - authMap.put("groupName", name); - - groups.add(authMap); + name = this.authService.getShortName(name); } - } - } + authMap.put("name", name); + authMap.put("id", authority); + authMap.put("group", authority); + authMap.put("groupName", name); + + groups.add(authMap); + } + } + } - /** - * @return The list of user objects to display. Returns the list of user for the current group. - */ - public List> getUsers() - { - List> users; - - UserTransaction tx = null; - try - { - FacesContext context = FacesContext.getCurrentInstance(); - tx = Repository.getUserTransaction(context, true); - tx.begin(); - - Set authorities; - if (this.group == null) - { - authorities = Collections.emptySet(); - } - else - { - // users of an existing group - boolean immediate = (this.filterMode.equals(FILTER_CHILDREN)); - authorities = this.getAuthorityService().getContainedAuthorities(AuthorityType.USER, this.group, immediate); - } - users = new ArrayList>(authorities.size()); - for (String authority : authorities) - { - Map authMap = new HashMap(5); - - String userName = this.getAuthorityService().getShortName(authority); - authMap.put("userName", userName); - authMap.put("id", authority); - - // get Person details for this Authority - NodeRef ref = this.getPersonService().getPerson(authority); - String firstName = (String)this.getNodeService().getProperty(ref, ContentModel.PROP_FIRSTNAME); - String lastName = (String)this.getNodeService().getProperty(ref, ContentModel.PROP_LASTNAME); - - // build a sensible label for display - StringBuilder label = new StringBuilder(48); - label.append(firstName) - .append(' ') - .append(lastName != null ? lastName : ""); - authMap.put("name", label.toString()); - - users.add(authMap); - } - - // commit the transaction - tx.commit(); - } - catch (Throwable err) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); - users = Collections.>emptyList(); - try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} - } - - return users; - } + /** + * @return The list of user objects to display. Returns the list of user for the current group. + */ + public List> getUsers() + { + List> users; + + UserTransaction tx = null; + try + { + FacesContext context = FacesContext.getCurrentInstance(); + tx = Repository.getUserTransaction(context, true); + tx.begin(); + + Set authorities; + if (this.group == null) + { + authorities = Collections.emptySet(); + } + else + { + // users of an existing group + boolean immediate = (this.filterMode.equals(FILTER_CHILDREN)); + authorities = this.getAuthorityService().getContainedAuthorities(AuthorityType.USER, this.group, immediate); + } + users = new ArrayList>(authorities.size()); + for (String authority : authorities) + { + final Map authMap = new HashMap(8); + + final String userName = this.getAuthorityService().getShortName(authority); + authMap.put("userName", userName); + authMap.put("id", authority); + authMap.put("name", new AuthorityNamePropertyResolver(userName)); + authMap.put("firstName", new AuthorityPropertyResolver(userName, ContentModel.PROP_FIRSTNAME)); + authMap.put("lastName", new AuthorityPropertyResolver(userName, ContentModel.PROP_LASTNAME)); + + users.add(authMap); + } + + // commit the transaction + tx.commit(); + } + catch (Throwable err) + { + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); + users = Collections.>emptyList(); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + + return users; + } /** * Set the current Group Authority. @@ -723,6 +716,7 @@ public class GroupsDialog extends BaseDialogBean public String Label; } + /** * Simple wrapper bean exposing user authority and person details for JSF results list */ @@ -749,4 +743,62 @@ public class GroupsDialog extends BaseDialogBean private String name; private String authority; } + + + /** + * Simple dynamic resolver class to return authority properties at runtime + */ + public class AuthorityPropertyResolver implements DynamicResolver + { + final private String authority; + final private QName property; + private String value = null; + + AuthorityPropertyResolver(String authority, QName property) + { + this.authority = authority; + this.property = property; + } + + @Override + public String toString() + { + if (this.value == null) + { + NodeRef ref = getPersonService().getPerson(this.authority); + this.value = (String)getNodeService().getProperty(ref, this.property); + } + return this.value; + } + } + + public class AuthorityNamePropertyResolver implements DynamicResolver + { + final private String authority; + private String value = null; + + AuthorityNamePropertyResolver(String authority) + { + this.authority = authority; + } + + @Override + public String toString() + { + if (this.value == null) + { + NodeRef ref = getPersonService().getPerson(this.authority); + String firstName = (String)getNodeService().getProperty(ref, ContentModel.PROP_FIRSTNAME); + String lastName = (String)getNodeService().getProperty(ref, ContentModel.PROP_LASTNAME); + + // build a sensible label for display + StringBuilder label = new StringBuilder(48); + label.append(firstName != null ? firstName : "") + .append(' ') + .append(lastName != null ? lastName : ""); + this.value = label.toString(); + } + return this.value; + } + } } diff --git a/source/java/org/alfresco/web/data/DynamicResolver.java b/source/java/org/alfresco/web/data/DynamicResolver.java new file mode 100644 index 0000000000..c9d3b4de5c --- /dev/null +++ b/source/java/org/alfresco/web/data/DynamicResolver.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.web.data; + +/** + * Interface marker used to indicate that a property is resolved at runtime + * + * @author Kevin Roast + */ +public interface DynamicResolver +{ + +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/data/Sort.java b/source/java/org/alfresco/web/data/Sort.java index fb416b98d8..6a112d951b 100644 --- a/source/java/org/alfresco/web/data/Sort.java +++ b/source/java/org/alfresco/web/data/Sort.java @@ -183,6 +183,10 @@ public abstract class Sort { this.comparator = new TimestampComparator(); } + else if (DynamicResolver.class.isAssignableFrom(returnType)) + { + this.comparator = new SimpleStringComparator(); + } else { s_logger.warn("Unsupported sort data type: " + returnType + " defaulting to .toString()"); diff --git a/source/web/jsp/groups/groups.jsp b/source/web/jsp/groups/groups.jsp index 7066590814..9b401ca675 100644 --- a/source/web/jsp/groups/groups.jsp +++ b/source/web/jsp/groups/groups.jsp @@ -131,7 +131,7 @@ + value="#{DialogManager.bean.users}" var="r" initialSortColumn="userName" initialSortDescending="true"> <%-- Primary column for icons view mode --%> @@ -144,12 +144,20 @@ <%-- Primary column for details view mode --%> - + - + - + + + + <%-- Last name column --%> + + + + + <%-- Username column --%>