diff --git a/config/alfresco/web-client-config-actions.xml b/config/alfresco/web-client-config-actions.xml index f96852836f..0a9a8fc010 100644 --- a/config/alfresco/web-client-config-actions.xml +++ b/config/alfresco/web-client-config-actions.xml @@ -655,12 +655,60 @@ /images/icons/new_edition_icon.gif wizard:newEdition + + + + new_group + /images/icons/create_group.gif + dialog:createGroup + #{DialogManager.setupParameters} + + #{actionContext.group} + #{actionContext.groupName} + + + + + + new_sub_group + /images/icons/create_group.gif + dialog:createGroup + #{DialogManager.setupParameters} + + #{actionContext.group} + #{actionContext.groupName} + + + + + + delete_group + /images/icons/delete_group.gif + dialog:deleteGroup + #{DialogManager.setupParameters} + + #{actionContext.group} + #{actionContext.groupName} + + + + + + add_user + /images/icons/add_user.gif + dialog:addUsers + #{DialogManager.setupParameters} + + #{actionContext.group} + #{actionContext.groupName} + + - + @@ -834,6 +882,22 @@ + + + + + + + + + + + + + + + + diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index 9264710268..d8a1373c28 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -288,6 +288,11 @@ icon="/images/icons/edit_large.gif" title-id="title_edit_file" description-id="editfile_description"/> + + diff --git a/source/java/org/alfresco/web/bean/DocumentDetailsBean.java b/source/java/org/alfresco/web/bean/DocumentDetailsBean.java index 62948759a5..65c7d8a49d 100644 --- a/source/java/org/alfresco/web/bean/DocumentDetailsBean.java +++ b/source/java/org/alfresco/web/bean/DocumentDetailsBean.java @@ -1161,4 +1161,14 @@ public class DocumentDetailsBean extends BaseDetailsBean implements IDialogBean { return baseDialogBean.getActionsContext(); } + + public String getActionsConfigId() + { + return baseDialogBean.getActionsConfigId(); + } + + public String getMoreActionsConfigId() + { + return baseDialogBean.getMoreActionsConfigId(); + } } diff --git a/source/java/org/alfresco/web/bean/SpaceDetailsBean.java b/source/java/org/alfresco/web/bean/SpaceDetailsBean.java index 58930eb0a7..62913cc660 100644 --- a/source/java/org/alfresco/web/bean/SpaceDetailsBean.java +++ b/source/java/org/alfresco/web/bean/SpaceDetailsBean.java @@ -662,4 +662,14 @@ public class SpaceDetailsBean extends BaseDetailsBean implements IDialogBean { return baseDialogBean.getActionsContext(); } + + public String getActionsConfigId() + { + return baseDialogBean.getActionsConfigId(); + } + + public String getMoreActionsConfigId() + { + return baseDialogBean.getMoreActionsConfigId(); + } } diff --git a/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java b/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java index d203781cef..9aee2c2c06 100644 --- a/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java +++ b/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java @@ -203,6 +203,20 @@ public abstract class BaseDialogBean implements IDialogBean return this.navigator.getCurrentNode(); } + public String getActionsConfigId() + { + // nothing by default, subclasses can override if necessary + + return null; + } + + public String getMoreActionsConfigId() + { + // nothing by default, subclasses can override if necessary + + return null; + } + /** * @param browseBean The BrowseBean to set. */ diff --git a/source/java/org/alfresco/web/bean/dialog/DialogManager.java b/source/java/org/alfresco/web/bean/dialog/DialogManager.java index a89eedb659..896f8cc6d6 100644 --- a/source/java/org/alfresco/web/bean/dialog/DialogManager.java +++ b/source/java/org/alfresco/web/bean/dialog/DialogManager.java @@ -74,6 +74,17 @@ public final class DialogManager { // store the parameters this.paramsToApply = ((UIActionLink)component).getParameterMap(); + + // make sure "null" parameters are actually null, this can occur + // when null parameters are sent to the client and posted back + for (String name : this.paramsToApply.keySet()) + { + String value = this.paramsToApply.get(name); + if (value != null && value.equalsIgnoreCase("null")) + { + this.paramsToApply.put(name, null); + } + } } } @@ -286,9 +297,18 @@ public final class DialogManager * * @return The action group id */ - public String getActions() + public String getActionsId() { - return this.currentDialogState.getConfig().getActionsConfigId(); + // first see if the dialog itself has supplied an actions id + String configId = this.currentDialogState.getDialog().getActionsConfigId(); + + if (configId == null) + { + // see if an actions id was specified in the dialog config + configId = this.currentDialogState.getConfig().getActionsConfigId(); + } + + return configId; } /** @@ -297,9 +317,18 @@ public final class DialogManager * * @return The action group id */ - public String getMoreActions() + public String getMoreActionsId() { - return this.currentDialogState.getConfig().getMoreActionsConfigId(); + // first see if the dialog itself has supplied a more actions id + String configId = this.currentDialogState.getDialog().getMoreActionsConfigId(); + + if (configId == null) + { + // see if an actions id was specified in the dialog config + configId = this.currentDialogState.getConfig().getMoreActionsConfigId(); + } + + return configId; } /** diff --git a/source/java/org/alfresco/web/bean/dialog/IDialogBean.java b/source/java/org/alfresco/web/bean/dialog/IDialogBean.java index dc12f01344..d4b00361cd 100644 --- a/source/java/org/alfresco/web/bean/dialog/IDialogBean.java +++ b/source/java/org/alfresco/web/bean/dialog/IDialogBean.java @@ -124,4 +124,18 @@ public interface IDialogBean * @return Object to use as the context for actions */ public Object getActionsContext(); + + /** + * Returns the id of an action group to use for the main actions + * + * @return Id of an action group + */ + public String getActionsConfigId(); + + /** + * Returns the id of an action group to use for the more actions + * + * @return Id of an action group + */ + public String getMoreActionsConfigId(); } diff --git a/source/java/org/alfresco/web/bean/groups/AddUsersDialog.java b/source/java/org/alfresco/web/bean/groups/AddUsersDialog.java index 408ee6ad55..59aaf151fa 100644 --- a/source/java/org/alfresco/web/bean/groups/AddUsersDialog.java +++ b/source/java/org/alfresco/web/bean/groups/AddUsersDialog.java @@ -41,12 +41,13 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; - +import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.PermissionService; - +import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.web.app.Application; -import org.alfresco.web.bean.GroupsDialog; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.bean.groups.GroupsDialog.UserAuthorityDetails; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.SortableSelectItem; import org.alfresco.web.ui.common.Utils; @@ -58,48 +59,57 @@ import org.alfresco.web.ui.common.component.UIGenericPicker; * @author YanO * @author gavinc */ -public class AddUsersDialog extends GroupsDialog +public class AddUsersDialog extends BaseDialogBean { - private static final String BUTTON_FINISH = "finish_button"; + /** The id of the group to add users to */ + protected String group; + + /** Name of the group to add users to */ + protected String groupName; + + /** The AuthorityService to be used by the bean */ + protected AuthorityService authService; + + /** personService bean reference */ + protected PersonService personService; /** selected users to be added to a group */ - private List usersForGroup; + protected List usersForGroup; /** datamodel for table of users added to group */ - private DataModel usersDataModel = null; + protected DataModel usersDataModel = null; + // ------------------------------------------------------------------------------ + // Dialog implementation + @Override public void init(Map parameters) { super.init(parameters); + + // retrieve parameters + this.group = parameters.get(GroupsDialog.PARAM_GROUP); + this.groupName = parameters.get(GroupsDialog.PARAM_GROUP_NAME); + usersForGroup = new ArrayList(); } @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { - try + // add each selected user to the current group in turn + for (UserAuthorityDetails wrapper : this.usersForGroup) { - // add each selected user to the current group in turn - for (UserAuthorityDetails wrapper : this.usersForGroup) - { - properties.getAuthService().addAuthority(properties.getActionGroup(), wrapper.getAuthority()); - } + this.authService.addAuthority(this.group, wrapper.getAuthority()); } - catch (Throwable err) - { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); - outcome = null; - } - setActionGroup(null); + return outcome; } @Override public String getContainerSubTitle() { - return properties.getActionGroupName(); + return this.groupName; } @Override @@ -108,12 +118,37 @@ public class AddUsersDialog extends GroupsDialog return false; } - @Override - public String getFinishButtonLabel() + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + public void setAuthService(AuthorityService authService) { - return Application.getMessage(FacesContext.getCurrentInstance(), BUTTON_FINISH); + this.authService = authService; } + public void setPersonService(PersonService personService) + { + this.personService = personService; + } + + /** + * @return Returns the usersDataModel. + */ + public DataModel getUsersDataModel() + { + if (this.usersDataModel == null) + { + this.usersDataModel = new ListDataModel(); + } + + this.usersDataModel.setWrappedData(this.usersForGroup); + + return this.usersDataModel; + } + + // ------------------------------------------------------------------------------ + // Helpers + /** * Query callback method executed by the Generic Picker component. This * method is part of the contract to the Generic Picker, it is up to the @@ -141,7 +176,7 @@ public class AddUsersDialog extends GroupsDialog // build xpath to match available User/Person objects ServiceRegistry services = Repository.getServiceRegistry(context); - NodeRef peopleRef = properties.getPersonService().getPeopleContainer(); + NodeRef peopleRef = personService.getPeopleContainer(); String xpath = "*[like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "firstName, '%" + contains + "%', false)" + " or " + "like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "lastName, '%" + contains + "%', false)]"; @@ -186,6 +221,9 @@ public class AddUsersDialog extends GroupsDialog } } + // ------------------------------------------------------------------------------ + // Event handlers + /** * Add the selected User to the list for adding to a Group */ @@ -216,10 +254,10 @@ public class AddUsersDialog extends GroupsDialog StringBuilder label = new StringBuilder(48); // build a display label showing the user person name - if (properties.getPersonService().personExists(authority) == true) + if (this.personService.personExists(authority) == true) { // found a Person with a User authority - NodeRef ref = properties.getPersonService().getPerson(authority); + NodeRef ref = this.personService.getPerson(authority); String firstName = (String) this.nodeService.getProperty(ref, ContentModel.PROP_FIRSTNAME); String lastName = (String) this.nodeService.getProperty(ref, ContentModel.PROP_LASTNAME); @@ -248,19 +286,4 @@ public class AddUsersDialog extends GroupsDialog this.usersForGroup.remove(wrapper); } } - - /** - * @return Returns the usersDataModel. - */ - public DataModel getUsersDataModel() - { - if (this.usersDataModel == null) - { - this.usersDataModel = new ListDataModel(); - } - - this.usersDataModel.setWrappedData(this.usersForGroup); - - return this.usersDataModel; - } } diff --git a/source/java/org/alfresco/web/bean/groups/CreateGroupDialog.java b/source/java/org/alfresco/web/bean/groups/CreateGroupDialog.java index 1912660ce3..46b5474e6b 100644 --- a/source/java/org/alfresco/web/bean/groups/CreateGroupDialog.java +++ b/source/java/org/alfresco/web/bean/groups/CreateGroupDialog.java @@ -32,54 +32,57 @@ import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.ValidatorException; +import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.web.app.Application; -import org.alfresco.web.bean.GroupsDialog; - -import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.dialog.BaseDialogBean; import org.alfresco.web.ui.common.Utils; -public class CreateGroupDialog extends GroupsDialog +public class CreateGroupDialog extends BaseDialogBean { + protected String parentGroup; + protected String parentGroupName; + protected String name; + + /** The AuthorityService to be used by the bean */ + protected AuthorityService authService; + private static final String MSG_ERR_EXISTS = "groups_err_exists"; + private static final String MSG_ERR_NAME = "groups_err_group_name"; + private static final String MSG_ROOT_GROUPS = "root_groups"; private static final String MSG_BUTTON_NEW_GROUP = "new_group"; + // ------------------------------------------------------------------------------ + // Dialog implementation + @Override public void init(Map parameters) { super.init(parameters); - properties.setName(""); + + // retrieve parameters + this.parentGroup = parameters.get(GroupsDialog.PARAM_GROUP); + this.parentGroupName = parameters.get(GroupsDialog.PARAM_GROUP_NAME); + + // reset variables + this.name = null; } @Override protected String finishImpl(FacesContext context, String outcome) throws Exception { - try + // create new Group using Authentication Service + String groupName = this.authService.getName(AuthorityType.GROUP, this.name); + if (this.authService.authorityExists(groupName) == false) { - // create new Group using Authentication Service - String groupName = properties.getAuthService().getName(AuthorityType.GROUP, properties.getName()); - if (properties.getAuthService().authorityExists(groupName) == false) - { - properties.getAuthService().createAuthority(AuthorityType.GROUP, properties.getActionGroup(), properties.getName()); - } - else - { - Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_EXISTS)); - outcome = null; - } + this.authService.createAuthority(AuthorityType.GROUP, this.parentGroup, this.name); } - catch (Throwable err) + else { - Utils.addErrorMessage(MessageFormat.format(Application.getMessage( - context, Repository.ERROR_GENERIC), err.getMessage()), err); + Utils.addErrorMessage(Application.getMessage(context, MSG_ERR_EXISTS)); outcome = null; } - if (outcome == null) - { - isFinished = false; - } - return outcome; } @@ -94,17 +97,38 @@ public class CreateGroupDialog extends GroupsDialog { String subtitle = null; - if (properties.getActionGroup() != null) + if (this.parentGroupName != null) { - subtitle = properties.getActionGroupName(); + subtitle = this.parentGroupName; } else { - subtitle = properties.getGroupName(); + subtitle = Application.getMessage(FacesContext.getCurrentInstance(), MSG_ROOT_GROUPS); } return subtitle; } + + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + public String getName() + { + return this.name; + } + + public void setName(String name) + { + this.name = name; + } + + public void setAuthService(AuthorityService authService) + { + this.authService = authService; + } + + // ------------------------------------------------------------------------------ + // Helpers public void validateGroupName(FacesContext context, UIComponent component, Object value) throws ValidatorException { @@ -112,10 +136,9 @@ public class CreateGroupDialog extends GroupsDialog if (name.indexOf('\'') != -1 || name.indexOf('"') != -1 || name.indexOf('\\') != -1) { - String err = MessageFormat.format(Application.getMessage(context, "groups_err_group_name"), + String err = MessageFormat.format(Application.getMessage(context, MSG_ERR_NAME), new Object[] { "', \", \\" }); throw new ValidatorException(new FacesMessage(err)); } } - } diff --git a/source/java/org/alfresco/web/bean/groups/DeleteGroupDialog.java b/source/java/org/alfresco/web/bean/groups/DeleteGroupDialog.java index 121afa760a..da4fb51f22 100644 --- a/source/java/org/alfresco/web/bean/groups/DeleteGroupDialog.java +++ b/source/java/org/alfresco/web/bean/groups/DeleteGroupDialog.java @@ -24,57 +24,106 @@ */ package org.alfresco.web.bean.groups; -import java.text.MessageFormat; +import java.util.Map; import javax.faces.context.FacesContext; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.web.app.Application; -import org.alfresco.web.bean.GroupsDialog; -import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.bean.dialog.BaseDialogBean; -public class DeleteGroupDialog extends GroupsDialog +public class DeleteGroupDialog extends BaseDialogBean { - private static final String BUTTON_DELETE = "delete"; + /** The group to be deleted */ + protected String group = null; + protected String groupName = null; + + /** The number of items the group contains */ + protected int numItemsInGroup = 0; + + /** The AuthorityService to be used by the bean */ + protected AuthorityService authService; + + private static final String MSG_DELETE = "delete"; + private static final String MSG_DELETE_GROUP = "delete_group"; - private static final String MSG_DELETE_GROUP = "delete_group"; + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + public void init(Map parameters) + { + super.init(parameters); - @Override - protected String finishImpl(FacesContext context, String outcome) throws Exception - { - try - { - // delete group using the Authentication Service - properties.getAuthService().deleteAuthority(properties.getActionGroup()); - removeFromBreadcrumb(properties.getActionGroup()); + // retrieve parameters + this.group = parameters.get(GroupsDialog.PARAM_GROUP); + this.groupName = parameters.get(GroupsDialog.PARAM_GROUP_NAME); + + // calculate the number of items the givev group has + if (this.group != null) + { + numItemsInGroup = this.authService.getContainedAuthorities( + AuthorityType.GROUP, this.group, false).size(); + numItemsInGroup += this.authService.getContainedAuthorities( + AuthorityType.USER, this.group, false).size(); + } + } + + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + // delete group using the Authentication Service + this.authService.deleteAuthority(this.group); + + return outcome; + } - // clear action context - setActionGroup(null); - } - catch (Throwable err) - { - // rollback the transaction - Utils.addErrorMessage(MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); - outcome = null; - } - return outcome; - } + @Override + protected String doPostCommitProcessing(FacesContext context, String outcome) + { + // add the group to the request object so it gets picked up by + // groups dialog, this will allow it to be removed from the breadcrumb + context.getExternalContext().getRequestMap().put( + GroupsDialog.KEY_GROUP, this.group); + + return outcome; + } - @Override - public boolean getFinishButtonDisabled() - { - return false; - } + @Override + public boolean getFinishButtonDisabled() + { + return false; + } - @Override - public String getFinishButtonLabel() - { - return Application.getMessage(FacesContext.getCurrentInstance(), BUTTON_DELETE); - } + @Override + public String getFinishButtonLabel() + { + return Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE); + } - @Override - public String getContainerTitle() - { - return Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE_GROUP) + " '" + properties.getActionGroupName() + "'"; - } + @Override + public String getContainerTitle() + { + return Application.getMessage(FacesContext.getCurrentInstance(), MSG_DELETE_GROUP) + " '" + + this.groupName + "'"; + } + + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + public String getGroupName() + { + return this.groupName; + } + + public int getNumItemsInGroup() + { + return this.numItemsInGroup; + } + + public void setAuthService(AuthorityService authService) + { + this.authService = authService; + } } diff --git a/source/java/org/alfresco/web/bean/GroupsDialog.java b/source/java/org/alfresco/web/bean/groups/GroupsDialog.java similarity index 59% rename from source/java/org/alfresco/web/bean/GroupsDialog.java rename to source/java/org/alfresco/web/bean/groups/GroupsDialog.java index 02125d3e10..33a2fa1d48 100644 --- a/source/java/org/alfresco/web/bean/GroupsDialog.java +++ b/source/java/org/alfresco/web/bean/groups/GroupsDialog.java @@ -22,7 +22,7 @@ * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ -package org.alfresco.web.bean; +package org.alfresco.web.bean.groups; import java.text.MessageFormat; import java.util.ArrayList; @@ -38,18 +38,23 @@ import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; 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.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; import org.alfresco.web.bean.dialog.BaseDialogBean; -import org.alfresco.web.bean.groups.GroupsProperties; +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.ui.common.Utils; import org.alfresco.web.ui.common.component.IBreadcrumbHandler; import org.alfresco.web.ui.common.component.UIActionLink; import org.alfresco.web.ui.common.component.UIBreadcrumb; +import org.alfresco.web.ui.common.component.UIListItem; import org.alfresco.web.ui.common.component.UIModeList; +import org.alfresco.web.ui.common.component.data.UIRichList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -58,12 +63,48 @@ import org.apache.commons.logging.LogFactory; * * @author Kevin Roast */ -public class GroupsDialog extends BaseDialogBean implements IContextListener +public class GroupsDialog extends BaseDialogBean + implements IContextListener, FilterViewSupport, ChangeViewSupport { - protected GroupsProperties properties; + public static final String KEY_GROUP = "group"; + public static final String PARAM_GROUP = "group"; + public static final String PARAM_GROUP_NAME = "groupName"; + /** The AuthorityService to be used by the bean */ + protected AuthorityService authService; + + /** personService bean reference */ + protected PersonService personService; + + /** Component references */ + protected UIRichList groupsRichList; + protected UIRichList usersRichList; + + /** Currently visible Group Authority */ + protected String group = null; + protected String groupName = null; + + /** RichList view mode */ + protected String viewMode = VIEW_ICONS; + + /** Filter mode */ + protected String filterMode = FILTER_CHILDREN; + + /** Groups path breadcrumb location */ + protected List location = null; + + private static final String VIEW_ICONS = "icons"; + private static final String VIEW_DETAILS = "details"; private static final String FILTER_CHILDREN = "children"; - private static final String MSG_GROUPS = "root_groups"; + private static final String FILTER_ALL = "all"; + + private static final String LABEL_VIEW_ICONS = "group_icons"; + private static final String LABEL_VIEW_DETAILS = "group_details"; + private static final String LABEL_FILTER_CHILDREN = "group_filter_children"; + private static final String LABEL_FILTER_ALL = "group_filter_all"; + + private static final String MSG_ROOT_GROUPS = "root_groups"; + private static final String MSG_CLOSE = "close"; private static Log logger = LogFactory.getLog(GroupsDialog.class); @@ -79,67 +120,179 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener } // ------------------------------------------------------------------------------ - // Bean property getters and setters + // Dialog implementation - public void setProperties(GroupsProperties properties) + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception { - this.properties = properties; + return null; } + + @Override + public String getContainerSubTitle() + { + String subtitle = null; - /** - * @param filterMode The filterMode to set. - */ + if (this.group != null) + { + subtitle = this.groupName; + } + else + { + subtitle = Application.getMessage(FacesContext.getCurrentInstance(), MSG_ROOT_GROUPS); + } + + return subtitle; + } + + @Override + public String getCancelButtonLabel() + { + return Application.getMessage(FacesContext.getCurrentInstance(), MSG_CLOSE); + } + + @Override + public void restored() + { + Object groupToRemove = FacesContext.getCurrentInstance().getExternalContext(). + getRequestMap().get(KEY_GROUP); + if (groupToRemove != null) + { + if (logger.isDebugEnabled()) + logger.debug("Removing group '" + groupToRemove + "' from breadcrumb"); + + removeFromBreadcrumb((String)groupToRemove); + } + } + + @Override + public Object getActionsContext() + { + return this; + } + + // ------------------------------------------------------------------------------ + // FilterViewSupport implementation + + public List getFilterItems() + { + FacesContext context = FacesContext.getCurrentInstance(); + List items = new ArrayList(2); + + UIListItem item1 = new UIListItem(); + item1.setValue(FILTER_CHILDREN); + item1.setLabel(Application.getMessage(context, LABEL_FILTER_CHILDREN)); + items.add(item1); + + UIListItem item2 = new UIListItem(); + item2.setValue(FILTER_ALL); + item2.setLabel(Application.getMessage(context, LABEL_FILTER_ALL)); + items.add(item2); + + return items; + } + + public void filterModeChanged(ActionEvent event) + { + UIModeList filterList = (UIModeList)event.getComponent(); + + // update list filter mode from user selection + setFilterMode(filterList.getValue().toString()); + } + + public String getFilterMode() + { + return this.filterMode; + } + public void setFilterMode(String filterMode) { - properties.setFilterMode(filterMode); + this.filterMode = filterMode; // clear datalist cache ready to change results based on filter setting contextUpdated(); } - /** - * @param group Set the Group to be used for the current action screen. - */ - public void setActionGroup(String group) + // ------------------------------------------------------------------------------ + // ChangeViewSupport implementation + + public List getViewItems() { - properties.setActionGroup(group); + FacesContext context = FacesContext.getCurrentInstance(); + List items = new ArrayList(2); - if (group != null) - { - // calculate action group metadata - properties.setActionGroupName(properties.getAuthService().getShortName(group)); - int count = properties.getAuthService().getContainedAuthorities(AuthorityType.GROUP, group, false).size(); - count += properties.getAuthService().getContainedAuthorities(AuthorityType.USER, group, false).size(); - properties.setActionGroupItems(count); - } - else - { - properties.setActionGroupName(null); - properties.setActionGroupItems(0); - } + UIListItem item1 = new UIListItem(); + item1.setValue(VIEW_ICONS); + item1.setLabel(Application.getMessage(context, LABEL_VIEW_ICONS)); + items.add(item1); - // clear value used by Create Group form - properties.setName(null); + UIListItem item2 = new UIListItem(); + item2.setValue(VIEW_DETAILS); + item2.setLabel(Application.getMessage(context, LABEL_VIEW_DETAILS)); + items.add(item2); + + return items; } - /** - * Set the current Group Authority. - *

- * Setting this value causes the UI to update and display the specified node as current. - * - * @param group The current group authority. - */ - public void setCurrentGroup(String group, String groupName) + public void viewModeChanged(ActionEvent event) { - if (logger.isDebugEnabled()) - logger.debug("Setting current group: " + group); + UIModeList viewList = (UIModeList)event.getComponent(); - // set the current Group Authority for our UI context operations - properties.setGroup(group); - properties.setGroupName(groupName); - - // inform that the UI needs updating after this change - contextUpdated(); + // update view mode from user selection + setViewMode(viewList.getValue().toString()); + } + + public String getViewMode() + { + return this.viewMode; + } + + public void setViewMode(String viewMode) + { + this.viewMode = viewMode; + } + + // ------------------------------------------------------------------------------ + // Bean property getters and setters + + public String getGroup() + { + return this.group; + } + + public String getGroupName() + { + return this.groupName; + } + + public void setAuthService(AuthorityService authService) + { + this.authService = authService; + } + + public void setPersonService(PersonService personService) + { + this.personService = personService; + } + + public UIRichList getGroupsRichList() + { + return groupsRichList; + } + + public void setGroupsRichList(UIRichList groupsRichList) + { + this.groupsRichList = groupsRichList; + } + + public UIRichList getUsersRichList() + { + return usersRichList; + } + + public void setUsersRichList(UIRichList usersRichList) + { + this.usersRichList = usersRichList; } /** @@ -147,16 +300,16 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener */ public List getLocation() { - if (properties.getLocation() == null) + if (this.location == null) { List loc = new ArrayList(8); loc.add(new GroupBreadcrumbHandler(null, - Application.getMessage(FacesContext.getCurrentInstance(), MSG_GROUPS))); + Application.getMessage(FacesContext.getCurrentInstance(), MSG_ROOT_GROUPS))); - properties.setLocation(loc); + this.location = loc; } - return properties.getLocation(); + return this.location; } /** @@ -175,32 +328,34 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener tx.begin(); Set authorities; - boolean immediate = (properties.getFilterMode().equals(FILTER_CHILDREN)); - if (properties.getGroup() == null) + boolean immediate = (this.filterMode.equals(FILTER_CHILDREN)); + if (this.group == null) { // root groups if (immediate == true) { - authorities = properties.getAuthService().getAllRootAuthorities(AuthorityType.GROUP); + authorities = this.authService.getAllRootAuthorities(AuthorityType.GROUP); } else { - authorities = properties.getAuthService().getAllAuthorities(AuthorityType.GROUP); + authorities = this.authService.getAllAuthorities(AuthorityType.GROUP); } } else { // sub-group of an existing group - authorities = properties.getAuthService().getContainedAuthorities(AuthorityType.GROUP, properties.getGroup(), immediate); + authorities = this.authService.getContainedAuthorities(AuthorityType.GROUP, this.group, immediate); } groups = new ArrayList(authorities.size()); for (String authority : authorities) { Map authMap = new HashMap(3, 1.0f); - String name = properties.getAuthService().getShortName(authority); + String name = this.authService.getShortName(authority); authMap.put("name", name); authMap.put("id", authority); + authMap.put("group", authority); + authMap.put("groupName", name); groups.add(authMap); } @@ -230,31 +385,31 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener try { FacesContext context = FacesContext.getCurrentInstance(); - tx = Repository.getUserTransaction(context); + tx = Repository.getUserTransaction(context, true); tx.begin(); Set authorities; - if (properties.getGroup() == null) + if (this.group == null) { authorities = Collections.emptySet(); } else { // users of an existing group - boolean immediate = (properties.getFilterMode().equals(FILTER_CHILDREN)); - authorities = properties.getAuthService().getContainedAuthorities(AuthorityType.USER, properties.getGroup(), immediate); + boolean immediate = (this.filterMode.equals(FILTER_CHILDREN)); + authorities = this.authService.getContainedAuthorities(AuthorityType.USER, this.group, immediate); } users = new ArrayList(authorities.size()); for (String authority : authorities) { Map authMap = new HashMap(3, 1.0f); - String userName = properties.getAuthService().getShortName(authority); + String userName = this.authService.getShortName(authority); authMap.put("userName", userName); authMap.put("id", authority); // get Person details for this Authority - NodeRef ref = properties.getPersonService().getPerson(authority); + NodeRef ref = this.personService.getPerson(authority); String firstName = (String)this.nodeService.getProperty(ref, ContentModel.PROP_FIRSTNAME); String lastName = (String)this.nodeService.getProperty(ref, ContentModel.PROP_LASTNAME); @@ -283,37 +438,28 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener } /** - * Set the Group to be used for next action dialog + * Set the current Group Authority. + *

+ * Setting this value causes the UI to update and display the specified node as current. + * + * @param group The current group authority. */ - public void setupGroupAction(ActionEvent event) + protected void setCurrentGroup(String group, String groupName) { - UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - String group = params.get("id"); - if (group != null && group.length() != 0) - { - if (logger.isDebugEnabled()) - logger.debug("Setup for action, setting current Group to: " + group); - - // prepare a node for the action context - setActionGroup(group); - - // clear datalist cache ready from return from action dialog - contextUpdated(); - } - } - - /** - * Clear the Group action context - e.g. ready for a Create Root Group operation - */ - public void clearGroupAction(ActionEvent event) - { - setActionGroup(null); + if (logger.isDebugEnabled()) + logger.debug("Setting current group: " + group); - // clear datalist cache ready from return from action dialog + // set the current Group Authority for our UI context operations + this.group = group; + this.groupName = groupName; + + // inform that the UI needs updating after this change contextUpdated(); } + // ------------------------------------------------------------------------------ + // Action handlers + /** * Action called when a Group folder is clicked. * Navigate into the Group and show child Groups and child Users. @@ -340,9 +486,17 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener String authority = params.get("id"); if (authority != null && authority.length() != 0) { + UserTransaction tx = null; try { - properties.getAuthService().removeAuthority(properties.getGroup(), authority); + FacesContext context = FacesContext.getCurrentInstance(); + tx = Repository.getUserTransaction(context); + tx.begin(); + + this.authService.removeAuthority(this.group, authority); + + // commit the transaction + tx.commit(); // refresh UI after change contextUpdated(); @@ -351,45 +505,26 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener { Utils.addErrorMessage(MessageFormat.format(Application.getMessage( FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err); + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} } } } - /** - * Change the current view mode based on user selection - */ - public void viewModeChanged(ActionEvent event) - { - UIModeList viewList = (UIModeList)event.getComponent(); - - // update view mode from user selection - properties.setViewMode(viewList.getValue().toString()); - } - - /** - * Change the current list filter mode based on user selection - */ - public void filterModeChanged(ActionEvent event) - { - UIModeList viewList = (UIModeList)event.getComponent(); - - // update list filter mode from user selection - setFilterMode(viewList.getValue().toString()); - } + // ------------------------------------------------------------------------------ + // Helpers /** * Update the breadcrumb with the clicked Group location */ - private void updateUILocation(String group) + protected void updateUILocation(String group) { - String groupName = properties.getAuthService().getShortName(group); - properties.getLocation().add(new GroupBreadcrumbHandler(group, groupName)); + String groupName = this.authService.getShortName(group); + this.location.add(new GroupBreadcrumbHandler(group, groupName)); this.setCurrentGroup(group, groupName); } - public void removeFromBreadcrumb(String group) + protected void removeFromBreadcrumb(String group) { - // remove this node from the breadcrumb if required List location = getLocation(); GroupBreadcrumbHandler handler = (GroupBreadcrumbHandler) location.get(location.size() - 1); @@ -408,12 +543,6 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener } } - @Override - protected String finishImpl(FacesContext context, String outcome) throws Exception - { - return null; - } - // ------------------------------------------------------------------------------ // IContextListener implementation @@ -426,8 +555,15 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener logger.debug("Invalidating Group Management Components..."); // force a requery of the richlist dataset - properties.getGroupsRichList().setValue(null); - properties.getUsersRichList().setValue(null); + if (this.groupsRichList != null) + { + this.groupsRichList.setValue(null); + } + + if (this.usersRichList != null) + { + this.usersRichList.setValue(null); + } } /** @@ -484,7 +620,7 @@ public class GroupsDialog extends BaseDialogBean implements IContextListener // All group breadcrumb elements relate to a Group // when selected we set the current Group Id and return setCurrentGroup(this.Group, this.Label); - properties.setLocation( (List)breadcrumb.getValue() ); + location = (List)breadcrumb.getValue(); return null; } diff --git a/source/java/org/alfresco/web/bean/groups/GroupsProperties.java b/source/java/org/alfresco/web/bean/groups/GroupsProperties.java deleted file mode 100644 index 22eba2f4da..0000000000 --- a/source/java/org/alfresco/web/bean/groups/GroupsProperties.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.bean.groups; - -import java.util.List; - -import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.web.ui.common.component.IBreadcrumbHandler; -import org.alfresco.web.ui.common.component.data.UIRichList; - -public class GroupsProperties -{ - private static final String FILTER_CHILDREN = "children"; - - /** The AuthorityService to be used by the bean */ - private AuthorityService authService; - - /** personService bean reference */ - private PersonService personService; - - /** Component references */ - private UIRichList groupsRichList; - private UIRichList usersRichList; - - /** Currently visible Group Authority */ - private String group = null; - private String groupName = null; - - /** Action group authority */ - private String actionGroup = null; - private String actionGroupName = null; - private int actionGroupItems = 0; - - /** Dialog properties */ - private String name = null; - - /** RichList view mode */ - private String viewMode = "icons"; - - /** List filter mode */ - private String filterMode = FILTER_CHILDREN; - - /** Groups path breadcrumb location */ - private List location = null; - - public AuthorityService getAuthService() - { - return authService; - } - - public void setAuthService(AuthorityService authService) - { - this.authService = authService; - } - - public PersonService getPersonService() - { - return personService; - } - - public void setPersonService(PersonService personService) - { - this.personService = personService; - } - - public UIRichList getGroupsRichList() - { - return groupsRichList; - } - - public void setGroupsRichList(UIRichList groupsRichList) - { - this.groupsRichList = groupsRichList; - } - - public UIRichList getUsersRichList() - { - return usersRichList; - } - - public void setUsersRichList(UIRichList usersRichList) - { - this.usersRichList = usersRichList; - } - - public String getGroup() - { - return group; - } - - public void setGroup(String group) - { - this.group = group; - } - - public String getGroupName() - { - return groupName; - } - - public void setGroupName(String groupName) - { - this.groupName = groupName; - } - - public String getActionGroup() - { - return actionGroup; - } - - public void setActionGroup(String actionGroup) - { - this.actionGroup = actionGroup; - } - - public String getActionGroupName() - { - return actionGroupName; - } - - public void setActionGroupName(String actionGroupName) - { - this.actionGroupName = actionGroupName; - } - - public int getActionGroupItems() - { - return actionGroupItems; - } - - public void setActionGroupItems(int actionGroupItems) - { - this.actionGroupItems = actionGroupItems; - } - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getViewMode() - { - return viewMode; - } - - public void setViewMode(String viewMode) - { - this.viewMode = viewMode; - } - - public String getFilterMode() - { - return filterMode; - } - - public void setFilterMode(String filterMode) - { - this.filterMode = filterMode; - } - - public List getLocation() - { - return location; - } - - public void setLocation(List location) - { - this.location = location; - } - -} diff --git a/source/java/org/alfresco/web/bean/wizard/WizardManager.java b/source/java/org/alfresco/web/bean/wizard/WizardManager.java index 152c32c02b..838dde8f87 100644 --- a/source/java/org/alfresco/web/bean/wizard/WizardManager.java +++ b/source/java/org/alfresco/web/bean/wizard/WizardManager.java @@ -82,7 +82,18 @@ public final class WizardManager if (component instanceof UIActionLink) { // store the parameters - setupParameters( ((UIActionLink)component).getParameterMap() ); + this.paramsToApply = ((UIActionLink)component).getParameterMap(); + + // make sure "null" parameters are actually null, this can occur + // when null parameters are sent to the client and posted back + for (String name : this.paramsToApply.keySet()) + { + String value = this.paramsToApply.get(name); + if (value != null && value.equalsIgnoreCase("null")) + { + this.paramsToApply.put(name, null); + } + } } } diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 77f78aadc8..01ca94d044 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -562,9 +562,13 @@ The bean that holds state for the Groups Management screens. - GroupsProperties - org.alfresco.web.bean.groups.GroupsProperties + GroupsDialog + org.alfresco.web.bean.groups.GroupsDialog session + + nodeService + #{NodeService} + authService #{AuthorityService} @@ -575,23 +579,6 @@ - - - The bean that holds state for the Groups Management screens. - - GroupsDialog - org.alfresco.web.bean.GroupsDialog - session - - nodeService - #{NodeService} - - - properties - #{GroupsProperties} - - - The bean that holds state for the Category Management screens. @@ -4371,8 +4358,12 @@ #{NodeService} - properties - #{GroupsProperties} + authService + #{AuthorityService} + + + personService + #{PersonService} @@ -4384,12 +4375,8 @@ session - nodeService - #{NodeService} - - - properties - #{GroupsProperties} + authService + #{AuthorityService} @@ -4401,12 +4388,8 @@ session - nodeService - #{NodeService} - - - properties - #{GroupsProperties} + authService + #{AuthorityService} diff --git a/source/web/jsp/dialog/container.jsp b/source/web/jsp/dialog/container.jsp index 1eb35cf51f..ed6ba6df77 100644 --- a/source/web/jsp/dialog/container.jsp +++ b/source/web/jsp/dialog/container.jsp @@ -86,28 +86,28 @@ <%-- Main actions --%> - + <%-- More actions menu --%> - + diff --git a/source/web/jsp/groups/delete-group.jsp b/source/web/jsp/groups/delete-group.jsp index 2f422ce31c..714e33b9e4 100644 --- a/source/web/jsp/groups/delete-group.jsp +++ b/source/web/jsp/groups/delete-group.jsp @@ -34,7 +34,7 @@
- -
- + @@ -62,7 +62,7 @@ diff --git a/source/web/jsp/groups/groups.jsp b/source/web/jsp/groups/groups.jsp index 2deadbd7b9..1c0166674f 100644 --- a/source/web/jsp/groups/groups.jsp +++ b/source/web/jsp/groups/groups.jsp @@ -26,294 +26,108 @@ <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - -<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> -<%@ page isELIgnored="false" %> -<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %> - - - - - - <%-- load a bundle of properties with I18N strings --%> - - - - - <%-- Main outer table --%> -
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %> @@ -46,7 +46,7 @@ - + - +
- - <%-- Title bar --%> - - - - - <%-- Main area --%> - - <%-- Shelf --%> - - <%-- Work Area --%> - - -
- <%@ include file="../parts/titlebar.jsp" %> -
- <%@ include file="../parts/shelf.jsp" %> - - - <%-- Breadcrumb --%> - <%@ include file="../parts/breadcrumb.jsp" %> - - <%-- Status and Actions --%> - - - - - - - <%-- separator row with gradient shadow --%> - - - - - - - <%-- Details --%> - - - - - - - <%-- Error Messages --%> - - - - - - - <%-- separator row with bottom panel graphics --%> - - - - - - -
- - <%-- Status and Actions inner contents table --%> - <%-- Generally this consists of an icon, textual summary and actions for the current object --%> - - - - - - - - - - - - -
- -
-
- <%-- show either root message or the current group name --%> - - -
-
-
- <%-- Create actions menu --%> - - - - - - - - - - - - <%-- More actions menu --%> - - - - - - - - - <%-- TODO: should this be add user(S) - multiple required on generic picker? --%> - - - - - - - <%-- Filter settings --%> - - - - - - <%-- View mode settings --%> - - - - -
-
- - - - - - -
- - <%-- Group Path Breadcrumb --%> -
- -
- - <%-- Groups List --%> -
- - - - - - <%-- Primary column for icons view mode --%> - - - - - - - - - - - - <%-- Primary column for details view mode --%> - - - - - - - - - - - - - - - <%-- Actions column --%> - - - - - - - - - - - - - - - - - - - - -
- - <%-- Users in Group list --%> -
- - - - - - <%-- Primary column for icons view mode --%> - - - - - - - - <%-- Primary column for details view mode --%> - - - - - - - - - - - <%-- Username column --%> - - - - - - - - <%-- Actions column --%> - - - - - - - - - - - - - - -
- -
- <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "greyround", "#F5F5F5"); %> - - - - -
- -
- <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "greyround"); %> -
-
- <%-- messages tag to show messages not handled by other specific message tags --%> - -
-
- - - - + - +<%-- Group Path Breadcrumb --%> + + + + + <%-- Groups List --%> + + + + + <%-- Primary column for icons view mode --%> + + + + + + + + + + + + <%-- Primary column for details view mode --%> + + + + + + + + + + + + + + + <%-- Actions column --%> + + + + + + + + + + + + + + <%-- Users in Group list --%> + + + + + <%-- Primary column for icons view mode --%> + + + + + + + + <%-- Primary column for details view mode --%> + + + + + + + + + + + <%-- Username column --%> + + + + + + + + <%-- Actions column --%> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/web/jsp/groups/new-group.jsp b/source/web/jsp/groups/new-group.jsp index d3523d372a..27db072c8e 100644 --- a/source/web/jsp/groups/new-group.jsp +++ b/source/web/jsp/groups/new-group.jsp @@ -75,7 +75,7 @@ : - *