diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 359f58b79f..088f7238db 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -1934,7 +1934,10 @@ error_domain_mismatch=Domain mismatch: expected = {0}, actual = {1} # Confirmations return_to_application=Return to application delete_space_info=To remove this space and all of its contents, click OK. +delete_space_assoc_info=This space appears in multiple locations, to remove the space from the current location, click OK. delete_space_confirm=Are you sure you want to delete \"{0}\" and all its contents? +delete_space_assoc_confirm=Are you sure you want to remove \"{0}\" from the current location? +delete_space_multiple_parents_warn=This space appears in multiple locations, the operation selected below will therefore effect all locations. delete_forums_info=To remove this forum space and its contents, click OK. delete_forum_info=To remove this forum and its topics, click OK. delete_forum_confirm=Are you sure you want to delete \"{0}\" and all its topics? @@ -1943,7 +1946,10 @@ delete_topic_confirm=Are you sure you want to delete \"{0}\" and all its posts? delete_post_info=To remove this post from the topic, click OK. delete_post_confirm=Are you sure you want to delete the post from \"{0}\"? delete_file_info=To remove this file and any previous versions, click OK. +delete_file_assoc_info=This file appears in multiple locations, to remove the file from the current location, click OK. delete_file_confirm=Are you sure you want to delete \"{0}\" and all previous versions? +delete_file_assoc_confirm=Are you sure you want to remove \"{0}\" from the current location? +delete_file_multiple_parents_confirm=\"{0}\" appears in multiple locations, are you sure you want to remove it from all locations and delete and all previous versions? delete_translation_confirm=Are you sure you want to delete \"{0}\" and all previous versions? Its multilingual properties will not be recoverable. delete_empty_translation_confirm=Are you sure you want to permanently delete \"{0}\"? This document will not be recovered. delete_ml_container_confirm=Are you sure you want to delete \"{0}\" and all previous editions? Each translation will be deleted too. diff --git a/config/alfresco/web-client-config-actions.xml b/config/alfresco/web-client-config-actions.xml index 440b161168..836de3b604 100644 --- a/config/alfresco/web-client-config-actions.xml +++ b/config/alfresco/web-client-config-actions.xml @@ -272,8 +272,7 @@ delete /images/icons/delete.gif - #{BrowseBean.setupDeleteAction} - dialog:deleteSpace + #{BrowseBean.deleteSpace} #{actionContext.id} diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index f497e45216..dfec936242 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -49,6 +49,10 @@ icon="/images/icons/delete_large.gif" title-id="delete_space" description-id="delete_space_info" /> + + + + diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java index 22c8f39f1e..07b9504879 100644 --- a/source/java/org/alfresco/web/bean/BrowseBean.java +++ b/source/java/org/alfresco/web/bean/BrowseBean.java @@ -37,7 +37,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import javax.faces.application.NavigationHandler; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.event.ActionEvent; @@ -69,6 +68,7 @@ import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; @@ -2140,7 +2140,6 @@ public class BrowseBean implements IContextListener, Serializable * * @param event The event */ - public void deleteFile(ActionEvent event) { setupContentAction(event); @@ -2187,12 +2186,103 @@ public class BrowseBean implements IContextListener, Serializable } // if there isn't a working copy go to normal delete dialog + boolean hasMultipleParents = false; + boolean showDeleteAssocDialog = false; + + // get type of node being deleted + Node node = this.getDocument(); + QName type = node.getType(); + TypeDefinition typeDef = this.dictionaryService.getType(type); + + // determine if the node being delete has multiple parents + if (!type.equals(ContentModel.TYPE_MULTILINGUAL_CONTAINER) && + !node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_EMPTY_TRANSLATION) && + !node.hasAspect(ContentModel.ASPECT_MULTILINGUAL_DOCUMENT) && + !type.equals(ContentModel.TYPE_LINK) && + !this.dictionaryService.isSubClass(typeDef.getName(), ContentModel.TYPE_LINK)) + { + List parents = this.nodeService.getParentAssocs(node.getNodeRef(), + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + if (parents != null && parents.size() > 1) + { + hasMultipleParents = true; + } + } + + // determine which delete dialog to display + if (this.navigator.getSearchContext() == null && hasMultipleParents) + { + // if we are not in a search and the node has multiple parents + // see if the current node has the primary parent association + NodeRef parentSpace = this.navigator.getCurrentNode().getNodeRef(); + ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); + + // show delete assoc dialog if the current space is not the primary parent for the node + showDeleteAssocDialog = !parentSpace.equals(assoc.getParentRef()); + } + + // show the appropriate dialog FacesContext fc = FacesContext.getCurrentInstance(); - NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler(); - navigationHandler.handleNavigation(fc, null, "dialog:deleteFile"); + if (showDeleteAssocDialog) + { + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:deleteFileAssoc"); + } + else + { + final Map dialogParams = new HashMap(1); + dialogParams.put("hasMultipleParents", Boolean.toString(hasMultipleParents)); + Application.getDialogManager().setupParameters(dialogParams); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:deleteFile"); + } } } + /** + * Handles the deleteSpace action by deciding which delete dialog to display + */ + public void deleteSpace(ActionEvent event) + { + setupDeleteAction(event); + + boolean hasMultipleParents = false; + boolean showDeleteAssocDialog = false; + + // determine if the node being delete has multiple parents + Node node = this.getActionSpace(); + List parents = this.nodeService.getParentAssocs(node.getNodeRef(), + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + if (parents != null && parents.size() > 1) + { + hasMultipleParents = true; + } + + // determine which delete dialog to display + if (this.navigator.getSearchContext() == null && hasMultipleParents) + { + // if we are not in a search and the node has multiple parents + // see if the current node has the primary parent association + NodeRef parentSpace = this.navigator.getCurrentNode().getNodeRef(); + ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); + + // show delete assoc dialog if the current space is not the primary parent for the node + showDeleteAssocDialog = !parentSpace.equals(assoc.getParentRef()); + } + + // show the appropriate dialog + FacesContext fc = FacesContext.getCurrentInstance(); + if (showDeleteAssocDialog) + { + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:deleteSpaceAssoc"); + } + else + { + final Map dialogParams = new HashMap(1); + dialogParams.put("hasMultipleParents", Boolean.toString(hasMultipleParents)); + Application.getDialogManager().setupParameters(dialogParams); + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:deleteSpace"); + } + } + // ------------------------------------------------------------------------------ // Inner classes diff --git a/source/java/org/alfresco/web/bean/admin/ImportDialog.java b/source/java/org/alfresco/web/bean/admin/ImportDialog.java index d24bd9a72c..e1cfcb0ba0 100644 --- a/source/java/org/alfresco/web/bean/admin/ImportDialog.java +++ b/source/java/org/alfresco/web/bean/admin/ImportDialog.java @@ -194,7 +194,7 @@ public class ImportDialog extends BaseDialogBean public String getFileUploadSuccessMsg() { String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success"); - return MessageFormat.format(msg, new Object[] {getFileName()}); + return MessageFormat.format(msg, new Object[] {Utils.encode(getFileName())}); } /** diff --git a/source/java/org/alfresco/web/bean/coci/CheckinCheckoutDialog.java b/source/java/org/alfresco/web/bean/coci/CheckinCheckoutDialog.java index b9b43fa177..64c19758f9 100644 --- a/source/java/org/alfresco/web/bean/coci/CheckinCheckoutDialog.java +++ b/source/java/org/alfresco/web/bean/coci/CheckinCheckoutDialog.java @@ -151,7 +151,7 @@ public class CheckinCheckoutDialog extends BaseDialogBean public String getFileUploadSuccessMsg() { String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success"); - return MessageFormat.format(msg, new Object[] {getFileName()}); + return MessageFormat.format(msg, new Object[] {Utils.encode(getFileName())}); } /** diff --git a/source/java/org/alfresco/web/bean/content/AddContentDialog.java b/source/java/org/alfresco/web/bean/content/AddContentDialog.java index ffa5fb37c5..a779fddd5c 100644 --- a/source/java/org/alfresco/web/bean/content/AddContentDialog.java +++ b/source/java/org/alfresco/web/bean/content/AddContentDialog.java @@ -51,6 +51,7 @@ import org.alfresco.web.app.Application; import org.alfresco.web.bean.FileUploadBean; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.ui.common.Utils; /** * Bean implementation for the "Add Content" dialog @@ -183,7 +184,7 @@ public class AddContentDialog extends BaseContentWizard // get the file upload message String msg = Application.getMessage(FacesContext.getCurrentInstance(), "file_upload_success"); - return MessageFormat.format(msg, new Object[] {getFileName()}); + return MessageFormat.format(msg, new Object[] {Utils.encode(getFileName())}); } /** diff --git a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java index af17b91a5c..5a6b074e57 100644 --- a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java +++ b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java @@ -300,7 +300,7 @@ public class CreateContentWizard extends BaseContentWizard new String[] {bundle.getString("file_name"), bundle.getString("type"), bundle.getString("content_type")}, - new String[] {this.fileName, getSummaryObjectType(), + new String[] {Utils.encode(this.fileName), getSummaryObjectType(), getSummaryMimeType(this.mimeType)}); } diff --git a/source/java/org/alfresco/web/bean/content/DeleteContentAssociationDialog.java b/source/java/org/alfresco/web/bean/content/DeleteContentAssociationDialog.java new file mode 100755 index 0000000000..7f43a42fe9 --- /dev/null +++ b/source/java/org/alfresco/web/bean/content/DeleteContentAssociationDialog.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2008 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.content; + +import java.text.MessageFormat; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean implementation for the "Delete Content Association" dialog + * + * @author valerysh + * @author gavinc + */ +public class DeleteContentAssociationDialog extends DeleteContentDialog +{ + + private static final Log logger = LogFactory.getLog(DeleteContentAssociationDialog.class); + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + protected String finishImpl(FacesContext context, String outcome) + throws Exception + { + // get the content to delete + Node node = this.browseBean.getDocument(); + + if (node != null) + { + if (logger.isDebugEnabled()) + logger.debug("Trying to delete content node association: " + node.getId()); + + NodeRef parentRef = this.navigator.getCurrentNode().getNodeRef(); + QName qname = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + QName.createValidLocalName(node.getName())); + ChildAssociationRef childAssocRef = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + parentRef, qname, node.getNodeRef()); + + // remove the child association + this.getNodeService().removeChildAssociation(childAssocRef); + } + else + { + logger.warn("WARNING: delete called without a current Document!"); + } + + return outcome; + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + String fileConfirmMsg = null; + + Node document = this.browseBean.getDocument(); + + fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_file_assoc_confirm"); + + return MessageFormat.format(fileConfirmMsg, + new Object[] {document.getName()}); + } +} diff --git a/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java b/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java index a016a0c20e..55e30be5ae 100644 --- a/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java +++ b/source/java/org/alfresco/web/bean/content/DeleteContentDialog.java @@ -142,8 +142,17 @@ public class DeleteContentDialog extends BaseDialogBean } else { - fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), - "delete_file_confirm"); + String strHasMultipleParents = this.parameters.get("hasMultipleParents"); + if (strHasMultipleParents != null && "true".equals(strHasMultipleParents)) + { + fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_file_multiple_parents_confirm"); + } + else + { + fileConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_file_confirm"); + } } return MessageFormat.format(fileConfirmMsg, diff --git a/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java b/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java index 27aee39385..677591faf4 100644 --- a/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java +++ b/source/java/org/alfresco/web/bean/content/DocumentDetailsDialog.java @@ -486,7 +486,7 @@ public class DocumentDetailsDialog extends BaseDetailsBean implements Navigatio if (this.getNodeService().exists(ref)) { builder.append("
  • "); - builder.append(Repository.getNameForNode(this.getNodeService(), ref)); + builder.append(Utils.encode(Repository.getNameForNode(this.getNodeService(), ref))); builder.append("
  • "); } } diff --git a/source/java/org/alfresco/web/bean/rules/CreateRuleWizard.java b/source/java/org/alfresco/web/bean/rules/CreateRuleWizard.java index 194e5df4ea..3bb0d909f4 100644 --- a/source/java/org/alfresco/web/bean/rules/CreateRuleWizard.java +++ b/source/java/org/alfresco/web/bean/rules/CreateRuleWizard.java @@ -206,7 +206,7 @@ public class CreateRuleWizard extends BaseActionWizard StringBuilder conditionsSummary = new StringBuilder(); for (Map props : this.allConditionsProperties) { - conditionsSummary.append(props.get(PROP_CONDITION_SUMMARY)); + conditionsSummary.append(Utils.encode((String)props.get(PROP_CONDITION_SUMMARY))); conditionsSummary.append("
    "); } @@ -214,7 +214,7 @@ public class CreateRuleWizard extends BaseActionWizard StringBuilder actionsSummary = new StringBuilder(); for (Map props : this.allActionsProperties) { - actionsSummary.append(props.get(PROP_ACTION_SUMMARY)); + actionsSummary.append(Utils.encode((String)props.get(PROP_ACTION_SUMMARY))); actionsSummary.append("
    "); } diff --git a/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java b/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java index a5f40ad73d..08da4853b3 100644 --- a/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java +++ b/source/java/org/alfresco/web/bean/spaces/CreateSpaceWizard.java @@ -479,7 +479,7 @@ public class CreateSpaceWizard extends BaseWizardBean return buildSummary( new String[] {bundle.getString("space_type"), bundle.getString("name"), bundle.getString("description"), bundle.getString("creating_from")}, - new String[] {spaceTypeLabel, this.name, Utils.encode(this.description), summaryCreateType}); + new String[] {spaceTypeLabel, Utils.encode(this.name), Utils.encode(this.description), summaryCreateType}); } /** diff --git a/source/java/org/alfresco/web/bean/spaces/DeleteSpaceAssociationDialog.java b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceAssociationDialog.java new file mode 100755 index 0000000000..ceda4a915a --- /dev/null +++ b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceAssociationDialog.java @@ -0,0 +1,104 @@ +/* + * 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.spaces; + +import java.text.MessageFormat; + +import javax.faces.context.FacesContext; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Node; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Bean implementation for the "Delete Space" dialog + * + * @author gavinc + */ +public class DeleteSpaceAssociationDialog extends DeleteSpaceDialog +{ + private static final Log logger = LogFactory.getLog(DeleteSpaceAssociationDialog.class); + + // ------------------------------------------------------------------------------ + // Dialog implementation + + @Override + protected String finishImpl(FacesContext context, String outcome) + throws Exception + { + // get the space to delete + Node node = this.browseBean.getActionSpace(); + if (node != null) + { + if (logger.isDebugEnabled()) + logger.debug("Trying to delete space association: " + node.getId()); + + NodeRef parentRef = this.navigator.getCurrentNode().getNodeRef(); + QName qname = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + QName.createValidLocalName(node.getName())); + ChildAssociationRef childAssocRef = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + parentRef, qname, node.getNodeRef()); + + // remove the child association + this.getNodeService().removeChildAssociation(childAssocRef); + } + else + { + logger.warn("WARNING: delete called without a current Space!"); + } + + return outcome; + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + /** + * Returns the confirmation to display to the user before deleting the content. + * + * @return The formatted message to display + */ + public String getConfirmMessage() + { + Node node = this.browseBean.getActionSpace(); + if (node != null) + { + String spaceConfirmMsg = Application.getMessage(FacesContext.getCurrentInstance(), + "delete_space_assoc_confirm"); + return MessageFormat.format(spaceConfirmMsg, new Object[] {node.getName()}); + } + else + { + return Application.getMessage(FacesContext.getCurrentInstance(), + "delete_node_not_found"); + } + } +} diff --git a/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java index 47883bebb4..6f4e86face 100644 --- a/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java +++ b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java @@ -27,6 +27,7 @@ package org.alfresco.web.bean.spaces; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.faces.context.FacesContext; import javax.transaction.UserTransaction; @@ -65,10 +66,25 @@ public class DeleteSpaceDialog extends BaseDialogBean private String deleteMode = DELETE_ALL; + protected boolean hasMultipleParents = false; // ------------------------------------------------------------------------------ // Dialog implementation + @Override + public void init(Map parameters) + { + super.init(parameters); + + this.hasMultipleParents = false; + + String strHasMultipleParents = this.parameters.get("hasMultipleParents"); + if (strHasMultipleParents != null && "true".equals(strHasMultipleParents)) + { + this.hasMultipleParents = true; + } + } + @Override protected String finishImpl(FacesContext context, String outcome) throws Exception @@ -249,4 +265,12 @@ public class DeleteSpaceDialog extends BaseDialogBean { this.deleteMode = deleteMode; } + + /** + * @return true if the space has multiple parents + */ + public boolean getHasMultipleParents() + { + return this.hasMultipleParents; + } } diff --git a/source/java/org/alfresco/web/bean/trashcan/TrashcanDialog.java b/source/java/org/alfresco/web/bean/trashcan/TrashcanDialog.java index 7931f05448..b8959d4dab 100644 --- a/source/java/org/alfresco/web/bean/trashcan/TrashcanDialog.java +++ b/source/java/org/alfresco/web/bean/trashcan/TrashcanDialog.java @@ -754,7 +754,7 @@ public class TrashcanDialog extends BaseDialogBean implements IContextListener } buf.append(""); buf.append(""); - buf.append(node.getName()); + buf.append(Utils.encode(node.getName())); buf.append(""); if (report) @@ -790,12 +790,12 @@ public class TrashcanDialog extends BaseDialogBean implements IContextListener ChildAssociationRef childRef = (ChildAssociationRef)node.getProperties().get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC); if (getNodeService().exists(childRef.getParentRef())) { - buf.append(Repository.getNamePath(getNodeService(), getNodeService().getPath(childRef.getParentRef()), null, "/", null)); + buf.append(Utils.encode(Repository.getNamePath(getNodeService(), getNodeService().getPath(childRef.getParentRef()), null, "/", null))); } } else { - buf.append(Repository.getNamePath(getNodeService(), getNodeService().getPath(node.getNodeRef()), null, "/", null)); + buf.append(Utils.encode(Repository.getNamePath(getNodeService(), getNodeService().getPath(node.getNodeRef()), null, "/", null))); } buf.append(""); } diff --git a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java index 48e04c2449..98a121691b 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java @@ -159,7 +159,7 @@ public class AVMEditBean extends BaseDialogBean public String getFileUploadSuccessMsg() { final String msg = Application.getMessage(FacesContext.getCurrentInstance(), MSG_UPLOAD_SUCCESS); - return MessageFormat.format(msg, new Object[] { this.getFileName() }); + return MessageFormat.format(msg, new Object[] { Utils.encode(this.getFileName()) }); } // ------------------------------------------------------------------------------ diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index f63c0a913f..26a01dd8b6 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -866,8 +866,19 @@ public class CreateWebContentWizard extends CreateContentWizard final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); // TODO: show first few lines of content here? - return this.buildSummary(new String[] { bundle.getString("file_name"), bundle.getString("type"), bundle.getString("content_type") }, new String[] { this.getFileName(), - this.getSummaryObjectType(), this.getSummaryMimeType(this.mimeType) }); + return this.buildSummary( + new String[] + { + bundle.getString("file_name"), + bundle.getString("type"), + bundle.getString("content_type") + }, + new String[] + { + Utils.encode(this.getFileName()), + this.getSummaryObjectType(), + this.getSummaryMimeType(this.mimeType) + }); } public boolean getEditMode() diff --git a/source/java/org/alfresco/web/ui/common/Utils.java b/source/java/org/alfresco/web/ui/common/Utils.java index 02db405535..908ad5b627 100644 --- a/source/java/org/alfresco/web/ui/common/Utils.java +++ b/source/java/org/alfresco/web/ui/common/Utils.java @@ -86,6 +86,8 @@ import org.springframework.web.jsf.FacesContextUtils; */ public final class Utils extends StringUtils { + public static final String USER_AGENT_FIREFOX = "Firefox"; + public static final String USER_AGENT_MSIE = "MSIE"; private static final String MSG_TIME_PATTERN = "time_pattern"; private static final String MSG_DATE_PATTERN = "date_pattern"; private static final String MSG_DATE_TIME_PATTERN = "date_time_pattern"; @@ -507,6 +509,26 @@ public final class Utils extends StringUtils { return buildImageTag(context, image, width, height, alt, onclick, null); } + + /** + * Build a context path safe image tag for the supplied image path. + * Image path should be supplied with a leading slash '/'. + * + * @param context FacesContext + * @param image The local image path from the web folder with leading slash '/' + * @param width Width in pixels + * @param height Height in pixels + * @param alt Optional alt/title text + * @param onclick JavaScript onclick event handler code + * @param verticalAlign Optional HTML alignment value + * + * @return Populated img tag + */ + public static String buildImageTag(FacesContext context, String image, int width, int height, + String alt, String onclick, String verticalAlign) + { + return buildImageTag(context, image, width, height, alt, onclick, verticalAlign, null); + } /** * Build a context path safe image tag for the supplied image path. @@ -518,16 +540,17 @@ public final class Utils extends StringUtils * @param height Height in pixels * @param alt Optional alt/title text * @param onclick JavaScript onclick event handler code - * @param verticalAlign Optional HTML alignment value + * @param verticalAlign Optional HTML alignment value + * @param style Optional inline CSS styling * * @return Populated img tag */ public static String buildImageTag(FacesContext context, String image, int width, int height, - String alt, String onclick, String verticalAlign) + String alt, String onclick, String verticalAlign, String style) { StringBuilder buf = new StringBuilder(200); - String style = "border-width:0px;"; + style = style != null ? "border-width:0px; " + style : "border-width:0px;"; buf.append("'); - out.write(value.toString()); + out.write(Utils.encode(value.toString())); out.write(""); } else { - out.write(value.toString()); + out.write(Utils.encode(value.toString())); } } } diff --git a/source/java/org/alfresco/web/ui/common/component/UISelectList.java b/source/java/org/alfresco/web/ui/common/component/UISelectList.java index 1819f79746..d63032817f 100644 --- a/source/java/org/alfresco/web/ui/common/component/UISelectList.java +++ b/source/java/org/alfresco/web/ui/common/component/UISelectList.java @@ -350,7 +350,7 @@ public class UISelectList extends UIInput implements NamingContainer out.write("' id='"); out.write(id); out.write("' value='"); - out.write(itemValue); + out.write(Utils.encode(itemValue)); out.write("'"); if (this.onchange != null) { @@ -399,12 +399,12 @@ public class UISelectList extends UIInput implements NamingContainer Utils.outputAttribute(out, getAttributes().get("itemStyle"), "style"); Utils.outputAttribute(out, getAttributes().get("itemStyleClass"), "class"); out.write(">
    "); - out.write(item.getLabel()); + out.write(Utils.encode(item.getLabel())); out.write("
    "); if (description != null) { out.write("
    "); - out.write(description); + out.write(Utils.encode(description)); out.write("
    "); } out.write(""); diff --git a/source/java/org/alfresco/web/ui/common/component/UIStatusMessage.java b/source/java/org/alfresco/web/ui/common/component/UIStatusMessage.java index 85691d110e..69bd1fc2bd 100644 --- a/source/java/org/alfresco/web/ui/common/component/UIStatusMessage.java +++ b/source/java/org/alfresco/web/ui/common/component/UIStatusMessage.java @@ -174,7 +174,7 @@ public class UIStatusMessage extends SelfRenderingComponent implements Serializa out.write(" "); - out.write(msg.getSummary()); + out.write(Utils.encode(msg.getSummary())); out.write(" - "); out.write(Utils.encode(msg.getDetail())); out.write(""); diff --git a/source/java/org/alfresco/web/ui/common/component/data/UIDataPager.java b/source/java/org/alfresco/web/ui/common/component/data/UIDataPager.java index 6e88107415..ad0e6f4c5a 100644 --- a/source/java/org/alfresco/web/ui/common/component/data/UIDataPager.java +++ b/source/java/org/alfresco/web/ui/common/component/data/UIDataPager.java @@ -45,6 +45,7 @@ import org.alfresco.web.app.Application; import org.alfresco.web.data.IDataContainer; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.WebResources; +import org.springframework.util.StringUtils; /** * @author Kevin Roast @@ -59,7 +60,9 @@ public class UIDataPager extends UICommand private static final String FIRST_PAGE = "first_page"; private static final String MSG_PAGEINFO = "page_info"; - + private static final int VISIBLE_PAGE_RANGE = 3; + private static final int AMOUNT_FIRST_PAGES = 7; + // ------------------------------------------------------------------------------ // Construction @@ -100,11 +103,45 @@ public class UIDataPager extends UICommand int currentPage = dataContainer.getCurrentPage(); int pageCount = dataContainer.getPageCount(); - buf.append(""); + } + + buf.append(beginTag); if (getAttributes().get("style") != null) { buf.append(" style=\"") .append(getAttributes().get("style")) + .append(divStyle) .append('"'); } if (getAttributes().get("styleClass") != null) @@ -113,10 +150,10 @@ public class UIDataPager extends UICommand .append(getAttributes().get("styleClass")); } buf.append('>'); - + // output Page X of Y text buf.append(MessageFormat.format(bundle.getString(MSG_PAGEINFO), new Object[] { - Integer.toString(currentPage + 1), // current page can be zero if no data present + inputPageNumber.toString(), // current page can be zero if no data present Integer.toString(pageCount) })); @@ -129,12 +166,12 @@ public class UIDataPager extends UICommand buf.append(""); - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_FIRSTPAGE, 16, 16, bundle.getString(FIRST_PAGE))); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_FIRSTPAGE, 16, 16, bundle.getString(FIRST_PAGE), null, imageVericalAlign, imageStyle)); buf.append(""); } else { - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_FIRSTPAGE_NONE, 16, 16, null)); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_FIRSTPAGE_NONE, 16, 16, null, null, imageVericalAlign, imageStyle)); } buf.append(" "); @@ -145,84 +182,44 @@ public class UIDataPager extends UICommand buf.append(""); - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_PREVIOUSPAGE, 16, 16, bundle.getString(PREVIOUS_PAGE))); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_PREVIOUSPAGE, 16, 16, bundle.getString(PREVIOUS_PAGE), null, imageVericalAlign, imageStyle)); buf.append(""); } else { - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_PREVIOUSPAGE_NONE, 16, 16, null)); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_PREVIOUSPAGE_NONE, 16, 16, null, null, imageVericalAlign, imageStyle)); } buf.append(" "); - // clickable digits for pages 1 to 10 - int totalIndex = (pageCount < 10 ? pageCount : 10); - for (int i=0; i") - .append(i + 1) - .append(" "); + type = PagerType.valueOf((String)objType); } - else + catch (Throwable ex) { - buf.append("") - .append(i + 1) - .append(" "); + s_logger.warn("DataPager id:" + this.getId() + " with incorrect 'numberPageType' attribute"); } } - // clickable digits for pages 20 to 100 (in jumps of 10) - if (pageCount >= 20) + + switch (type) { - buf.append("... "); - totalIndex = (pageCount / 10) * 10; - totalIndex = (totalIndex < 100 ? totalIndex : 100); - for (int i=19; i") - .append(i + 1) - .append(" "); - } - else - { - buf.append("") - .append(i + 1) - .append(" "); - } - } - } - // clickable digits for last page if > 10 and not already shown - if ((pageCount > 10) && (pageCount % 10 != 0)) - { - if (pageCount-1 != currentPage) - { - if (pageCount < 20) - { - buf.append("... "); - } - buf.append("") - .append(pageCount) - .append(" "); - } - else - { - if (pageCount < 20) - { - buf.append("... "); - } - buf.append("") - .append(pageCount) - .append(" "); - } + case STANDARD: + encodeType0(buf, currentPage, pageCount); + break; + case DECADES: + encodeType1(buf, currentPage, pageCount); + break; + case TRACKPAGE: + encodeType2(buf, currentPage, pageCount); + break; + default: + encodeType2(buf, currentPage, pageCount); } // next page @@ -231,12 +228,12 @@ public class UIDataPager extends UICommand buf.append(""); - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_NEXTPAGE, 16, 16, bundle.getString(NEXT_PAGE))); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_NEXTPAGE, 16, 16, bundle.getString(NEXT_PAGE), null, imageVericalAlign, imageStyle)); buf.append(""); } else { - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_NEXTPAGE_NONE, 16, 16, null)); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_NEXTPAGE_NONE, 16, 16, null, null, imageVericalAlign, imageStyle)); } buf.append(" "); @@ -247,18 +244,256 @@ public class UIDataPager extends UICommand buf.append(""); - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_LASTPAGE, 16, 16, bundle.getString(LAST_PAGE))); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_LASTPAGE, 16, 16, bundle.getString(LAST_PAGE), null, imageVericalAlign, imageStyle)); buf.append(""); } else { - buf.append(Utils.buildImageTag(context, WebResources.IMAGE_LASTPAGE_NONE, 16, 16, null)); + buf.append(Utils.buildImageTag(context, WebResources.IMAGE_LASTPAGE_NONE, 16, 16, null, null, imageVericalAlign, imageStyle)); } - buf.append(""); + buf.append(endTag); out.write(buf.toString()); } + + private void createClicableDigitForPage(int num, StringBuilder buf) + { + buf.append("") + .append(num + 1) + .append(" "); + } + + private void createDigitForPage(int num, StringBuilder buf) + { + buf.append("") + .append(num + 1) + .append(" "); + } + + private void encodeType0(StringBuilder buf, int currentPage, int pageCount) + { + int totalIndex = (pageCount < 10 ? pageCount : 10); + for (int i=0; i= 20) + { + buf.append("... "); + totalIndex = (pageCount / 10) * 10; + totalIndex = (totalIndex < 100 ? totalIndex : 100); + for (int i=19; i 10 and not already shown + if ((pageCount > 10) && (pageCount % 10 != 0)) + { + if (pageCount-1 != currentPage) + { + if (pageCount < 20) + { + buf.append("... "); + } + + createClicableDigitForPage(pageCount - 1, buf); + } + else + { + if (pageCount < 20) + { + buf.append("... "); + } + createDigitForPage(pageCount - 1, buf); + } + } + } + + private void encodeType1(StringBuilder buf, int currentPage, int pageCount) + { + // clickable digits for pages 1 to 10 + int totalIndex = (pageCount < 10 ? pageCount : 10); + int number = -1; + if (currentPage == 0) + { + number = generateClickableDigitForPageCurrent(currentPage, pageCount, buf, false, currentPage + VISIBLE_PAGE_RANGE + 1 < pageCount); + } + + if (currentPage > VISIBLE_PAGE_RANGE + 1) + { + createClicableDigitForPage(0, buf); + } + + if (currentPage <= 9 && currentPage != 0) + { + number = generateClickableDigitForPageCurrent(currentPage, pageCount, buf, currentPage > VISIBLE_PAGE_RANGE + 1, currentPage + VISIBLE_PAGE_RANGE + 1 < pageCount); + } + + // clickable digits for pages 20 to 100, 101 to 200, ... (in jumps of 10) + if (number <= 9 && currentPage < 100 && pageCount > 9) + { + createClicableDigitForPage(9, buf); + } + + // clickable digits for pages 20 to 100 (in jumps of 10) + if (pageCount >= 10) + { + int i = 19; + totalIndex = (pageCount / 10) * 10; + totalIndex = (totalIndex < 100 ? totalIndex : 100); + int stepIndex = (currentPage + 1) / 100; + if (stepIndex > 0) + { + i = (100 * stepIndex); + totalIndex = i + 100; + i--; + if (pageCount < totalIndex) + { + totalIndex = pageCount; + } + } + for (; i < totalIndex; i += 10) + { + if (i <= currentPage && currentPage <= (i + VISIBLE_PAGE_RANGE)) + { + generateClickableDigitForPageCurrent(currentPage, pageCount, buf, true, (currentPage + 1 + VISIBLE_PAGE_RANGE) < totalIndex); + continue; + } + if (currentPage < i && currentPage > (i-10 + VISIBLE_PAGE_RANGE)) + { + number = generateClickableDigitForPageCurrent(currentPage, pageCount, buf, true, (currentPage + VISIBLE_PAGE_RANGE + 2) < totalIndex); + if (number + 1 < pageCount) + { + buf.append("... "); + } + if (currentPage + VISIBLE_PAGE_RANGE >= i) + { + continue; + } + } + if (i != currentPage) + { + createClicableDigitForPage(i, buf); + } + else + { + createDigitForPage(i, buf); + } + } + } + + // clickable digits for last page + if (number != pageCount && totalIndex < pageCount) + { + if (pageCount > number) + { + createClicableDigitForPage(pageCount - 1, buf); + } + else + { + createDigitForPage(pageCount - 1, buf); + } + } + } + + private void encodeType2(StringBuilder buf, int currentPage, int pageCount) + { + int number = AMOUNT_FIRST_PAGES; + if (currentPage + VISIBLE_PAGE_RANGE < AMOUNT_FIRST_PAGES) + { + int totalIndex = AMOUNT_FIRST_PAGES < pageCount ? AMOUNT_FIRST_PAGES : pageCount; + for (int i = 0; i < totalIndex; i++) + { + if (i != currentPage) + { + createClicableDigitForPage(i, buf); + } + else + { + createDigitForPage(i, buf); + } + } + if (currentPage + VISIBLE_PAGE_RANGE + 1 < pageCount) + { + buf.append("... "); + } + } + else + { + createClicableDigitForPage(0, buf); + number = generateClickableDigitForPageCurrent(currentPage, pageCount, buf, currentPage > VISIBLE_PAGE_RANGE + 1, (currentPage + 1 + VISIBLE_PAGE_RANGE) < pageCount); + } + + if (number < pageCount) + { + if (pageCount > number) + { + createClicableDigitForPage(pageCount - 1, buf); + } + else + { + createDigitForPage(pageCount - 1, buf); + } + } + } + + //clickable digits for pages current page - 3 and current page + 3 + private int generateClickableDigitForPageCurrent(int currentPage, int pageCount, StringBuilder buf, boolean startDivider, boolean finishDivider) + { + int startPage = currentPage - VISIBLE_PAGE_RANGE; + if (startPage < 0) + { + startPage = 0; + } + if (startDivider) + { + buf.append("... "); + } + for (int i = startPage; i < currentPage; i++) + { + createClicableDigitForPage(i, buf); + } + + buf.append("") + .append(currentPage + 1) + .append(" "); + + int i = currentPage + 1; + int finishPage = currentPage + VISIBLE_PAGE_RANGE; + if (finishPage >= pageCount) + { + finishPage = pageCount - 1; + } + for (; i <= finishPage; i++) + { + createClicableDigitForPage(i, buf); + } + if (finishDivider) + { + buf.append("... "); + } + + return i; + } /** * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext) @@ -332,6 +567,63 @@ public class UIDataPager extends UICommand return dataContainer.getClientId(getFacesContext()) + NamingContainer.SEPARATOR_CHAR + "pager"; } + /** + * Output the JavaScript event script to handle onkeyup event in the Page Number input. + * It validates and sends appropriate page number on 'Enter'. + * + * @return JavaScript code + */ + private String generateInputOnkeyupScript() + { + final String formClientId = Utils.getParentForm(getFacesContext(), this).getClientId(getFacesContext()); + final StringBuilder script = new StringBuilder(128); + script.append("function validateAndSubmit(e)"); + script.append("{"); + script.append(" var keycode;"); + script.append(" if (window.event) keycode = window.event.keyCode;"); + script.append(" else if (e) keycode = e.which;"); + script.append(" if (keycode == 13)"); + script.append(" {"); + script.append(" var inputControl = document.getElementById('").append(getPageInputId()).append("');"); + script.append(" var val = parseInt(inputControl.value);"); + script.append(" if (val == 'NaN' || document.forms['").append(formClientId).append("']['").append(getHiddenFieldName()).append("']==undefined)"); + script.append(" { inputControl.value = 1; return false; }"); + script.append(" else"); + script.append(" { val = (val-1)>=0 ? val-1 : 0; "); + script.append(" document.forms['").append(formClientId).append("']['").append(getHiddenFieldName()).append("'].value=val;"); + script.append(" document.forms['").append(formClientId).append("'].submit(); return false;"); + script.append(" }"); + script.append(" }"); + script.append(" return true;"); + script.append("}; return validateAndSubmit(event);"); + return script.toString(); + } + + /** + * Output the JavaScript event script to handle onkeydown event in the Page Number input. + * It handles only digits and some 'useful' keys. + * @return JavaScript code + */ + private String generateInputOnkeydownScript() + { + final StringBuilder script = new StringBuilder(128); + script.append("function onlyDigits(e)"); + script.append("{"); + script.append(" var keycode;"); + script.append(" if (window.event) keycode = window.event.keyCode;"); + script.append(" else if (e) keycode = e.which;"); + script.append(" var keychar = String.fromCharCode(keycode);"); + script.append(" var numcheck = /\\d/;"); + script.append(" return keycode==13 || keycode==8 || keycode==37 || keycode==39 || keycode==46 || (keycode>=96 && keycode<=105) || numcheck.test(keychar);"); + script.append("}; return onlyDigits(event);"); + return script.toString(); + } + + private String getPageInputId() + { + return getHiddenFieldName() + NamingContainer.SEPARATOR_CHAR + "pageNamber"; + } + // ------------------------------------------------------------------------------ // Inner classes @@ -341,12 +633,22 @@ public class UIDataPager extends UICommand */ private static class PageEvent extends ActionEvent { - public PageEvent(UIComponent component, int page) - { - super(component); - Page = page; - } - - public int Page = 0; + private static final long serialVersionUID = -5338654505243607790L; + + public PageEvent(UIComponent component, int page) + { + super(component); + Page = page; + } + public int Page = 0; + } + + + /** + * Enumeration of the available Data Pager display types see ETWOONE-389 + */ + private enum PagerType + { + STANDARD, DECADES, TRACKPAGE } } diff --git a/source/java/org/alfresco/web/ui/common/component/data/UIRichList.java b/source/java/org/alfresco/web/ui/common/component/data/UIRichList.java index 3b6ab59b50..b1157c2ca9 100644 --- a/source/java/org/alfresco/web/ui/common/component/data/UIRichList.java +++ b/source/java/org/alfresco/web/ui/common/component/data/UIRichList.java @@ -456,16 +456,23 @@ public class UIRichList extends UIComponentBase implements IDataContainer,Serial int pageSize = getPageSize(); if (pageSize != -1 && pageSize != 0) { - // calc start row index based on current page index - this.rowIndex = (this.currentPage * pageSize) - 1; - // calc total number of pages available this.pageCount = (rowCount / this.pageSize) + 1; + if (rowCount % pageSize == 0 && this.pageCount != 1) { this.pageCount--; } + // set currentPage as lastPage if input digit in UIDataPager > pageCount + if (this.currentPage >= this.pageCount) + { + this.currentPage = this.pageCount - 1; + } + + // calc start row index based on current page index + this.rowIndex = (this.currentPage * pageSize) - 1; + // calc the maximum row index that can be returned this.maxRowIndex = this.rowIndex + pageSize; if (this.maxRowIndex >= rowCount) diff --git a/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java b/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java index 79dffcaa3d..4261840ebd 100644 --- a/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java +++ b/source/java/org/alfresco/web/ui/common/component/data/UISortLink.java @@ -108,7 +108,7 @@ public class UISortLink extends UICommand buf.append('>'); // output column label - buf.append((String)getAttributes().get("label")); + buf.append(Utils.encode((String)getAttributes().get("label"))); if (bPreviouslySorted == true) { diff --git a/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java b/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java index 586b2ec417..9f6ea30aa1 100644 --- a/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java +++ b/source/java/org/alfresco/web/ui/common/renderer/DatePickerRenderer.java @@ -375,7 +375,7 @@ public class DatePickerRenderer extends BaseRenderer outputAttribute(out, "selected", "selected"); } out.write(">"); - out.write(item.getLabel()); + out.write(Utils.encode(item.getLabel())); out.write(""); } out.write(""); diff --git a/source/java/org/alfresco/web/ui/common/tag/data/DataPagerTag.java b/source/java/org/alfresco/web/ui/common/tag/data/DataPagerTag.java index b18eb7f10c..aa4e30997e 100644 --- a/source/java/org/alfresco/web/ui/common/tag/data/DataPagerTag.java +++ b/source/java/org/alfresco/web/ui/common/tag/data/DataPagerTag.java @@ -37,6 +37,9 @@ public class DataPagerTag extends HtmlComponentTag // ------------------------------------------------------------------------------ // Component methods + private String dataPagerType; + private String displayInput; + /** * @see javax.faces.webapp.UIComponentTag#getComponentType() */ @@ -68,5 +71,19 @@ public class DataPagerTag extends HtmlComponentTag protected void setProperties(UIComponent component) { super.setProperties(component); + setStringProperty(component, "dataPagerType", this.dataPagerType); + setBooleanProperty(component, "displayInput", this.displayInput); } + + public void setDataPagerType(String dataPagerType) + { + this.dataPagerType = dataPagerType; + } + + public void setDisplayInput(String displayInput) + { + this.displayInput = displayInput; + } + + } diff --git a/source/java/org/alfresco/web/ui/repo/component/AbstractItemSelector.java b/source/java/org/alfresco/web/ui/repo/component/AbstractItemSelector.java index 6a1a4fdaf6..e64e1534da 100644 --- a/source/java/org/alfresco/web/ui/repo/component/AbstractItemSelector.java +++ b/source/java/org/alfresco/web/ui/repo/component/AbstractItemSelector.java @@ -301,7 +301,7 @@ public abstract class AbstractItemSelector extends UIInput { // build a comma separated list of node names List nodes = (List)val; - StringBuilder buffer = new StringBuilder(); + StringBuilder buffer = new StringBuilder(64); for (Object obj : nodes) { if (buffer.length() != 0) @@ -311,7 +311,7 @@ public abstract class AbstractItemSelector extends UIInput if (obj instanceof NodeRef) { - buffer.append(Repository.getNameForNode(service, (NodeRef)obj)); + buffer.append(Utils.encode(Repository.getNameForNode(service, (NodeRef)obj))); } else { @@ -327,7 +327,7 @@ public abstract class AbstractItemSelector extends UIInput // if there is a value show it's name if (nodeRef != null) { - out.write(Repository.getNameForNode(service, nodeRef)); + out.write(Utils.encode(Repository.getNameForNode(service, nodeRef))); } } else @@ -447,7 +447,7 @@ public abstract class AbstractItemSelector extends UIInput .append(attrs.get("nodeStyleClass")); } buf.append(">") - .append(label) + .append(Utils.encode(label)) .append(""); break; diff --git a/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java b/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java index 314098c781..3af286ac8e 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java +++ b/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java @@ -329,9 +329,9 @@ public class UIContentSelector extends UIInput out.write(""); } } diff --git a/source/java/org/alfresco/web/ui/repo/component/UINavigator.java b/source/java/org/alfresco/web/ui/repo/component/UINavigator.java index 6b1d6079f3..b062eac12e 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UINavigator.java +++ b/source/java/org/alfresco/web/ui/repo/component/UINavigator.java @@ -292,7 +292,7 @@ public class UINavigator extends SelfRenderingComponent out.write(""); - out.write(areaTitle); + out.write(Utils.encode(areaTitle)); out.write(""); // generate the javascript method to capture the tree node click events diff --git a/source/java/org/alfresco/web/ui/repo/component/UINodeWorkflowInfo.java b/source/java/org/alfresco/web/ui/repo/component/UINodeWorkflowInfo.java index b40bf14809..a4cd4dc29b 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UINodeWorkflowInfo.java +++ b/source/java/org/alfresco/web/ui/repo/component/UINodeWorkflowInfo.java @@ -245,7 +245,7 @@ public class UINodeWorkflowInfo extends SelfRenderingComponent actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "space_action"); } Object[] params = new Object[] {action, approveFolderName, Utils.encode(approveStepName)}; - out.write(MessageFormat.format(actionPattern, params)); + out.write(Utils.encode(MessageFormat.format(actionPattern, params))); // add details of the reject step if there is one if (rejectStepName != null && rejectMove != null && rejectFolderName != null) @@ -261,7 +261,7 @@ public class UINodeWorkflowInfo extends SelfRenderingComponent out.write(" "); params = new Object[] {action, rejectFolderName, Utils.encode(rejectStepName)}; - out.write(MessageFormat.format(actionPattern, params)); + out.write(Utils.encode(MessageFormat.format(actionPattern, params))); } } else diff --git a/source/java/org/alfresco/web/ui/repo/component/UIOpenSearch.java b/source/java/org/alfresco/web/ui/repo/component/UIOpenSearch.java index f358e1a216..95918a5e74 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UIOpenSearch.java +++ b/source/java/org/alfresco/web/ui/repo/component/UIOpenSearch.java @@ -39,6 +39,7 @@ import org.alfresco.repo.web.scripts.bean.SearchProxy; import org.alfresco.repo.web.scripts.config.OpenSearchConfigElement; import org.alfresco.repo.web.scripts.config.OpenSearchConfigElement.EngineConfig; import org.alfresco.web.app.Application; +import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.SelfRenderingComponent; import org.springframework.web.jsf.FacesContextUtils; @@ -239,7 +240,7 @@ public class UIOpenSearch extends SelfRenderingComponent out.write(engine.getId()); out.write("-engine-enabled' type='checkbox' checked='checked' />"); out.write(""); - out.write(engine.getLabel()); + out.write(Utils.encode(engine.getLabel())); out.write(""); } out.write("\n"); diff --git a/source/java/org/alfresco/web/ui/repo/component/UIWorkflowHistory.java b/source/java/org/alfresco/web/ui/repo/component/UIWorkflowHistory.java index a37be1b305..31d98d38df 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UIWorkflowHistory.java +++ b/source/java/org/alfresco/web/ui/repo/component/UIWorkflowHistory.java @@ -192,7 +192,7 @@ public class UIWorkflowHistory extends SelfRenderingComponent out.write(""); out.write(desc == null ? "" : Utils.encode(desc)); out.write(""); - out.write(task.title); + out.write(Utils.encode(task.title)); out.write(""); out.write(id.toString()); out.write(""); diff --git a/source/java/org/alfresco/web/ui/repo/component/property/BaseAssociationEditor.java b/source/java/org/alfresco/web/ui/repo/component/property/BaseAssociationEditor.java index 432718862b..57bbb42622 100644 --- a/source/java/org/alfresco/web/ui/repo/component/property/BaseAssociationEditor.java +++ b/source/java/org/alfresco/web/ui/repo/component/property/BaseAssociationEditor.java @@ -733,9 +733,9 @@ public abstract class BaseAssociationEditor extends UIInput } else { - out.write(Repository.getDisplayPath(nodeService.getPath(targetRef))); + out.write(Utils.encode(Repository.getDisplayPath(nodeService.getPath(targetRef)))); out.write("/"); - out.write(Repository.getNameForNode(nodeService, targetRef)); + out.write(Utils.encode(Repository.getNameForNode(nodeService, targetRef))); } out.write(""); - out.write(Repository.getDisplayPath(nodeService.getPath(item))); + out.write(Utils.encode(Repository.getDisplayPath(nodeService.getPath(item)))); out.write("/"); - out.write(Repository.getNameForNode(nodeService, item)); + out.write(Utils.encode(Repository.getNameForNode(nodeService, item))); out.write(""); } } diff --git a/source/java/org/alfresco/web/ui/repo/component/property/UIAssociationEditor.java b/source/java/org/alfresco/web/ui/repo/component/property/UIAssociationEditor.java index e1029f5240..d0b9ecac6e 100644 --- a/source/java/org/alfresco/web/ui/repo/component/property/UIAssociationEditor.java +++ b/source/java/org/alfresco/web/ui/repo/component/property/UIAssociationEditor.java @@ -196,7 +196,7 @@ public class UIAssociationEditor extends BaseAssociationEditor displayString = Application.getMessage(context, MSG_WARN_CANNOT_VIEW_TARGET_DETAILS); } - out.write(displayString); + out.write(Utils.encode(displayString)); } out.write(""); } diff --git a/source/java/org/alfresco/web/ui/repo/renderer/BaseMultiValueRenderer.java b/source/java/org/alfresco/web/ui/repo/renderer/BaseMultiValueRenderer.java index 691da86840..0580bcd1d2 100644 --- a/source/java/org/alfresco/web/ui/repo/renderer/BaseMultiValueRenderer.java +++ b/source/java/org/alfresco/web/ui/repo/renderer/BaseMultiValueRenderer.java @@ -262,7 +262,7 @@ public abstract class BaseMultiValueRenderer extends BaseRenderer if (value instanceof NodeRef) { - out.write(Repository.getNameForNode(nodeService, (NodeRef)value)); + out.write(Utils.encode(Repository.getNameForNode(nodeService, (NodeRef)value))); } else if (value instanceof Date) { @@ -290,7 +290,7 @@ public abstract class BaseMultiValueRenderer extends BaseRenderer } else { - out.write(value.toString()); + out.write(Utils.encode(value.toString())); } out.write("  "); diff --git a/source/java/org/alfresco/web/ui/repo/renderer/MultilingualTextAreaRenderer.java b/source/java/org/alfresco/web/ui/repo/renderer/MultilingualTextAreaRenderer.java index 4d2f5033c2..ae7761ae93 100644 --- a/source/java/org/alfresco/web/ui/repo/renderer/MultilingualTextAreaRenderer.java +++ b/source/java/org/alfresco/web/ui/repo/renderer/MultilingualTextAreaRenderer.java @@ -51,7 +51,11 @@ public class MultilingualTextAreaRenderer extends HtmlTextareaRenderer // to workaround a bug in MyFaces where it appears a new line gets removed // in the process view/edit process add it back (ETWOONE-91) Object value = ((ValueHolder) uiComponent).getValue(); - String valueStr = "\r\n" + (String)value; + String valueStr = null; + if (value != null) + { + valueStr = "\r\n" + (String)value; + } ((ValueHolder) uiComponent).setValue(valueStr); super.encodeTextArea(facesContext, uiComponent); } diff --git a/source/java/org/alfresco/web/ui/repo/tag/PageTag.java b/source/java/org/alfresco/web/ui/repo/tag/PageTag.java index db91506913..65dd01b8aa 100644 --- a/source/java/org/alfresco/web/ui/repo/tag/PageTag.java +++ b/source/java/org/alfresco/web/ui/repo/tag/PageTag.java @@ -35,6 +35,7 @@ import javax.servlet.jsp.tagext.TagSupport; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.coci.CCProperties; +import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -228,11 +229,11 @@ public class PageTag extends TagSupport out.write(""); if (this.titleId != null && this.titleId.length() != 0) { - out.write(Application.getMessage(pageContext.getSession(), this.titleId)); + out.write(Utils.encode(Application.getMessage(pageContext.getSession(), this.titleId))); } else if (this.title != null && this.title.length() != 0) { - out.write(this.title); + out.write(Utils.encode(this.title)); } else { diff --git a/source/java/org/alfresco/web/ui/wcm/component/UILinkValidationReport.java b/source/java/org/alfresco/web/ui/wcm/component/UILinkValidationReport.java index a763204de9..e1e45e5a4c 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UILinkValidationReport.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UILinkValidationReport.java @@ -494,9 +494,9 @@ public class UILinkValidationReport extends AbstractLinkValidationReportComponen List<String> brokenFiles = linkState.getBrokenFilesByForm(file); out.write("<div class='linkValItemDetails'><div class='linkValFormName'>"); - out.write(formName); + out.write(Utils.encode(formName)); out.write("</div><div class='linkValFormPath'>"); - out.write(formPath); + out.write(Utils.encode(formPath)); out.write("</div><div class='linkValToggle'><img src='"); out.write(context.getExternalContext().getRequestContextPath()); if (generatedFilesExpanded) @@ -719,9 +719,9 @@ public class UILinkValidationReport extends AbstractLinkValidationReportComponen String fileId = "file" + Integer.toString((filePath + fileName).hashCode()); out.write("<div class='linkValItemDetails'><div class='linkValFileName'>"); - out.write(fileName); + out.write(Utils.encode(fileName)); out.write("</div><div class='linkValFilePath'>"); - out.write(filePath); + out.write(Utils.encode(filePath)); out.write("</div>"); if (brokenLinks != null && brokenLinks.length() > 0) diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIPendingSubmissions.java b/source/java/org/alfresco/web/ui/wcm/component/UIPendingSubmissions.java index cf47b002f6..bbaf3a6237 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIPendingSubmissions.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIPendingSubmissions.java @@ -258,11 +258,11 @@ public class UIPendingSubmissions extends SelfRenderingComponent requestMap.remove(REQUEST_TASKTYPE); out.write("</td><td>"); - out.write(label); + out.write(Utils.encode(label)); out.write("</td><td>"); out.write(submitted); out.write("</td><td>"); - out.write(username); + out.write(Utils.encode(username)); out.write("</td><td>"); out.write(launch); out.write("</td><td><nobr>"); diff --git a/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java b/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java index 7a15a691e4..39362db63b 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UISandboxSnapshots.java @@ -256,13 +256,13 @@ public class UISandboxSnapshots extends SelfRenderingComponent int version = item.getVersionID(); out.write("<tr><td>"); - out.write(item.getTag()); + out.write(Utils.encode(item.getTag())); out.write("</td><td>"); - out.write(item.getDescription() != null ? item.getDescription() : ""); + out.write(item.getDescription() != null ? Utils.encode(item.getDescription()) : ""); out.write("</td><td>"); out.write(df.format(new Date(item.getCreateDate()))); out.write("</td><td>"); - out.write(item.getCreator()); + out.write(Utils.encode(item.getCreator())); out.write("</td><td>"); out.write(Integer.toString(version)); out.write("</td><td>"); @@ -286,7 +286,6 @@ public class UISandboxSnapshots extends SelfRenderingComponent params.put("sandbox", sandbox); params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); action = createAction(context, sandbox, ACT_SNAPSHOT_REVERT, "/images/icons/revert.gif", "#{AVMBrowseBean.revertSnapshot}", null, null, params); - } requestMap.put(REQUEST_SNAPVERSION, Integer.toString(item.getVersionID())); @@ -323,11 +322,10 @@ public class UISandboxSnapshots extends SelfRenderingComponent out.write("  "); // Compare To Current Snapshot - action = findAction(ACT_SNAPSHOT_COMPARE_TO_CURRENT, sandbox); if (action == null) { - Map<String, String> params = new HashMap<String, String>(2, 1.0f); + Map<String, String> params = new HashMap<String, String>(4, 1.0f); params.put("sandbox", sandbox); params.put("store", sandbox); params.put("version", "#{" + REQUEST_SNAPVERSION + "}"); @@ -357,7 +355,7 @@ public class UISandboxSnapshots extends SelfRenderingComponent Utils.encodeRecursive(context, action); } out.write("  "); - // //Compare To Any Snapshot + // Compare To Any Snapshot action = findAction(ACT_SNAPSHOT_COMPARE_TO_ANY, sandbox); if (action == null) { diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index 203e120597..a37b72d383 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -435,7 +435,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa out.write("<b>"); out.write(bundle.getString(MSG_USERNAME)); out.write(":</b> "); - out.write(username); + out.write(Utils.encode(username)); } else { @@ -813,7 +813,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa out.write(Utils.buildImageTag(fc, FileTypeImageUtils.getFileTypeImage(fc, name, true), "")); out.write("</a></td><td>"); out.write(linkPrefix); - out.write(name); + out.write(Utils.encode(name)); UIAVMLockIcon lockIcon = (UIAVMLockIcon)fc.getApplication().createComponent( UIAVMLockIcon.ALFRESCO_FACES_AVMLOCKICON); lockIcon.setId("avmlock_" + Integer.toString(rowIndex)); @@ -825,7 +825,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa { out.write(Utils.buildImageTag(fc, SPACE_ICON, 16, 16, "")); out.write("</td><td>"); - out.write(name); + out.write(Utils.encode(name)); } out.write("</td><td>"); @@ -871,14 +871,14 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa { out.write(Utils.buildImageTag(fc, FileTypeImageUtils.getFileTypeImage(fc, name, true), "")); out.write("</td><td style='color:#aaaaaa'>"); - out.write(name + " [" + bundle.getString(MSG_DELETED_ITEM) + "]"); + out.write(Utils.encode(name) + " [" + bundle.getString(MSG_DELETED_ITEM) + "]"); out.write("</a>"); } else { out.write(Utils.buildImageTag(fc, SPACE_ICON, 16, 16, "")); out.write("</td><td style='color:#aaaaaa'>"); - out.write(name + " [" + bundle.getString(MSG_DELETED_ITEM) + "]"); + out.write(Utils.encode(name) + " [" + bundle.getString(MSG_DELETED_ITEM) + "]"); } out.write("</td><td style='color:#aaaaaa'>"); @@ -959,10 +959,10 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa { out.write("<tr><td>"); String title = (String)f.getTitle(); - out.write(title != null ? title : ""); + out.write(title != null ? Utils.encode(title) : ""); out.write("</td><td>"); String desc = (String)f.getDescription(); - out.write(desc != null ? desc : ""); + out.write(desc != null ? Utils.encode(desc) : ""); out.write("</td><td>"); // set the form-id into the request scope for actions data binding diff --git a/source/web/WEB-INF/alfresco.tld b/source/web/WEB-INF/alfresco.tld index 7b49b60843..4995e522ed 100644 --- a/source/web/WEB-INF/alfresco.tld +++ b/source/web/WEB-INF/alfresco.tld @@ -397,6 +397,18 @@ <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> + + <attribute> + <name>dataPagerType</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> + + <attribute> + <name>displayInput</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + </attribute> </tag> <tag> diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 6889513643..a33a05db71 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -481,6 +481,43 @@ <managed-bean> <description> + The bean that backs up the Delete Space Association Dialog + </description> + <managed-bean-name>DeleteSpaceAssociationDialog</managed-bean-name> + <managed-bean-class>org.alfresco.web.bean.spaces.DeleteSpaceAssociationDialog</managed-bean-class> + <managed-bean-scope>session</managed-bean-scope> + <managed-property> + <property-name>nodeService</property-name> + <value>#{NodeService}</value> + </managed-property> + <managed-property> + <property-name>fileFolderService</property-name> + <value>#{FileFolderService}</value> + </managed-property> + <managed-property> + <property-name>searchService</property-name> + <value>#{SearchService}</value> + </managed-property> + <managed-property> + <property-name>navigator</property-name> + <value>#{NavigationBean}</value> + </managed-property> + <managed-property> + <property-name>browseBean</property-name> + <value>#{BrowseBean}</value> + </managed-property> + <managed-property> + <property-name>dictionaryService</property-name> + <value>#{DictionaryService}</value> + </managed-property> + <managed-property> + <property-name>namespaceService</property-name> + <value>#{NamespaceService}</value> + </managed-property> + </managed-bean> + + <managed-bean> + <description> The bean that manages a users Clipboard state. </description> <managed-bean-name>ClipboardBean</managed-bean-name> @@ -3599,6 +3636,43 @@ <managed-bean> <description> + The bean that backs up the Delete Content Association Dialog + </description> + <managed-bean-name>DeleteContentAssociationDialog</managed-bean-name> + <managed-bean-class>org.alfresco.web.bean.content.DeleteContentAssociationDialog</managed-bean-class> + <managed-bean-scope>session</managed-bean-scope> + <managed-property> + <property-name>nodeService</property-name> + <value>#{NodeService}</value> + </managed-property> + <managed-property> + <property-name>fileFolderService</property-name> + <value>#{FileFolderService}</value> + </managed-property> + <managed-property> + <property-name>searchService</property-name> + <value>#{SearchService}</value> + </managed-property> + <managed-property> + <property-name>navigator</property-name> + <value>#{NavigationBean}</value> + </managed-property> + <managed-property> + <property-name>browseBean</property-name> + <value>#{BrowseBean}</value> + </managed-property> + <managed-property> + <property-name>dictionaryService</property-name> + <value>#{DictionaryService}</value> + </managed-property> + <managed-property> + <property-name>namespaceService</property-name> + <value>#{NamespaceService}</value> + </managed-property> + </managed-bean> + + <managed-bean> + <description> The bean that backs up the Delete AVM Folder Dialog </description> <managed-bean-name>DeleteFolderDialog</managed-bean-name> diff --git a/source/web/jsp/content/create-content-wizard/details.jsp b/source/web/jsp/content/create-content-wizard/details.jsp index db1ceefc5c..9c8d7ba157 100644 --- a/source/web/jsp/content/create-content-wizard/details.jsp +++ b/source/web/jsp/content/create-content-wizard/details.jsp @@ -62,7 +62,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("wizard:wizard-body:file-name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/forums/create-dialog.jsp b/source/web/jsp/forums/create-dialog.jsp index e60b3f3a60..6c8e4c5075 100644 --- a/source/web/jsp/forums/create-dialog.jsp +++ b/source/web/jsp/forums/create-dialog.jsp @@ -61,7 +61,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("dialog:dialog-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/forums/create-topic-dialog.jsp b/source/web/jsp/forums/create-topic-dialog.jsp index 2700c2c05d..3a5420feb5 100644 --- a/source/web/jsp/forums/create-topic-dialog.jsp +++ b/source/web/jsp/forums/create-topic-dialog.jsp @@ -62,7 +62,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("dialog:dialog-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/spaces/create-space-dialog.jsp b/source/web/jsp/spaces/create-space-dialog.jsp index 446ce8fe42..28c5ce1c41 100644 --- a/source/web/jsp/spaces/create-space-dialog.jsp +++ b/source/web/jsp/spaces/create-space-dialog.jsp @@ -61,7 +61,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("dialog:dialog-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/spaces/create-space-wizard/details.jsp b/source/web/jsp/spaces/create-space-wizard/details.jsp index 8f3a61917f..91def2d87b 100644 --- a/source/web/jsp/spaces/create-space-wizard/details.jsp +++ b/source/web/jsp/spaces/create-space-wizard/details.jsp @@ -84,7 +84,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("wizard:wizard-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/spaces/delete-space.jsp b/source/web/jsp/spaces/delete-space.jsp index 10e832fd4d..557a5422f5 100644 --- a/source/web/jsp/spaces/delete-space.jsp +++ b/source/web/jsp/spaces/delete-space.jsp @@ -51,6 +51,24 @@ </f:verbatim> </h:panelGroup> +<h:panelGroup rendered="#{DialogManager.bean.hasMultipleParents}"> + <f:verbatim> + <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %> + <table cellpadding="0" cellspacing="0" border="0" width="100%"> + <tr> + <td valign=top style="padding-top:2px" width=20> + </f:verbatim><h:graphicImage url="/images/icons/warning.gif" width="16" height="16"/><f:verbatim> + </td> + <td class="mainSubText"> + </f:verbatim><h:outputText value="#{msg.delete_space_multiple_parents_warn}" /><f:verbatim> + </td> + </tr> + </table> + <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %> + <br/> + </f:verbatim> +</h:panelGroup> + <h:outputText value="#{msg.select_delete_operation}" styleClass="mainSubTitle" /> <h:panelGrid columns="1" cellpadding="2" cellspacing="2" border="0"> <h:selectOneRadio id="delete-operation" layout="pageDirection" value="#{DialogManager.bean.deleteMode}"> diff --git a/source/web/jsp/wcm/create-folder-dialog.jsp b/source/web/jsp/wcm/create-folder-dialog.jsp index c14e3f25f9..56a116eea0 100644 --- a/source/web/jsp/wcm/create-folder-dialog.jsp +++ b/source/web/jsp/wcm/create-folder-dialog.jsp @@ -60,7 +60,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("dialog:dialog-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/wcm/create-web-content-wizard/details.jsp b/source/web/jsp/wcm/create-web-content-wizard/details.jsp index 4cee018641..c0d9ecff0d 100644 --- a/source/web/jsp/wcm/create-web-content-wizard/details.jsp +++ b/source/web/jsp/wcm/create-web-content-wizard/details.jsp @@ -62,7 +62,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("wizard:wizard-body:file-name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/wcm/create-webapp.jsp b/source/web/jsp/wcm/create-webapp.jsp index 1ddcb0427e..a7a28963de 100644 --- a/source/web/jsp/wcm/create-webapp.jsp +++ b/source/web/jsp/wcm/create-webapp.jsp @@ -60,7 +60,7 @@ { finishButtonPressed = false; return validateName(document.getElementById("dialog:dialog-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); } else diff --git a/source/web/jsp/wcm/create-website-wizard/details.jsp b/source/web/jsp/wcm/create-website-wizard/details.jsp index caee690cf2..507b89aaae 100644 --- a/source/web/jsp/wcm/create-website-wizard/details.jsp +++ b/source/web/jsp/wcm/create-website-wizard/details.jsp @@ -64,13 +64,13 @@ { finishButtonPressed = false; var valid = validateName(document.getElementById("wizard:wizard-body:name"), - '</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" /><f:verbatim>', + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_character}" encodeForJavaScript="true" /><f:verbatim>'), true); if (valid == true) { valid = validateRegex(document.getElementById("wizard:wizard-body:dnsname"), "^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$", true, null, - '</f:verbatim><a:outputText value="#{msg.validation_invalid_dns_name}" /><f:verbatim>', true); + decodeURI('</f:verbatim><a:outputText value="#{msg.validation_invalid_dns_name}" encodeForJavaScript="true" /><f:verbatim>'), true); } return valid; } diff --git a/source/web/scripts/ajax/common.js b/source/web/scripts/ajax/common.js index d3f309d52c..23ca708289 100644 --- a/source/web/scripts/ajax/common.js +++ b/source/web/scripts/ajax/common.js @@ -53,8 +53,15 @@ function handleErrorDojo(type, errObj) */ function handleErrorYahoo(e) { - // TODO: Show a nicer error page, an alert will do for now! - alert(e.status + " : " + e.statusText); + if (e.status == 401) + { + document.location = window.location.protocol + "//" + window.location.host + getContextPath(); + } + else + { + // TODO: Show a nicer error page, an alert will do for now! + alert(e.status + " : " + e.statusText); + } } /** diff --git a/source/web/scripts/ajax/yahoo-tree.js b/source/web/scripts/ajax/yahoo-tree.js index f78b58efa7..ac361852e4 100644 --- a/source/web/scripts/ajax/yahoo-tree.js +++ b/source/web/scripts/ajax/yahoo-tree.js @@ -62,10 +62,17 @@ function loadDataForNode(node, onCompleteCallback) }, failure: function(o) { - handleErrorYahoo("Error: Failed to retrieve children for node: " + o.argument[0].data.nodeRef); - - // execute the callback method - o.argument[1](); + if (o.status == 401) + { + document.location = window.location.protocol + "//" + window.location.host + getContextPath(); + } + else + { + handleErrorYahoo("Error: Failed to retrieve children for node: " + o.argument[0].data.nodeRef); + + // execute the callback method + o.argument[1](); + } }, argument: [node, onCompleteCallback] }