From 2cd50470753aff0383e4968680f69ecf6bb4d9b0 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Tue, 19 Jan 2010 12:01:16 +0000 Subject: [PATCH] Merged V3.2E to HEAD 17533: Fix for unreported issue for events with multiple days (secondary elements) aren't filtered correctly when view is filtered by tags 17535: ETHREEOH-3411 - Alert appears when loading My Dashboard when Documents I'm editing dashlet is aded and site name was edited with XSS text 17536: Fixes for various forms issues (ETHREEOH-3398, ETHREEOH-3273, ETHREEOH-3339 & ALFCOM-3587) and reverted accidentally checked in log4j.properties file - Folders can now have tags applied in edit form - Working copy nodes have their cm:name property set to protected - Removed mandatory marker from checkbox control (if you have a boolean there is always a value so no need to mark as mandatory) - Potential security issue 17537: ETHREEOH-1908 - .docx word documents are not displayed in 'Word Documents' category in 'Document List' component. Also fixed some i18n strings. 17538: Fix for ETHREEOH-3085 and ETHREEOH-3341. - NTLM/Kerberos, Tomcat/JBoss5 and JSF client now play nicely on session timeout and display the correct configured page on first login. - Tested Share NTLM works correctly with above changes. 17539: Fix for ETHREEOH-3368: UI does not show multi-valued MLText propertis as localisable 17543: Merged DEV_TEMPORARY to V3.2 17529: Fix for ETHREEOH-3186 & ETHREEOH-3187 17544: Fix for ETHREEOH-1509 - Manage action is not applied for task resources part from My Tasks tab in Office Addins if user already opens another task. 17547: Fix for ETHREEOH-1709 - AccessDeniedException - Download Servlet not re-directing user to login page. - WebDav path now resolved to a noderef as system user - then the permission test for READ_CONTENT is performed directly on the resulting noderef. 17548: Fix for ETHREEOH-3137 - Tags created for All day event are not displayed in Tags pane. 17551: Final part of fix for ETHREEOH-2161 includes solution for ETHREEOH-3270. - An admin user can now optionally disable the execute of Rules and the Archive of nodes during a folder delete operation. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18128 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/portlets.properties | 4 +- config/alfresco/messages/webclient.properties | 4 +- .../portlet/AlfrescoDefaultViewSelector.java | 3 +- .../web/app/portlet/AlfrescoFacesPortlet.java | 5 +- .../alfresco/web/app/servlet/BaseServlet.java | 121 ++++++------- .../alfresco/web/app/servlet/FacesHelper.java | 5 +- .../HTTPRequestAuthenticationFilter.java | 2 +- .../servlet/KerberosAuthenticationFilter.java | 45 ++++- .../app/servlet/NTLMAuthenticationFilter.java | 47 ++++- .../generator/BaseComponentGenerator.java | 7 + .../MultilingualTextFieldGenerator.java | 4 +- .../web/bean/spaces/DeleteSpaceDialog.java | 165 ++++++++++++------ .../web/forms/xforms/XFormsProcessor.java | 6 +- .../renderer/MultiValueFieldRenderer.java | 17 +- .../web/ui/repo/tag/UploadFormTag.java | 3 +- .../readonly-and-default-values-test.xsd | 78 +++++++++ source/web/jsp/spaces/delete-space.jsp | 10 ++ .../web/jsp/workflow/manage-task-dialog.jsp | 2 +- 18 files changed, 384 insertions(+), 144 deletions(-) create mode 100644 source/test-resources/xforms/tests/schema/readonly-and-default-values-test.xsd diff --git a/config/alfresco/messages/portlets.properties b/config/alfresco/messages/portlets.properties index f7a2202b52..b741758197 100755 --- a/config/alfresco/messages/portlets.properties +++ b/config/alfresco/messages/portlets.properties @@ -27,8 +27,8 @@ portlets.myspaces.create_space=Create Space portlets.myspaces.create_space.title=Create a new Space portlets.myspaces.upload=Upload portlets.myspaces.upload.title=Upload a new document -portlets.myspaces.name=name -portlets.myspaces.title=title +portlets.myspaces.name=Name +portlets.myspaces.title=Title portlets.myspaces.description=Description portlets.myspaces.all_items=All Items portlets.myspaces.spaces=Spaces diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 7edd9aeacb..aa0ae82842 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -227,7 +227,7 @@ view_details=View Details view_details_file=View Details for file change_details=Change Details update=Update -download=download +download=Download cut=Cut copy=Copy paste=Paste @@ -1641,6 +1641,8 @@ delete_op_all=This space and all its contents. Note: Rules will also be deleted. delete_op_files=Only the files within this space. delete_op_folders=Only the folders within this space. delete_op_contents=Files and folders within this space. +delete_execute_rules=Execute Rules +delete_archive_nodes=Archive Nodes # Email users dialog email_space_users=Email Space users diff --git a/source/java/org/alfresco/web/app/portlet/AlfrescoDefaultViewSelector.java b/source/java/org/alfresco/web/app/portlet/AlfrescoDefaultViewSelector.java index 536db3e2cd..7b9e38485a 100644 --- a/source/java/org/alfresco/web/app/portlet/AlfrescoDefaultViewSelector.java +++ b/source/java/org/alfresco/web/app/portlet/AlfrescoDefaultViewSelector.java @@ -31,6 +31,7 @@ import javax.portlet.RenderResponse; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.web.app.servlet.AuthenticationHelper; +import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.User; import org.apache.myfaces.portlet.DefaultViewSelector; @@ -47,7 +48,7 @@ public class AlfrescoDefaultViewSelector implements DefaultViewSelector User user = (User)request.getPortletSession().getAttribute(AuthenticationHelper.AUTHENTICATION_USER); if (user != null && user.getUserName().equals(AuthenticationUtil.getGuestUserName())) { - return "/jsp/browse/browse.jsp"; + return FacesHelper.BROWSE_VIEW_ID; } else { diff --git a/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java b/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java index 1b25b75081..2d6f69fb28 100644 --- a/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java +++ b/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java @@ -50,6 +50,7 @@ import org.alfresco.util.TempFileProvider; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.AuthenticationHelper; import org.alfresco.web.app.servlet.AuthenticationStatus; +import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.ErrorBean; import org.alfresco.web.bean.FileUploadBean; import org.alfresco.web.bean.LoginBean; @@ -291,7 +292,7 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet } else { - nonFacesRequest(request, response, "/jsp/browse/browse.jsp"); + nonFacesRequest(request, response, FacesHelper.BROWSE_VIEW_ID); } } else @@ -423,7 +424,7 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet { ViewHandler viewHandler = context.getApplication().getViewHandler(); // TODO: configure the portlet error return page - UIViewRoot view = viewHandler.createView(context, "/jsp/browse/browse.jsp"); + UIViewRoot view = viewHandler.createView(context, FacesHelper.BROWSE_VIEW_ID); context.setViewRoot(view); } diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java index f766f49af0..d86ba42371 100644 --- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java +++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java @@ -39,6 +39,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.extensions.surf.util.I18NUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.model.FileFolderService; @@ -96,8 +98,6 @@ public abstract class BaseServlet extends HttpServlet private static Log logger = LogFactory.getLog(BaseServlet.class); - // Tenant service - private static TenantService m_tenantService; /** * Return the ServiceRegistry helper instance @@ -309,66 +309,69 @@ public abstract class BaseServlet extends HttpServlet * @param args The elements of the path to lookup * @param decode True to decode the arg from UTF-8 format, false for no decoding */ - private static NodeRef resolveWebDAVPath(WebApplicationContext wc, String[] args, boolean decode) + private static NodeRef resolveWebDAVPath(final WebApplicationContext wc, final String[] args, final boolean decode) { - NodeRef nodeRef = null; + return AuthenticationUtil.runAs(new RunAsWork() + { + public NodeRef doWork() throws Exception + { + NodeRef nodeRef = null; + + List paths = new ArrayList(args.length - 1); - List paths = new ArrayList(args.length - 1); - - FileInfo file = null; - try - { - // create a list of path elements (decode the URL as we go) - for (int x = 1; x < args.length; x++) - { - paths.add(decode ? URLDecoder.decode(args[x]) : args[x]); + FileInfo file = null; + try + { + // create a list of path elements (decode the URL as we go) + for (int x = 1; x < args.length; x++) + { + paths.add(decode ? URLDecoder.decode(args[x]) : args[x]); + } + + if (logger.isDebugEnabled()) + logger.debug("Attempting to resolve webdav path: " + paths); + + // get the company home node to start the search from + nodeRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()); + + TenantService tenantService = (TenantService)wc.getBean("tenantService"); + if (tenantService != null && tenantService.isEnabled()) + { + if (logger.isDebugEnabled()) + logger.debug("MT is enabled."); + + NodeService nodeService = (NodeService) wc.getBean("NodeService"); + SearchService searchService = (SearchService) wc.getBean("SearchService"); + NamespaceService namespaceService = (NamespaceService) wc.getBean("NamespaceService"); + + // TODO: since these constants are used more widely than just the WebDAVServlet, + // they should be defined somewhere other than in that servlet + String rootPath = wc.getServletContext().getInitParameter(org.alfresco.repo.webdav.WebDAVServlet.KEY_ROOT_PATH); + + // note: rootNodeRef is required (for storeRef part) + nodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, nodeRef); + } + + if (paths.size() != 0) + { + FileFolderService ffs = (FileFolderService)wc.getBean("FileFolderService"); + file = ffs.resolveNamePath(nodeRef, paths); + nodeRef = file.getNodeRef(); + } + + if (logger.isDebugEnabled()) + logger.debug("Resolved webdav path to NodeRef: " + nodeRef); + } + catch (FileNotFoundException fne) + { + if (logger.isWarnEnabled()) + logger.warn("Failed to resolve webdav path", fne); + + nodeRef = null; + } + return nodeRef; } - - if (logger.isDebugEnabled()) - logger.debug("Attempting to resolve webdav path: " + paths); - - // get the company home node to start the search from - nodeRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()); - - m_tenantService = (TenantService) wc.getBean("tenantService"); - if (m_tenantService !=null && m_tenantService.isEnabled()) - { - if (logger.isDebugEnabled()) - { - logger.debug("MT is enabled."); - } - - NodeService nodeService = (NodeService) wc.getBean("NodeService"); - SearchService searchService = (SearchService) wc.getBean("SearchService"); - NamespaceService namespaceService = (NamespaceService) wc.getBean("NamespaceService"); - - // TODO: since these constants are used more widely than just the WebDAVServlet, - // they should be defined somewhere other than in that servlet - String m_rootPath = wc.getServletContext().getInitParameter(org.alfresco.repo.webdav.WebDAVServlet.KEY_ROOT_PATH); - - // note: rootNodeRef is required (for storeRef part) - nodeRef = m_tenantService.getRootNode(nodeService, searchService, namespaceService, m_rootPath, nodeRef); - } - - if (paths.size() != 0) - { - FileFolderService ffs = (FileFolderService)wc.getBean("FileFolderService"); - file = ffs.resolveNamePath(nodeRef, paths); - nodeRef = file.getNodeRef(); - } - - if (logger.isDebugEnabled()) - logger.debug("Resolved webdav path to NodeRef: " + nodeRef); - } - catch (FileNotFoundException fne) - { - if (logger.isWarnEnabled()) - logger.warn("Failed to resolve webdav path", fne); - - nodeRef = null; - } - - return nodeRef; + }, AuthenticationUtil.getSystemUserName()); } /** diff --git a/source/java/org/alfresco/web/app/servlet/FacesHelper.java b/source/java/org/alfresco/web/app/servlet/FacesHelper.java index f916f0e3f8..d5f7702262 100644 --- a/source/java/org/alfresco/web/app/servlet/FacesHelper.java +++ b/source/java/org/alfresco/web/app/servlet/FacesHelper.java @@ -48,6 +48,9 @@ import org.apache.commons.logging.LogFactory; */ public final class FacesHelper { + /** Root browse screen JSF view ID */ + public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp"; + private static Log logger = LogFactory.getLog(FacesHelper.class); /** @@ -138,7 +141,7 @@ public final class FacesHelper // set a new viewRoot, otherwise context.getViewRoot returns null if (viewRoot == null) { - viewRoot = "/jsp/browse/browse.jsp"; + viewRoot = FacesHelper.BROWSE_VIEW_ID; } UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, viewRoot); diff --git a/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java index 06384e7663..e8cf5fb710 100644 --- a/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java @@ -208,7 +208,7 @@ public class HTTPRequestAuthenticationFilter implements Filter if (logger.isDebugEnabled()) logger.debug("Login page requested, chaining ..."); - resp.sendRedirect(req.getContextPath() + "/faces/jsp/browse/browse.jsp"); + resp.sendRedirect(req.getContextPath() + BaseServlet.FACES_SERVLET + FacesHelper.BROWSE_VIEW_ID); return; } else diff --git a/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java index d1085edcd8..6f7daae10d 100644 --- a/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java @@ -26,6 +26,7 @@ package org.alfresco.web.app.servlet; import java.io.IOException; +import javax.faces.context.FacesContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -36,6 +37,9 @@ import org.springframework.extensions.config.ConfigService; import org.alfresco.repo.SessionUser; import org.alfresco.repo.webdav.auth.BaseKerberosAuthenticationFilter; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.NavigationBean; +import org.alfresco.web.bean.repository.PreferencesService; import org.alfresco.web.bean.repository.User; import org.alfresco.web.config.ClientConfigElement; import org.apache.commons.logging.Log; @@ -128,17 +132,44 @@ public class KerberosAuthenticationFilter extends BaseKerberosAuthenticationFilt * @see org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter#onLoginComplete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override - protected boolean onLoginComplete(HttpServletRequest req, HttpServletResponse res) + protected boolean onLoginComplete(ServletContext sc, HttpServletRequest req, HttpServletResponse res, boolean userInit) throws IOException { // If the original URL requested was the login page then redirect to the browse view - if (req.getRequestURI().endsWith(getLoginPage()) == true) + if (userInit || req.getRequestURI().endsWith(getLoginPage())) { - if (logger.isDebugEnabled()) - logger.debug("Login page requested, redirecting to browse page"); - - // Redirect to the browse view - res.sendRedirect(req.getContextPath() + "/faces/jsp/browse/browse.jsp"); + if (logger.isDebugEnabled() && req.getRequestURI().endsWith(getLoginPage())) + logger.debug("Login page requested - redirecting to initially configured page"); + if (logger.isDebugEnabled() && userInit) + logger.debug("Session reinitialised - redirecting to initially configured page"); + + FacesContext fc = FacesHelper.getFacesContext(req, res, sc); + ConfigService configService = Application.getConfigService(fc); + ClientConfigElement configElement = (ClientConfigElement)configService.getGlobalConfig().getConfigElement("client"); + String location = configElement.getInitialLocation(); + + String preference = (String)PreferencesService.getPreferences(fc).getValue("start-location"); + if (preference != null) + { + location = preference; + } + + if (NavigationBean.LOCATION_MYALFRESCO.equals(location)) + { + // Clear previous location - Fixes the issue ADB-61 + NavigationBean navigationBean = (NavigationBean)FacesHelper.getManagedBean(fc, "NavigationBean"); + if (navigationBean != null) + { + navigationBean.setLocation(null); + navigationBean.setToolbarLocation(null); + } + res.sendRedirect(req.getContextPath() + BaseServlet.FACES_SERVLET + "/jsp/dashboards/container.jsp"); + } + else + { + res.sendRedirect(req.getContextPath() + BaseServlet.FACES_SERVLET + FacesHelper.BROWSE_VIEW_ID); + } + return false; } else diff --git a/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java index ed3e975fc7..c0995905be 100644 --- a/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java @@ -26,6 +26,7 @@ package org.alfresco.web.app.servlet; import java.io.IOException; +import javax.faces.context.FacesContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -36,6 +37,9 @@ import org.springframework.extensions.config.ConfigService; import org.alfresco.repo.SessionUser; import org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.NavigationBean; +import org.alfresco.web.bean.repository.PreferencesService; import org.alfresco.web.bean.repository.User; import org.alfresco.web.config.ClientConfigElement; import org.apache.commons.logging.Log; @@ -90,7 +94,6 @@ public class NTLMAuthenticationFilter extends BaseNTLMAuthenticationFilter protected SessionUser createUserObject(String userName, String ticket, NodeRef personNode, NodeRef homeSpaceRef) { // Create a web client user object - User user = new User( userName, ticket, personNode); user.setHomeSpaceId( homeSpaceRef.getId()); @@ -115,7 +118,6 @@ public class NTLMAuthenticationFilter extends BaseNTLMAuthenticationFilter throws IOException { // Redirect to the login page if user validation fails - redirectToLoginPage(req, res); } @@ -123,17 +125,44 @@ public class NTLMAuthenticationFilter extends BaseNTLMAuthenticationFilter * @see org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter#onLoginComplete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override - protected boolean onLoginComplete(HttpServletRequest req, HttpServletResponse res) + protected boolean onLoginComplete(ServletContext sc, HttpServletRequest req, HttpServletResponse res, boolean userInit) throws IOException { // If the original URL requested was the login page then redirect to the browse view - if (req.getRequestURI().endsWith(getLoginPage()) == true) + if (userInit || req.getRequestURI().endsWith(getLoginPage())) { - if (logger.isDebugEnabled()) - logger.debug("Login page requested, redirecting to browse page"); - - // Redirect to the browse view - res.sendRedirect(req.getContextPath() + "/faces/jsp/browse/browse.jsp"); + if (logger.isDebugEnabled() && req.getRequestURI().endsWith(getLoginPage())) + logger.debug("Login page requested - redirecting to initially configured page"); + if (logger.isDebugEnabled() && userInit) + logger.debug("Session reinitialised - redirecting to initially configured page"); + + FacesContext fc = FacesHelper.getFacesContext(req, res, sc); + ConfigService configService = Application.getConfigService(fc); + ClientConfigElement configElement = (ClientConfigElement)configService.getGlobalConfig().getConfigElement("client"); + String location = configElement.getInitialLocation(); + + String preference = (String)PreferencesService.getPreferences(fc).getValue("start-location"); + if (preference != null) + { + location = preference; + } + + if (NavigationBean.LOCATION_MYALFRESCO.equals(location)) + { + // Clear previous location - Fixes the issue ADB-61 + NavigationBean navigationBean = (NavigationBean)FacesHelper.getManagedBean(fc, "NavigationBean"); + if (navigationBean != null) + { + navigationBean.setLocation(null); + navigationBean.setToolbarLocation(null); + } + res.sendRedirect(req.getContextPath() + BaseServlet.FACES_SERVLET + "/jsp/dashboards/container.jsp"); + } + else + { + res.sendRedirect(req.getContextPath() + BaseServlet.FACES_SERVLET + FacesHelper.BROWSE_VIEW_ID); + } + return false; } else diff --git a/source/java/org/alfresco/web/bean/generator/BaseComponentGenerator.java b/source/java/org/alfresco/web/bean/generator/BaseComponentGenerator.java index 65fb98ded4..e49a5bd1ec 100644 --- a/source/java/org/alfresco/web/bean/generator/BaseComponentGenerator.java +++ b/source/java/org/alfresco/web/bean/generator/BaseComponentGenerator.java @@ -45,6 +45,7 @@ import org.alfresco.repo.dictionary.constraint.StringLengthConstraint; import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.Constraint; import org.alfresco.service.cmr.dictionary.ConstraintDefinition; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.web.app.Application; import org.alfresco.web.app.servlet.FacesHelper; @@ -331,6 +332,12 @@ public abstract class BaseComponentGenerator implements IComponentGenerator if (getControlType() == ControlType.FIELD) { multiValueComponent.setRendererType(RepoConstants.ALFRESCO_FACES_FIELD_RENDERER); + + // set flag to indicate the wrapped field is multilingual, if necessary + if (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)) + { + multiValueComponent.getAttributes().put("mltext", Boolean.TRUE); + } } else { diff --git a/source/java/org/alfresco/web/bean/generator/MultilingualTextFieldGenerator.java b/source/java/org/alfresco/web/bean/generator/MultilingualTextFieldGenerator.java index d9f0082424..03c515e560 100644 --- a/source/java/org/alfresco/web/bean/generator/MultilingualTextFieldGenerator.java +++ b/source/java/org/alfresco/web/bean/generator/MultilingualTextFieldGenerator.java @@ -29,6 +29,7 @@ import javax.faces.component.UISelectOne; import javax.faces.context.FacesContext; import org.alfresco.web.ui.repo.RepoConstants; +import org.alfresco.web.ui.repo.component.UIMultiValueEditor; import org.alfresco.web.ui.repo.component.property.PropertySheetItem; import org.alfresco.web.ui.repo.component.property.UIPropertySheet; @@ -45,7 +46,8 @@ public class MultilingualTextFieldGenerator extends TextFieldGenerator { UIComponent component = super.generateAndAdd(context, propertySheet, item); - if ((component instanceof UISelectOne) == false) + if ((component instanceof UISelectOne) == false && + (component instanceof UIMultiValueEditor) == false) { component.setRendererType(RepoConstants.ALFRESCO_FACES_MLTEXT_RENDERER); } diff --git a/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java index 6f4e86face..8b14dee235 100644 --- a/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java +++ b/source/java/org/alfresco/web/bean/spaces/DeleteSpaceDialog.java @@ -65,9 +65,12 @@ public class DeleteSpaceDialog extends BaseDialogBean private static final String DELETE_CONTENTS = "contents"; private String deleteMode = DELETE_ALL; + private boolean executeRules = true; + private boolean archiveNodes = true; protected boolean hasMultipleParents = false; + // ------------------------------------------------------------------------------ // Dialog implementation @@ -99,81 +102,103 @@ public class DeleteSpaceDialog extends BaseDialogBean if (logger.isDebugEnabled()) logger.debug("Trying to delete space: " + node.getId() + " using delete mode: " + this.deleteMode); - if (DELETE_ALL.equals(this.deleteMode)) + try { - NodeRef nodeRef = node.getNodeRef(); - if (this.getNodeService().exists(nodeRef)) + if (!this.executeRules) { - // The node still exists - this.getNodeService().deleteNode(node.getNodeRef()); + Repository.getServiceRegistry(context).getRuleService().disableRules(); } - } - else - { - List childRefs = this.getNodeService().getChildAssocs(node.getNodeRef(), - ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - List deleteRefs = new ArrayList(childRefs.size()); - for (ChildAssociationRef ref : childRefs) + if (DELETE_ALL.equals(this.deleteMode)) { - NodeRef nodeRef = ref.getChildRef(); - + NodeRef nodeRef = node.getNodeRef(); + // Check the node still exists if (this.getNodeService().exists(nodeRef)) { - if (DELETE_CONTENTS.equals(this.deleteMode)) + if (!this.archiveNodes) { - deleteRefs.add(nodeRef); + this.getNodeService().addAspect(node.getNodeRef(), ContentModel.ASPECT_TEMPORARY, null); } - else + this.getNodeService().deleteNode(node.getNodeRef()); + } + } + else + { + List childRefs = this.getNodeService().getChildAssocs(node.getNodeRef(), + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); + List deleteRefs = new ArrayList(childRefs.size()); + for (ChildAssociationRef ref : childRefs) + { + NodeRef nodeRef = ref.getChildRef(); + + if (this.getNodeService().exists(nodeRef)) { - // find it's type so we can see if it's a node we are interested in - QName type = this.getNodeService().getType(nodeRef); - - // make sure the type is defined in the data dictionary - TypeDefinition typeDef = this.getDictionaryService().getType(type); - - if (typeDef != null) + if (DELETE_CONTENTS.equals(this.deleteMode)) { - if (DELETE_FOLDERS.equals(this.deleteMode)) + deleteRefs.add(nodeRef); + } + else + { + // find it's type so we can see if it's a node we are interested in + QName type = this.getNodeService().getType(nodeRef); + + // make sure the type is defined in the data dictionary + TypeDefinition typeDef = this.getDictionaryService().getType(type); + + if (typeDef != null) { - // look for folder type - if (this.getDictionaryService().isSubClass(type, ContentModel.TYPE_FOLDER) == true && - this.getDictionaryService().isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) + if (DELETE_FOLDERS.equals(this.deleteMode)) { - deleteRefs.add(nodeRef); + // look for folder type + if (this.getDictionaryService().isSubClass(type, ContentModel.TYPE_FOLDER) == true && + this.getDictionaryService().isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false) + { + deleteRefs.add(nodeRef); + } } - } - else if (DELETE_FILES.equals(this.deleteMode)) - { - // look for content file type - if (this.getDictionaryService().isSubClass(type, ContentModel.TYPE_CONTENT)) + else if (DELETE_FILES.equals(this.deleteMode)) { - deleteRefs.add(nodeRef); + // look for content file type + if (this.getDictionaryService().isSubClass(type, ContentModel.TYPE_CONTENT)) + { + deleteRefs.add(nodeRef); + } } } } } } + + // delete the list of refs + TransactionService txService = Repository.getServiceRegistry(context).getTransactionService(); + for (NodeRef nodeRef : deleteRefs) + { + UserTransaction tx = null; + + try + { + tx = txService.getNonPropagatingUserTransaction(); + tx.begin(); + + if (!this.archiveNodes) + { + this.getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null); + } + this.getNodeService().deleteNode(nodeRef); + + tx.commit(); + } + catch (Throwable err) + { + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + } + } } - - // delete the list of refs - TransactionService txService = Repository.getServiceRegistry(context).getTransactionService(); - for (NodeRef nodeRef : deleteRefs) + } + finally + { + if (!this.executeRules) { - UserTransaction tx = null; - - try - { - tx = txService.getNonPropagatingUserTransaction(); - tx.begin(); - - this.getNodeService().deleteNode(nodeRef); - - tx.commit(); - } - catch (Throwable err) - { - try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} - } + Repository.getServiceRegistry(context).getRuleService().enableRules(); } } } @@ -273,4 +298,36 @@ public class DeleteSpaceDialog extends BaseDialogBean { return this.hasMultipleParents; } + + /** + * @return true to execute rules during delete + */ + public boolean getExecuteRules() + { + return this.executeRules; + } + + /** + * @param executeRules execute rules during delete + */ + public void setExecuteRules(boolean executeRules) + { + this.executeRules = executeRules; + } + + /** + * @return true to archive nodes during delete + */ + public boolean getArchiveNodes() + { + return this.archiveNodes; + } + + /** + * @param archiveNodes archive nodes during delete + */ + public void setArchiveNodes(boolean archiveNodes) + { + this.archiveNodes = archiveNodes; + } } diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java index 848fe1e12c..30f5bef6fc 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java @@ -232,20 +232,20 @@ public class XFormsProcessor implements FormProcessor SimpleDateFormat.getDateInstance(DateFormat.SHORT, Application.getLanguage(fc)); js.append("alfresco.xforms.constants.DATE_FORMAT = '"). - append(sdf.toLocalizedPattern()). + append(sdf.toPattern()). append("';\n"); sdf = (SimpleDateFormat) SimpleDateFormat.getTimeInstance(DateFormat.SHORT, Application.getLanguage(fc)); js.append("alfresco.xforms.constants.TIME_FORMAT = '"). - append(sdf.toLocalizedPattern()). + append(sdf.toPattern()). append("';\n"); sdf = (SimpleDateFormat) SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Application.getLanguage(fc)); js.append("alfresco.xforms.constants.DATE_TIME_FORMAT = '"). - append(sdf.toLocalizedPattern()). + append(sdf.toPattern()). append("';\n"); for (String[] ns : JS_NAMESPACES) { diff --git a/source/java/org/alfresco/web/ui/repo/renderer/MultiValueFieldRenderer.java b/source/java/org/alfresco/web/ui/repo/renderer/MultiValueFieldRenderer.java index ee3518065c..b13f05f1b2 100644 --- a/source/java/org/alfresco/web/ui/repo/renderer/MultiValueFieldRenderer.java +++ b/source/java/org/alfresco/web/ui/repo/renderer/MultiValueFieldRenderer.java @@ -25,6 +25,7 @@ package org.alfresco.web.ui.repo.renderer; import java.io.IOException; +import java.util.Map; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; @@ -51,6 +52,7 @@ public class MultiValueFieldRenderer extends BaseMultiValueRenderer out.write(""); } + @SuppressWarnings("unchecked") @Override protected void renderPostWrappedComponent(FacesContext context, ResponseWriter out, UIMultiValueEditor editor) throws IOException @@ -59,6 +61,19 @@ public class MultiValueFieldRenderer extends BaseMultiValueRenderer out.write(Application.getMessage(context, MSG_ADD_TO_LIST_BUTTON)); out.write("' onclick=\""); out.write(generateFormSubmit(context, editor, Integer.toString(UIMultiValueEditor.ACTION_ADD))); - out.write("\"/>"); + out.write("\"/>"); + + // if the wrapped component is an mltext field add the icon + if (editor.getAttributes().get("mltext") != null) + { + String tooltip = Application.getMessage(context, "marker_tooltip"); + out.write(""); + } + + out.write(""); } } diff --git a/source/java/org/alfresco/web/ui/repo/tag/UploadFormTag.java b/source/java/org/alfresco/web/ui/repo/tag/UploadFormTag.java index 5a7980397a..7941b63118 100644 --- a/source/java/org/alfresco/web/ui/repo/tag/UploadFormTag.java +++ b/source/java/org/alfresco/web/ui/repo/tag/UploadFormTag.java @@ -33,6 +33,7 @@ import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import org.alfresco.web.app.Application; +import org.alfresco.web.app.servlet.BaseServlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -77,7 +78,7 @@ public class UploadFormTag extends TagSupport out.write(req.getContextPath()); out.write("/uploadFileServlet'>\n"); out.write("\n"); } } diff --git a/source/test-resources/xforms/tests/schema/readonly-and-default-values-test.xsd b/source/test-resources/xforms/tests/schema/readonly-and-default-values-test.xsd new file mode 100644 index 0000000000..109afee3f1 --- /dev/null +++ b/source/test-resources/xforms/tests/schema/readonly-and-default-values-test.xsd @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + full + + + full + + + minimal + + + minimal + + + + + + + + + + + + + + + + + + + + full + + + full + + + minimal + + + minimal + + + + + + + + + + + diff --git a/source/web/jsp/spaces/delete-space.jsp b/source/web/jsp/spaces/delete-space.jsp index 557a5422f5..b1c8bfec6a 100644 --- a/source/web/jsp/spaces/delete-space.jsp +++ b/source/web/jsp/spaces/delete-space.jsp @@ -78,3 +78,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/source/web/jsp/workflow/manage-task-dialog.jsp b/source/web/jsp/workflow/manage-task-dialog.jsp index c87256ccdc..d4a02d4b09 100644 --- a/source/web/jsp/workflow/manage-task-dialog.jsp +++ b/source/web/jsp/workflow/manage-task-dialog.jsp @@ -58,7 +58,7 @@ styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow" altRowStyleClass="recordSetRowAlt" width="100%" pageSize="10" initialSortColumn="name" initialSortDescending="true" - rendered="#{not empty DialogManager.bean.resources}"> + rendered="#{not empty DialogManager.bean.resources}" refreshOnBind="true"> <%-- Name column --%>