mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.2 to HEAD
19363: *RECORD ONLY* Fix for ALF-1952 - multi-pass HTML stripping 19527: Fix for ALF-1037 - only documents modified by current user should be shown in My Documents dashlet filter 19528: Fix for ALF-944 - list of users for Group admin in Explorer now only retrieves data required for values on display git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19529 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -36,6 +36,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.security.AuthorityService;
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityType;
|
import org.alfresco.service.cmr.security.AuthorityType;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.app.context.IContextListener;
|
import org.alfresco.web.app.context.IContextListener;
|
||||||
import org.alfresco.web.app.context.UIContextService;
|
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.ChangeViewSupport;
|
||||||
import org.alfresco.web.bean.dialog.FilterViewSupport;
|
import org.alfresco.web.bean.dialog.FilterViewSupport;
|
||||||
import org.alfresco.web.bean.repository.Repository;
|
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.Utils;
|
||||||
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
|
||||||
import org.alfresco.web.ui.common.component.UIActionLink;
|
import org.alfresco.web.ui.common.component.UIActionLink;
|
||||||
@@ -333,191 +335,182 @@ public class GroupsDialog extends BaseDialogBean
|
|||||||
return this.location;
|
return this.location;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if user is in the root group
|
* @return true if user is in the root group
|
||||||
*/
|
*/
|
||||||
public boolean isAllowSearchGroups()
|
public boolean isAllowSearchGroups()
|
||||||
{
|
{
|
||||||
return this.group == null;
|
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.
|
* @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<Map<String,String>> getGroups()
|
public List<Map<String,String>> getGroups()
|
||||||
{
|
{
|
||||||
if (this.group == null)
|
if (this.group == null)
|
||||||
{
|
{
|
||||||
if (this.groups == null)
|
if (this.groups == null)
|
||||||
{
|
{
|
||||||
searchGroups();
|
searchGroups();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this.groups == null)
|
if (this.groups == null)
|
||||||
{
|
{
|
||||||
showAllGroups();
|
showAllGroups();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.groups;
|
return this.groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns the groups search criteria
|
|
||||||
*/
|
|
||||||
public String getGroupsSearchCriteria()
|
|
||||||
{
|
|
||||||
return groupsSearchCriteria;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler called when the user wishes to search for a group
|
* @return Returns the groups search criteria
|
||||||
*
|
*/
|
||||||
* @return The outcome
|
public String getGroupsSearchCriteria()
|
||||||
*/
|
{
|
||||||
public String searchGroups()
|
return groupsSearchCriteria;
|
||||||
{
|
}
|
||||||
searchGroups(false);
|
|
||||||
// return null to stay on the same page
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action handler to show all the sub-groups in the group
|
* Event handler called when the user wishes to search for a group
|
||||||
*
|
*
|
||||||
* @return The outcome
|
* @return The outcome
|
||||||
*/
|
*/
|
||||||
public String showAllGroups()
|
public String searchGroups()
|
||||||
{
|
{
|
||||||
searchGroups(true);
|
searchGroups(false);
|
||||||
// return null to stay on the same page
|
// return null to stay on the same page
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches groups
|
* Action handler to show all the sub-groups in the group
|
||||||
*
|
*
|
||||||
* @param all if true searches all groups and doesn't take account of search term
|
* @return The outcome
|
||||||
*/
|
*/
|
||||||
private void searchGroups(boolean all)
|
public String showAllGroups()
|
||||||
{
|
{
|
||||||
groupsRichList.setValue(null);
|
searchGroups(true);
|
||||||
String search = null;
|
// return null to stay on the same page
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Use the search criteria if we are not searching for everything
|
/**
|
||||||
if (!all)
|
* Searches groups
|
||||||
{
|
*
|
||||||
if (this.groupsSearchCriteria == null)
|
* @param all if true searches all groups and doesn't take account of search term
|
||||||
{
|
*/
|
||||||
search = null;
|
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
|
else
|
||||||
{
|
{
|
||||||
search = groupsSearchCriteria.trim();
|
// Let's make it search on the short name/display name prefix
|
||||||
if (search.length() == 0)
|
search = search + "*";
|
||||||
{
|
|
||||||
search = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 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.<Map<String,String>> emptyList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean immediate = (this.filterMode.equals(FILTER_CHILDREN));
|
||||||
|
Set<String> authorities = this.authService.findAuthorities(AuthorityType.GROUP, this.group, immediate, search, AuthorityService.ZONE_APP_DEFAULT);
|
||||||
|
groups = new ArrayList<Map<String,String>>(authorities.size());
|
||||||
|
for (String authority : authorities)
|
||||||
|
{
|
||||||
|
Map<String, String> authMap = new HashMap<String, String>(11);
|
||||||
|
|
||||||
if (!all && search == null)
|
String name = this.authService.getAuthorityDisplayName(authority);
|
||||||
{
|
if (name == null)
|
||||||
// Do not allow empty searches
|
|
||||||
this.groups = Collections.<Map<String,String>> emptyList();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boolean immediate = (this.filterMode.equals(FILTER_CHILDREN));
|
|
||||||
Set<String> authorities = this.authService.findAuthorities(AuthorityType.GROUP, this.group, immediate, search, AuthorityService.ZONE_APP_DEFAULT);
|
|
||||||
groups = new ArrayList<Map<String,String>>(authorities.size());
|
|
||||||
for (String authority : authorities)
|
|
||||||
{
|
{
|
||||||
Map<String, String> authMap = new HashMap<String, String>(11);
|
name = this.authService.getShortName(name);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
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.
|
* @return The list of user objects to display. Returns the list of user for the current group.
|
||||||
*/
|
*/
|
||||||
public List<Map<String,String>> getUsers()
|
public List<Map<String, Object>> getUsers()
|
||||||
{
|
{
|
||||||
List<Map<String,String>> users;
|
List<Map<String, Object>> users;
|
||||||
|
|
||||||
UserTransaction tx = null;
|
UserTransaction tx = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FacesContext context = FacesContext.getCurrentInstance();
|
FacesContext context = FacesContext.getCurrentInstance();
|
||||||
tx = Repository.getUserTransaction(context, true);
|
tx = Repository.getUserTransaction(context, true);
|
||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
Set<String> authorities;
|
Set<String> authorities;
|
||||||
if (this.group == null)
|
if (this.group == null)
|
||||||
{
|
{
|
||||||
authorities = Collections.<String>emptySet();
|
authorities = Collections.<String>emptySet();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// users of an existing group
|
// users of an existing group
|
||||||
boolean immediate = (this.filterMode.equals(FILTER_CHILDREN));
|
boolean immediate = (this.filterMode.equals(FILTER_CHILDREN));
|
||||||
authorities = this.getAuthorityService().getContainedAuthorities(AuthorityType.USER, this.group, immediate);
|
authorities = this.getAuthorityService().getContainedAuthorities(AuthorityType.USER, this.group, immediate);
|
||||||
}
|
}
|
||||||
users = new ArrayList<Map<String,String>>(authorities.size());
|
users = new ArrayList<Map<String, Object>>(authorities.size());
|
||||||
for (String authority : authorities)
|
for (String authority : authorities)
|
||||||
{
|
{
|
||||||
Map<String, String> authMap = new HashMap<String, String>(5);
|
final Map<String, Object> authMap = new HashMap<String, Object>(8);
|
||||||
|
|
||||||
String userName = this.getAuthorityService().getShortName(authority);
|
final String userName = this.getAuthorityService().getShortName(authority);
|
||||||
authMap.put("userName", userName);
|
authMap.put("userName", userName);
|
||||||
authMap.put("id", authority);
|
authMap.put("id", authority);
|
||||||
|
authMap.put("name", new AuthorityNamePropertyResolver(userName));
|
||||||
// get Person details for this Authority
|
authMap.put("firstName", new AuthorityPropertyResolver(userName, ContentModel.PROP_FIRSTNAME));
|
||||||
NodeRef ref = this.getPersonService().getPerson(authority);
|
authMap.put("lastName", new AuthorityPropertyResolver(userName, ContentModel.PROP_LASTNAME));
|
||||||
String firstName = (String)this.getNodeService().getProperty(ref, ContentModel.PROP_FIRSTNAME);
|
|
||||||
String lastName = (String)this.getNodeService().getProperty(ref, ContentModel.PROP_LASTNAME);
|
users.add(authMap);
|
||||||
|
}
|
||||||
// build a sensible label for display
|
|
||||||
StringBuilder label = new StringBuilder(48);
|
// commit the transaction
|
||||||
label.append(firstName)
|
tx.commit();
|
||||||
.append(' ')
|
}
|
||||||
.append(lastName != null ? lastName : "");
|
catch (Throwable err)
|
||||||
authMap.put("name", label.toString());
|
{
|
||||||
|
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||||
users.add(authMap);
|
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
||||||
}
|
users = Collections.<Map<String, Object>>emptyList();
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
// commit the transaction
|
}
|
||||||
tx.commit();
|
|
||||||
}
|
return users;
|
||||||
catch (Throwable err)
|
}
|
||||||
{
|
|
||||||
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
|
||||||
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
|
|
||||||
users = Collections.<Map<String,String>>emptyList();
|
|
||||||
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current Group Authority.
|
* Set the current Group Authority.
|
||||||
@@ -723,6 +716,7 @@ public class GroupsDialog extends BaseDialogBean
|
|||||||
public String Label;
|
public String Label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple wrapper bean exposing user authority and person details for JSF results list
|
* 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 name;
|
||||||
private String authority;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
35
source/java/org/alfresco/web/data/DynamicResolver.java
Normal file
35
source/java/org/alfresco/web/data/DynamicResolver.java
Normal file
@@ -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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@@ -183,6 +183,10 @@ public abstract class Sort
|
|||||||
{
|
{
|
||||||
this.comparator = new TimestampComparator();
|
this.comparator = new TimestampComparator();
|
||||||
}
|
}
|
||||||
|
else if (DynamicResolver.class.isAssignableFrom(returnType))
|
||||||
|
{
|
||||||
|
this.comparator = new SimpleStringComparator();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_logger.warn("Unsupported sort data type: " + returnType + " defaulting to .toString()");
|
s_logger.warn("Unsupported sort data type: " + returnType + " defaulting to .toString()");
|
||||||
|
@@ -131,7 +131,7 @@
|
|||||||
|
|
||||||
<a:richList id="users-list" binding="#{DialogManager.bean.usersRichList}" viewMode="#{DialogManager.bean.viewMode}" pageSize="12"
|
<a:richList id="users-list" binding="#{DialogManager.bean.usersRichList}" viewMode="#{DialogManager.bean.viewMode}" pageSize="12"
|
||||||
styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
|
styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%"
|
||||||
value="#{DialogManager.bean.users}" var="r" initialSortColumn="name" initialSortDescending="true">
|
value="#{DialogManager.bean.users}" var="r" initialSortColumn="userName" initialSortDescending="true">
|
||||||
|
|
||||||
<%-- Primary column for icons view mode --%>
|
<%-- Primary column for icons view mode --%>
|
||||||
<a:column primary="true" style="padding:2px;text-align:left;vertical-align:top;font-weight: bold;" rendered="#{DialogManager.bean.viewMode == 'icons'}">
|
<a:column primary="true" style="padding:2px;text-align:left;vertical-align:top;font-weight: bold;" rendered="#{DialogManager.bean.viewMode == 'icons'}">
|
||||||
@@ -144,12 +144,20 @@
|
|||||||
<%-- Primary column for details view mode --%>
|
<%-- Primary column for details view mode --%>
|
||||||
<a:column primary="true" style="padding:2px;text-align:left;" rendered="#{DialogManager.bean.viewMode == 'details'}">
|
<a:column primary="true" style="padding:2px;text-align:left;" rendered="#{DialogManager.bean.viewMode == 'details'}">
|
||||||
<f:facet name="small-icon">
|
<f:facet name="small-icon">
|
||||||
<h:graphicImage alt="#{r.name}" value="/images/icons/person.gif" />
|
<h:graphicImage alt="#{r.firstName}" value="/images/icons/person.gif" />
|
||||||
</f:facet>
|
</f:facet>
|
||||||
<f:facet name="header">
|
<f:facet name="header">
|
||||||
<a:sortLink label="#{msg.name}" value="name" mode="case-insensitive" styleClass="header"/>
|
<a:sortLink label="#{msg.first_name}" value="firstName" mode="case-insensitive" styleClass="header"/>
|
||||||
</f:facet>
|
</f:facet>
|
||||||
<h:outputText value="#{r.name}" />
|
<h:outputText value="#{r.firstName}" />
|
||||||
|
</a:column>
|
||||||
|
|
||||||
|
<%-- Last name column --%>
|
||||||
|
<a:column width="120" style="text-align:left" rendered="#{DialogManager.bean.viewMode == 'details'}">
|
||||||
|
<f:facet name="header">
|
||||||
|
<a:sortLink label="#{msg.last_name}" value="lastName" styleClass="header" />
|
||||||
|
</f:facet>
|
||||||
|
<h:outputText value="#{r.lastName}" />
|
||||||
</a:column>
|
</a:column>
|
||||||
|
|
||||||
<%-- Username column --%>
|
<%-- Username column --%>
|
||||||
|
Reference in New Issue
Block a user