diff --git a/config/alfresco/templates/client/node_summary_panel.ftl b/config/alfresco/templates/client/node_summary_panel.ftl index 1a30ab6470..84d49d97e5 100644 --- a/config/alfresco/templates/client/node_summary_panel.ftl +++ b/config/alfresco/templates/client/node_summary_panel.ftl @@ -7,7 +7,7 @@
${node.name?html} | - <#if node.isDocument> + <#if node.isDocument || node.isLinkToDocument> <#assign navurl="/navigate/showDocDetails/"> <#else> <#assign navurl="/navigate/showSpaceDetails/"> diff --git a/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java index 37dff00e4e..b5efa0c092 100644 --- a/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/HTTPRequestAuthenticationFilter.java @@ -92,42 +92,6 @@ public class HTTPRequestAuthenticationFilter extends AbstractAuthenticationFilte private Pattern authPattern = null; - /** - * Define the HTTP header that contains the user name - * - * @param httpServletRequestAuthHeaderName - */ - public HTTPRequestAuthenticationFilter(String httpServletRequestAuthHeaderName) - { - this(httpServletRequestAuthHeaderName, null); - } - - /** - * Define the header that contains the user name and how to extract the user name. - * - * @param httpServletRequestAuthHeaderName - * @param authPatternString - */ - public HTTPRequestAuthenticationFilter(String httpServletRequestAuthHeaderName, String authPatternString) - { - super(); - assert (httpServletRequestAuthHeaderName != null); - this.httpServletRequestAuthHeaderName = httpServletRequestAuthHeaderName; - this.authPatternString = authPatternString; - if (this.authPatternString != null) - { - try - { - authPattern = Pattern.compile(this.authPatternString); - } - catch (PatternSyntaxException e) - { - logger.warn("Invalid pattern: " + this.authPatternString, e); - authPattern = null; - } - } - } - public void destroy() { // Nothing to do @@ -341,27 +305,51 @@ public class HTTPRequestAuthenticationFilter extends AbstractAuthenticationFilte I18NUtil.setLocale(Application.getLanguage(httpSess)); } + public void init(FilterConfig config) throws ServletException { + // Save the context + this.context = config.getServletContext(); + + // Setup the authentication context + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context); + ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); - transactionService = serviceRegistry.getTransactionService(); nodeService = serviceRegistry.getNodeService(); - + authService = serviceRegistry.getAuthenticationService(); + transactionService = serviceRegistry.getTransactionService(); + personService = (PersonService) ctx.getBean("PersonService"); // transactional and permission-checked authComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); - authService = (AuthenticationService) ctx.getBean("authenticationService"); - personService = (PersonService) ctx.getBean("personService"); - - // Get a list of the available locales - + + ConfigService configServiceService = (ConfigService) ctx.getBean("webClientConfigService"); LanguagesConfigElement configElement = (LanguagesConfigElement) configServiceService.getConfig("Languages") .getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID); m_languages = configElement.getLanguages(); - authPattern = Pattern.compile(authPatternString); + + httpServletRequestAuthHeaderName = config.getInitParameter("httpServletRequestAuthHeaderName"); + if(httpServletRequestAuthHeaderName == null) + { + httpServletRequestAuthHeaderName = "x-user"; + } + this.authPatternString = config.getInitParameter("authPatternString"); + if (this.authPatternString != null) + { + try + { + authPattern = Pattern.compile(this.authPatternString); + } + catch (PatternSyntaxException e) + { + logger.warn("Invalid pattern: " + this.authPatternString, e); + authPattern = null; + } + } + } /** diff --git a/source/java/org/alfresco/web/bean/wcm/LinkValidationDialog.java b/source/java/org/alfresco/web/bean/wcm/LinkValidationDialog.java index 8137f4ca40..b78676b525 100644 --- a/source/java/org/alfresco/web/bean/wcm/LinkValidationDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/LinkValidationDialog.java @@ -176,6 +176,9 @@ public class LinkValidationDialog extends BaseDialogBean this.runningReport = true; executeReport(); + // reset the isFinished flag so we can run the report again + this.isFinished = false; + return null; } diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index 6cae008eb1..48a058e2bf 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -51,6 +51,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMSyncService; @@ -414,6 +415,9 @@ public class SubmitDialog extends BaseDialogBean String destPath = stagingPath + wrapper.getPath(); AVMDifference diff = new AVMDifference(-1, srcPath, -1, destPath, AVMDifference.NEWER); diffs.add(diff); + + // process the expiration date (if any) + processExpirationDate(srcPath); // recursively remove locks from this item recursivelyRemoveLocks(storeId, -1, this.avmService.lookup(-1, srcPath, true), srcPath); @@ -426,9 +430,6 @@ public class SubmitDialog extends BaseDialogBean { this.virtUpdatePath = destPath; } - - // process the expiration date (if any) - processExpirationDate(srcPath); } // write changes to layer so files are marked as modified @@ -1033,8 +1034,12 @@ public class SubmitDialog extends BaseDialogBean submittedPaths.add(renditionPath); } } - this.workflows.add(new FormWorkflowWrapper(fid.getForm().getDefaultWorkflow().getName(), - fid.getForm().getDefaultWorkflowParameters())); + WorkflowDefinition defaultWfDef = fid.getForm().getDefaultWorkflow(); + if (defaultWfDef != null) + { + this.workflows.add(new FormWorkflowWrapper(defaultWfDef.getName(), + fid.getForm().getDefaultWorkflowParameters())); + } } } } @@ -1045,6 +1050,9 @@ public class SubmitDialog extends BaseDialogBean { // rollback the transaction on error try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + + // rethrow the exception to highlight the problem + throw (RuntimeException)e; } } diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java index 85768aac36..f91d74da9d 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -37,6 +37,7 @@ import javax.faces.context.FacesContext; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; +import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -201,8 +202,9 @@ public class FormImpl te); } result = AVMUtil.buildPath(parentAVMPath, - result, - AVMUtil.PathRelation.SANDBOX_RELATIVE); + result, + AVMUtil.PathRelation.SANDBOX_RELATIVE); + result = AVMNodeConverter.NormalizePath(result); LOGGER.debug("processed pattern " + outputPathPattern + " as " + result); return result; } diff --git a/source/java/org/alfresco/web/forms/FormsTest.java b/source/java/org/alfresco/web/forms/FormsTest.java new file mode 100644 index 0000000000..c1e429432f --- /dev/null +++ b/source/java/org/alfresco/web/forms/FormsTest.java @@ -0,0 +1,274 @@ +/* + * 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.forms; + +import java.io.*; +import java.util.*; +import org.alfresco.service.namespace.QName; +import org.alfresco.model.WCMAppModel; +import junit.framework.AssertionFailedError; +import org.alfresco.service.cmr.repository.*; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.util.BaseSpringTest; +import org.alfresco.web.forms.XMLUtil; +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.jxpath.Pointer; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chiba.xml.ns.NamespaceConstants; +import org.chiba.xml.events.XFormsEventNames; +import org.chiba.xml.events.XMLEvent; +import org.chiba.xml.xforms.ChibaBean; +import org.chiba.xml.xforms.exception.XFormsException; +import org.chiba.xml.xforms.XFormsElement; +import org.chiba.xml.events.DOMEventNames; +import org.w3c.dom.*; +import org.w3c.dom.events.*; +import org.xml.sax.*; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.cmr.model.*; +import org.alfresco.repo.security.authentication.MutableAuthenticationDao; +import org.alfresco.util.TestWithUserUtils; +import org.apache.shale.test.mock.*; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.StaticWebApplicationContext; + +/** + * JUnit tests to exercise parts of the forms codebase + * + * @author ariel backenroth + */ +public class FormsTest + extends BaseSpringTest +{ + + ///////////////////////////////////////////////////////////////////////////// + + private static class MockForm + extends FormImpl + { + + MockForm(final NodeRef folderNodeRef, + final FormsService formsService) + { + super(folderNodeRef, formsService); + } + + + public void setOutputPathPattern(final String opp) + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + nodeService.setProperty(this.getNodeRef(), WCMAppModel.PROP_OUTPUT_PATH_PATTERN, opp); + } + } + + ///////////////////////////////////////////////////////////////////////////// + + private final static Log LOGGER = LogFactory.getLog(FormsTest.class); + private final static String WEB_CLIENT_APPLICATION_CONTEXT = + "classpath:alfresco/web-client-application-context.xml"; + + private NodeService nodeService; + private FormsService formsService; + private MockForm mockForm; + + protected void onSetUpInTransaction() + throws Exception + { + System.err.println("onSetUpInTransaction"); + super.onSetUpInTransaction(); + this.nodeService = (NodeService)super.applicationContext.getBean("dbNodeService"); + assertNotNull(this.nodeService); + final FileFolderService fileFolderService = (FileFolderService) + super.applicationContext.getBean("fileFolderService"); + assertNotNull(fileFolderService); + this.formsService = (FormsService)super.applicationContext.getBean("FormsService"); + assertNotNull(this.formsService); + final AuthenticationService authenticationService = (AuthenticationService) + applicationContext.getBean("authenticationService"); + authenticationService.clearCurrentSecurityContext(); + final MutableAuthenticationDao authenticationDAO = (MutableAuthenticationDao) + applicationContext.getBean("authenticationDao"); + + // Create a workspace that contains the 'live' nodes + final StoreRef testStoreRef = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, + "Test_" + System.currentTimeMillis()); + + // Get a reference to the root node + final NodeRef rootNodeRef = this.nodeService.getRootNode(testStoreRef); + + // Create an authenticate the user + if(!authenticationDAO.userExists("admin")) + { + authenticationService.createAuthentication("admin", "admin".toCharArray()); + } + + TestWithUserUtils.authenticateUser("admin", + "admin", + rootNodeRef, + authenticationService); + + // set up a faces context + final MockExternalContext ec = new MockExternalContext(new MockServletContext(), + new MockHttpServletRequest(), + new MockHttpServletResponse()); + final StaticWebApplicationContext ac = new StaticWebApplicationContext(); + ac.setParent(this.applicationContext); + this.applicationContext = ac; + ec.getApplicationMap().put(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, + this.applicationContext); + new MockFacesContext(ec); + + + final FileInfo folderInfo = + fileFolderService.create(rootNodeRef, + "test_form", + WCMAppModel.TYPE_FORMFOLDER); + final HashMap