From c12bf069fa5fdd1e086797008215df90a5f913a3 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 14:42:34 +0000 Subject: [PATCH 01/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 129764 jvonka: REPO-1144: LockService - add isLocked & isLockedAndReadOnly common helper methods to public API - remove duplicated code from various locations to use the new methods - add sanity checks to Lock*Test git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130225 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/web/bean/repository/Node.java | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/source/java/org/alfresco/web/bean/repository/Node.java b/source/java/org/alfresco/web/bean/repository/Node.java index 930423f448..3b8002644c 100644 --- a/source/java/org/alfresco/web/bean/repository/Node.java +++ b/source/java/org/alfresco/web/bean/repository/Node.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository WAR Community - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Repository WAR Community + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.web.bean.repository; import java.io.IOException; @@ -427,11 +427,7 @@ public class Node implements Serializable, NamespacePrefixResolverProvider if (hasAspect(ContentModel.ASPECT_LOCKABLE)) { - LockStatus lockStatus = getServiceRegistry().getLockService().getLockStatus(getNodeRef()); - if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER) - { - locked = Boolean.TRUE; - } + locked = getServiceRegistry().getLockService().isLocked(getNodeRef()); } } From c2a6decad3475b59d33f822318c2140e4c46996a Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 14:47:06 +0000 Subject: [PATCH 02/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 130105 dhulley: Use alfresco-core:6.5 for the web-client project (REPO-990) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130253 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 7352c3db39..1f8ad9f5ba 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,9 @@ UTF-8 ${tomcat.default.alfresco.port} ${tomcat.default.alfresco.ssl.port} + + 6.5 + @@ -128,6 +131,7 @@ org.alfresco alfresco-core + ${dependency.alfresco-core.version} tests test @@ -216,6 +220,7 @@ ${project.groupId} alfresco-core + ${dependency.alfresco-core.version} log*.properties From 1ebc4289ddc340675b6a233a14146393a377aa63 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Sep 2016 14:47:24 +0000 Subject: [PATCH 03/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 130130 dhulley: Update root dependency for alfresco-core to 6.5 (REPO-990) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@130255 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pom.xml b/pom.xml index 1f8ad9f5ba..9e55c17c5b 100644 --- a/pom.xml +++ b/pom.xml @@ -17,8 +17,6 @@ ${tomcat.default.alfresco.port} ${tomcat.default.alfresco.ssl.port} - 6.5 - @@ -131,7 +129,6 @@ org.alfresco alfresco-core - ${dependency.alfresco-core.version} tests test @@ -220,7 +217,6 @@ ${project.groupId} alfresco-core - ${dependency.alfresco-core.version} log*.properties From 6f411d0d2767ce7a00f260ded44e18b53bafde4c Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:03:27 +0000 Subject: [PATCH 04/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 130406 jvonka: REPO-1062 / MNT-16176: allow existing users to use SSO external auth via Sharewhen repo is read-only - re-implement the fix (note: we do not allow auto-creation of missing users) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132128 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/app/servlet/AuthenticationHelper.java | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java index 63abdbf6f4..54e91dc8a7 100644 --- a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java +++ b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository WAR Community - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Repository WAR Community + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.web.app.servlet; import java.io.IOException; @@ -433,10 +433,14 @@ public final class AuthenticationHelper if (logger.isDebugEnabled()) logger.debug("Creating an object for " + currentUsername + " with ticket: " + ticket); final ServiceRegistry services = (ServiceRegistry) wc.getBean(ServiceRegistry.SERVICE_REGISTRY); + + // If the repository is read only, we have to settle for a read only transaction. Auto user creation + // will not be possible. + boolean readOnly = services.getTransactionService().isReadOnly(); + return services.getTransactionService().getRetryingTransactionHelper().doInTransaction( new RetryingTransactionHelper.RetryingTransactionCallback() { - public User execute() throws Throwable { NodeService nodeService = services.getNodeService(); @@ -453,7 +457,7 @@ public final class AuthenticationHelper user.setHomeSpaceId(homeRef.getId()); return user; } - }); + }, readOnly, false); } /** From 4c87e911b71cad31ac7dbccfe7d851c1d54df83c Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:15:35 +0000 Subject: [PATCH 05/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 130710 adavis: Merged 5.2.N-UPGRADES (5.2.1) to 5.2.N (5.2.1) 130660: Merged 5.2-UPGRADES (5.2.1) to 5.2.N-UPGRADES (5.2.1) << Some things have moved forwards on 5.2.N so the original commits are not the same >> - AuthUsers upgraded to the same as 5.2.N (5.2.0.1 -> 5.2.0.3) - isoparser upgraded to the same as 5.2.N (1.0-RC-15 to 1.0.2) 125130: ACE-4055 Revert upgrade of json to 20160212: it has incompatible changes, 125114: BDE-624 First batch of 3rd party upgrades in enterprise projects jasypt 1.9.1 -> 1.9.2 vaadin 6.8.8 -> 6.8.16, 125015: BDE-624 First batch of 3rd party upgrades Spring Framework 3.2.14.RELEASE -> 3.2.16.RELEASE Jackson2 2.3.2 -> 2.7.3 httpcomponents 4.5.1 -> 4.5.2 mysql driver 5.1.35 -> 5.1.38 postgresql driver 9.4-1201-jdbc41 -> 9.4.1208.jre7 slf4j 1.7.12 -> 1.7.21 json 20090211 -> 20160212 joda-time 2.8.1 -> 2.9.3 commons-compress 1.9 -> 1.11 commons-net 3.3 -> 3.4 commons-validator 1.4.1 -> 1.5.0 axiom 1.2.15 -> 1.2.18 jaxb 2.2.6 -> 2.2.7 myfaces 1.1.8 -> 1.1.10 h2 1.4.187 -> 1.4.191 browsermob 2.1.0-beta-1 -> 2.1.0-beta-5 javax.mail 1.5.2 -> 1.5.5 derby 10.11.1.1 -> 10.12.1.1 wss4j 1.5.12 -> 1.6.19 XmlSchema 1.4.5 -> 1.4.7 xstream 1.2.2 -> 1.3.1 geronimo-ws-metadata_2.0_spec 1.1.2 -> 1.1.3 stax-utils 20060502 -> 20070216 bcprov 1.45 -> 1.46 isoparser 1.0-RC-1 -> 1.0-RC-15 metadata-extractor 2.6.2 -> 2.9.0 jsr107cache 1.0 -> 1.1 concurrentlinkedhashmap 1.2 -> 1.4.2 FastInfoset 1.2.2 -> 1.2.13 groovy 2.4.4 -> 2.4.6 jmagick 6.2.4 -> 6.6.9 livetribe-jsr223 2.0.6 -> 2.0.7 netcdf 4.2-min -> 4.2.20 spring-social-facebook 1.0.0.RC1 -> 1.1.1.RELEASE spring-social-web 1.0.3.RELEASE -> 1.1.4.RELEASE spring-social-twitter 1.0.5.RELEASE -> 1.1.2.RELEASE spring-security-core 3.1.3.RELEASE -> 3.1.7.RELEASE aspectjrt 1.8.2 -> 1.8.7 solr4 4.10.3 -> 4.10.4 shale-test 1.0.4 -> 1.0.5, 130709: REPO-482 The platform uses the simple-to-upgrade libraries for 5.2 - UNDO metadata-extractor 2.6.2 -> 2.9.1 TikaAutoMetadataExtracterTest testImageVideo is failing. Had expected to have been able to take out the patch made in MNT-13920, but the metadata and properties now appear to be wrong in another way! git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132173 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e55c17c5b..6d2b309c16 100644 --- a/pom.xml +++ b/pom.xml @@ -160,7 +160,7 @@ org.apache.shale shale-test - 1.0.4 + 1.0.5 test From b4ed1d1fcec787f1507c198b32760cab76b1c0bb Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:46:48 +0000 Subject: [PATCH 06/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 131286 amukha: Merged DEV to 5.2.N (5.2.1) 131050 skopf: REPO-483 - The repository does not contain any code or data related to JBPM / ACE-1659 - Remove JBPM and Hibernate 131057 skopf: REPO-483 - The repository does not contain any code or data related to JBPM / ACE-1659 - Remove JBPM and Hibernate / fix test CMISTest.testModelAvailability 131064 skopf: REPO-483 - The repository does not contain any code or data related to JBPM / ACE-1659 - Remove JBPM and Hibernate - added patch to remove JBPM database tables 131169 skopf: REPO-483 - The repository does not contain any code or data related to JBPM / ACE-1659 - Remove JBPM and Hibernate - replaced generic DB script with database specific scripts 131171 skopf: REPO-483 - The repository does not contain any code or data related to JBPM / ACE-1659 - Remove JBPM and Hibernate - Fix DB2 patch 131213 skopf: REPO-483 - The repository does not contain any code or data related to JBPM / ACE-1659 - Remove JBPM and Hibernate - Fix JBPM table removal patch git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132233 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../servlet/AdminAuthenticationFilter.java | 2 +- .../app/servlet/JBPMDeployProcessServlet.java | 171 ----------- .../bean/workflow/StartWorkflowWizard.java | 2 - .../web/ui/repo/tag/JBPMProcessImageTag.java | 279 ------------------ 4 files changed, 1 insertion(+), 453 deletions(-) delete mode 100644 source/java/org/alfresco/web/app/servlet/JBPMDeployProcessServlet.java delete mode 100644 source/java/org/alfresco/web/ui/repo/tag/JBPMProcessImageTag.java diff --git a/source/java/org/alfresco/web/app/servlet/AdminAuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/AdminAuthenticationFilter.java index 0201922a0e..cdb315cbc8 100644 --- a/source/java/org/alfresco/web/app/servlet/AdminAuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/AdminAuthenticationFilter.java @@ -42,7 +42,7 @@ import org.apache.commons.logging.LogFactory; /** * This servlet filter is used to restrict direct URL access to administration - * resource in the web client, for example the admin and jBPM consoles. + * resource in the web client, for example the admin console. * * @author gavinc * @deprecated 5.0 not exposed in web-client web.xml diff --git a/source/java/org/alfresco/web/app/servlet/JBPMDeployProcessServlet.java b/source/java/org/alfresco/web/app/servlet/JBPMDeployProcessServlet.java deleted file mode 100644 index fa8f49f7b6..0000000000 --- a/source/java/org/alfresco/web/app/servlet/JBPMDeployProcessServlet.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * #%L - * Alfresco Repository WAR Community - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ -package org.alfresco.web.app.servlet; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; - -import javax.servlet.ServletException; -import javax.servlet.UnavailableException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.workflow.jbpm.JBPMEngine; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.workflow.WorkflowDefinition; -import org.alfresco.service.cmr.workflow.WorkflowDeployment; -import org.alfresco.service.cmr.workflow.WorkflowException; -import org.alfresco.service.cmr.workflow.WorkflowService; -import org.alfresco.util.PropertyCheck; -import org.apache.commons.fileupload.DiskFileUpload; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.FileUploadException; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.WebApplicationContextUtils; - - -/** - * Servlet for handling process deployments from jBPM process designer. - * - * @author davidc - * @deprecated 5.0 not exposed in web-client web.xml - */ -public class JBPMDeployProcessServlet extends HttpServlet -{ - private static final long serialVersionUID = 8002539291245090187L; - private static final String BEAN_GLOBAL_PROPERTIES = "global-properties"; - private static final String PROP_ENABLED = "system.workflow.deployservlet.enabled"; - - @Override - public void init() throws ServletException - { - // Render this servlet permanently unavailable if its enablement property is not set - WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - Properties globalProperties = (Properties) wc.getBean(BEAN_GLOBAL_PROPERTIES); - String enabled = globalProperties.getProperty(PROP_ENABLED); - if (!PropertyCheck.isValidPropertyString(enabled) || !Boolean.parseBoolean(enabled)) - { - throw new UnavailableException("system.workflow.deployservlet.enabled=false"); - } - } - - @Override - public void service(HttpServletRequest request, HttpServletResponse response) throws IOException - { - try - { - response.setContentType("text/html"); - InputStream deploymentArchive = getDeploymentArchive(request); - WorkflowDefinition workflowDef = deployArchive(deploymentArchive); - response.getWriter().println("Deployed archive " + workflowDef.title + " successfully"); - } - catch(IOException e) - { - // NOTE: according to original jBPM deployment servlet - response.getWriter().println("IOException"); - } - catch(FileUploadException e) - { - // NOTE: according to original jBPM deployment servlet - response.getWriter().println("FileUploadException"); - } - } - - /** - * Retrieve the JBPM Process Designer deployment archive from the request - * - * @param request the request - * @return the input stream onto the deployment archive - * @throws WorkflowException - * @throws FileUploadException - * @throws IOException - */ - private InputStream getDeploymentArchive(HttpServletRequest request) - throws FileUploadException, IOException - { - if (!FileUpload.isMultipartContent(request)) - { - throw new FileUploadException("Not a multipart request"); - } - - GPDUpload fileUpload = new GPDUpload(); - List list = fileUpload.parseRequest(request); - Iterator iterator = list.iterator(); - if (!iterator.hasNext()) - { - throw new FileUploadException("No process file in the request"); - } - - FileItem fileItem = (FileItem) iterator.next(); - if (fileItem.getContentType().indexOf("application/x-zip-compressed") == -1) - { - throw new FileUploadException("Not a process archive"); - } - - return fileItem.getInputStream(); - } - - - /** - * Deploy the jBPM process archive to the Alfresco Repository - * - * @param deploymentArchive the archive to deploy - * @return the deployed workflow definition - */ - private WorkflowDefinition deployArchive(InputStream deploymentArchive) - { - WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); - WorkflowService workflowService = (WorkflowService)wc.getBean(ServiceRegistry.WORKFLOW_SERVICE.getLocalName()); - WorkflowDeployment deployment = workflowService.deployDefinition(JBPMEngine.ENGINE_ID, deploymentArchive, MimetypeMap.MIMETYPE_ZIP); - return deployment.definition; - } - - - /** - * NOTE: Workaround... - * - * The JBPM process designer (as of 3.1.2) issues a request with a multi-part line - * delimited by ",". It should be ":" according to the HTTP specification which - * the commons file-upload is adhering to. - * - * @author davidc - */ - @SuppressWarnings("deprecation") - private class GPDUpload extends DiskFileUpload - { - @Override - protected byte[] getBoundary(String contentType) - { - return super.getBoundary(contentType.replace(",", ";")); - } - } -} \ No newline at end of file diff --git a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java index a97eb37acc..f890c3471c 100644 --- a/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java +++ b/source/java/org/alfresco/web/bean/workflow/StartWorkflowWizard.java @@ -47,7 +47,6 @@ import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.repo.publishing.PublishingEventHelper; import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.activiti.ActivitiConstants; -import org.alfresco.repo.workflow.jbpm.JBPMEngine; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.invitation.InvitationService; import org.alfresco.service.cmr.repository.InvalidNodeRefException; @@ -820,7 +819,6 @@ public class StartWorkflowWizard extends BaseWizardBean { publishingWorkflows = new ArrayList(2); - publishingWorkflows.add(JBPMEngine.ENGINE_ID + "$" + PublishingEventHelper.WORKFLOW_DEFINITION_NAME); publishingWorkflows.add(ActivitiConstants.ENGINE_ID + "$" + PublishingEventHelper.WORKFLOW_DEFINITION_NAME); } diff --git a/source/java/org/alfresco/web/ui/repo/tag/JBPMProcessImageTag.java b/source/java/org/alfresco/web/ui/repo/tag/JBPMProcessImageTag.java deleted file mode 100644 index 23011a0c67..0000000000 --- a/source/java/org/alfresco/web/ui/repo/tag/JBPMProcessImageTag.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * #%L - * Alfresco Repository WAR Community - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ -/* - * JBoss, Home of Professional Open Source - * Copyright 2005, JBoss Inc., and individual contributors as indicated - * by the @authors tag. See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ -package org.alfresco.web.ui.repo.tag; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.JspWriter; -import javax.servlet.jsp.tagext.TagSupport; - -import org.dom4j.DocumentException; -import org.dom4j.DocumentHelper; -import org.dom4j.Element; -import org.dom4j.XPath; -import org.dom4j.xpath.DefaultXPath; -import org.jbpm.JbpmContext; -import org.jbpm.file.def.FileDefinition; -import org.jbpm.graph.def.ProcessDefinition; -import org.jbpm.graph.exe.Token; -import org.jbpm.taskmgmt.exe.TaskInstance; - - -// -// -// TODO: DC - Tidy up -// -// - - - - -public class JBPMProcessImageTag extends TagSupport { - - private static final long serialVersionUID = 1L; - private long taskInstanceId = -1; - private long tokenInstanceId = -1; - - private byte[] gpdBytes = null; - private byte[] imageBytes = null; - private Token currentToken = null; - private ProcessDefinition processDefinition = null; - - static String currentTokenColor = "red"; - static String childTokenColor = "blue"; - static String tokenNameColor = "blue"; - - - public void release() { - taskInstanceId = -1; - gpdBytes = null; - imageBytes = null; - currentToken = null; - } - - public int doEndTag() throws JspException { - try { - initialize(); - retrieveByteArrays(); - if (gpdBytes != null && imageBytes != null) { - writeTable(); - } - } catch (IOException e) { - e.printStackTrace(); - throw new JspException("table couldn't be displayed", e); - } catch (DocumentException e) { - e.printStackTrace(); - throw new JspException("table couldn't be displayed", e); - } - release(); - return EVAL_PAGE; - } - - private void retrieveByteArrays() { - try { - FileDefinition fileDefinition = processDefinition.getFileDefinition(); - gpdBytes = fileDefinition.getBytes("gpd.xml"); - imageBytes = fileDefinition.getBytes("processimage.jpg"); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void writeTable() throws IOException, DocumentException { - - int borderWidth = 4; - Element rootDiagramElement = DocumentHelper.parseText(new String(gpdBytes)).getRootElement(); - int[] boxConstraint; - int[] imageDimension = extractImageDimension(rootDiagramElement); - String imageLink = "/alfresco/processimage?definitionId=" + processDefinition.getId(); - JspWriter jspOut = pageContext.getOut(); - - if (tokenInstanceId > 0) { - - List allTokens = new ArrayList(); - walkTokens(currentToken, allTokens); - - jspOut.println("
"); - - for (int i = 0; i < allTokens.size(); i++) - { - Token token = (Token) allTokens.get(i); - - //check how many tokens are on teh same level (= having the same parent) - int offset = i; - if(i > 0) { - while(offset > 0 && ((Token) allTokens.get(offset - 1)).getParent().equals(token.getParent())) { - offset--; - } - } - boxConstraint = extractBoxConstraint(rootDiagramElement, token); - - //Adjust for borders - //boxConstraint[2]-=borderWidth*2; - //boxConstraint[3]-=borderWidth*2; - - jspOut.println("
"); - - if(token.getName()!=null) - { - jspOut.println(" " + token.getName() +""); - } - - jspOut.println("
"); - } - jspOut.println("
"); - } - else - { - boxConstraint = extractBoxConstraint(rootDiagramElement); - - jspOut.println(""); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println("
"); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println(" "); - jspOut.println("
 
"); - jspOut.println("
"); - } - } - - private int[] extractBoxConstraint(Element root) { - int[] result = new int[4]; - String nodeName = currentToken.getNode().getName(); - XPath xPath = new DefaultXPath("//node[@name='" + nodeName + "']"); - Element node = (Element) xPath.selectSingleNode(root); - result[0] = Integer.valueOf(node.attribute("x").getValue()).intValue(); - result[1] = Integer.valueOf(node.attribute("y").getValue()).intValue(); - result[2] = Integer.valueOf(node.attribute("width").getValue()).intValue(); - result[3] = Integer.valueOf(node.attribute("height").getValue()).intValue(); - return result; - } - - private int[] extractBoxConstraint(Element root, Token token) { - int[] result = new int[4]; - String nodeName = token.getNode().getName(); - XPath xPath = new DefaultXPath("//node[@name='" + nodeName + "']"); - Element node = (Element) xPath.selectSingleNode(root); - result[0] = Integer.valueOf(node.attribute("x").getValue()).intValue(); - result[1] = Integer.valueOf(node.attribute("y").getValue()).intValue(); - result[2] = Integer.valueOf(node.attribute("width").getValue()).intValue(); - result[3] = Integer.valueOf(node.attribute("height").getValue()).intValue(); - return result; - } - - private int[] extractImageDimension(Element root) { - int[] result = new int[2]; - result[0] = Integer.valueOf(root.attribute("width").getValue()).intValue(); - result[1] = Integer.valueOf(root.attribute("height").getValue()).intValue(); - return result; - } - - private void initialize() { - JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext(); - if (this.taskInstanceId > 0) { - TaskInstance taskInstance = jbpmContext.getTaskMgmtSession().loadTaskInstance(taskInstanceId); - currentToken = taskInstance.getToken(); - } - else - { - if (this.tokenInstanceId > 0) - currentToken = jbpmContext.getGraphSession().loadToken(this.tokenInstanceId); - } - processDefinition = currentToken.getProcessInstance().getProcessDefinition(); - } - - private void walkTokens(Token parent, List allTokens) - { - Map children = parent.getChildren(); - if(children != null && children.size() > 0) - { - Collection childTokens = children.values(); - for (Iterator iterator = childTokens.iterator(); iterator.hasNext();) - { - Token child = (Token) iterator.next(); - walkTokens(child, allTokens); - } - } - - allTokens.add(parent); - } - - public void setTask(long id) { - this.taskInstanceId = id; - } - - public void setToken(long id) { - this.tokenInstanceId = id; - } - -} From 47ae44e500a8cfe964f9fa156ec986fa4f3ec83c Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:50:08 +0000 Subject: [PATCH 07/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 131370 adavis: Merged 5.2.N-SERVLET-3.0 (5.2.1) to 5.2.N (5.2.1) 130708: REPO-843 / REPO-1246: Upgrade to Servlet 3.0 (part I), 130714: REPO-843 / REPO-1246: Upgrade to Servlet 3.0 (part 1b) - fix web.xml (web-app), 130727: REPO-843 / REPO-1246: Upgrade to Servlet 3.0 (part 1b) - update other web.xml's (other than web-client project), 130844: REPO-843 / REPO-1251: Upgrade to Servlet API 3.0.x (part 2) - update to Spring WebScripts 6.9 (ACE-5584) - update to servlet-api 3.0.1, 130847: REPO-843 / REPO-1251: Upgrade to Servlet API 3.0.x (part 2) - update to Spring WebScripts 6.9 (ACE-5584) - follow-on to commit the correct pom.xml (ie. parent rather than overlay), 130852: REPO-843 / REPO-1251: Upgrade to Servlet API 3.0.x (part 2) - update to Spring WebScripts 6.9 (ACE-5584) - follow-on git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132252 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 2 +- source/web/WEB-INF/web.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 6d2b309c16..8e5a902c31 100644 --- a/pom.xml +++ b/pom.xml @@ -97,7 +97,7 @@ javax.servlet - servlet-api + javax.servlet-api provided diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index 3c1f134540..6b84d1f14e 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -1,8 +1,8 @@ - + Alfresco From 01156b23b57eca203465bac7371a9d24d81d7a8d Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:52:23 +0000 Subject: [PATCH 08/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 131485 kroast: Merged 5.2-DEV (5.2.0) to 5.2.N (5.2.N) 131352 kroast: ACE-4881 - [Pentest 121015] Multiple admin CSRF - Added CSRF filter config to protect the Alfresco Admin Console pages git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132265 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/web-client-security-config.xml | 118 ++++++++++++++++++ .../web/WEB-INF/web-application-context.xml | 33 +++-- source/web/WEB-INF/web.xml | 16 +++ 3 files changed, 159 insertions(+), 8 deletions(-) create mode 100644 config/alfresco/web-client-security-config.xml diff --git a/config/alfresco/web-client-security-config.xml b/config/alfresco/web-client-security-config.xml new file mode 100644 index 0000000000..bb620d3668 --- /dev/null +++ b/config/alfresco/web-client-security-config.xml @@ -0,0 +1,118 @@ + + + + + + + true + + + + + + alf-csrftoken + + + + + + + + + + + {token} +
{token}
+ {token} +
+ + + + + + + + GET + /service/enterprise/admin/.* + + + {token} + {token} + + + + + + + POST +
multipart/.+
+
+ + {token} + {token} + + + {referer} + + + {origin} + +
+ + + + + POST|PUT|DELETE + + + {token} + {token} + + + {referer} + + + {origin} + + +
+ +
+ +
\ No newline at end of file diff --git a/source/web/WEB-INF/web-application-context.xml b/source/web/WEB-INF/web-application-context.xml index b5d44df9bc..4928a19dee 100644 --- a/source/web/WEB-INF/web-application-context.xml +++ b/source/web/WEB-INF/web-application-context.xml @@ -2,12 +2,29 @@ - - - - - + + + + + + + + + + + classpath:alfresco/web-scripts-config.xml + classpath:alfresco/web-client-security-config.xml + classpath:alfresco/extension/web-scripts-config-custom.xml + + + + + + + + + \ No newline at end of file diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index 6b84d1f14e..3c89e4fa47 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -98,6 +98,12 @@ --> + + CSRF Token filter. Checks for a session based CSRF token in request headers (or form parameters) based on config. + CSRF Token Filter + org.springframework.extensions.webscripts.servlet.CSRFFilter + + @@ -232,6 +238,16 @@ /wcs/api/solr/* + + CSRF Token Filter + /service/enterprise/admin/* + + + + CSRF Token Filter + /s/enterprise/admin/* + + From 507e3f1c04320ecb4d2a0fe2073dad5511b58f8b Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 3 Nov 2016 13:53:13 +0000 Subject: [PATCH 09/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 131530 kroast: ACE-4881 - [Pentest 121015] Multiple admin CSRF - Fix issue spotted by Michael Suzuki, where the /s endpoint was not configured correctly to generate CSRF tokens git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132270 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/web-client-security-config.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/alfresco/web-client-security-config.xml b/config/alfresco/web-client-security-config.xml index bb620d3668..226b1e6075 100644 --- a/config/alfresco/web-client-security-config.xml +++ b/config/alfresco/web-client-security-config.xml @@ -69,6 +69,16 @@ {token} + + + GET + /s/enterprise/admin/.* + + + {token} + {token} + + diff --git a/source/web/WEB-INF/sun-jaxws.xml b/source/web/WEB-INF/sun-jaxws.xml deleted file mode 100644 index 5d8faa8332..0000000000 --- a/source/web/WEB-INF/sun-jaxws.xml +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - - - - - org.apache.chemistry.opencmis.server.impl.webservices.AuthHandler - - - - - - diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index 3c89e4fa47..b940b845da 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -271,11 +271,6 @@ org.alfresco.repo.webdav.WebDAVSessionListener - - - com.sun.xml.ws.transport.http.servlet.WSServletContextListener - - From 95a4158cabc5c068894e0f8e4a7fb27ef583376d Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 10 Nov 2016 16:56:50 +0000 Subject: [PATCH 11/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 132392 mmuller: Added the withShare profile for web-client like the enterprise version. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132661 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3282579be5..f9d586762f 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ UTF-8 ${tomcat.default.alfresco.port} ${tomcat.default.alfresco.ssl.port} - + 5.1.1 @@ -347,5 +347,48 @@
+ + withShare + + + org.alfresco + alfresco-share-services + ${runner.share.version} + amp + + + + + + maven-war-plugin + + + + org.alfresco + alfresco-share-services + amp + + + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + + + + org.alfresco + share + /share + ${runner.share.version} + war + true + + + + + + + From b47a414c5878746db227f913d6c6c4eb2692a7e1 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Thu, 10 Nov 2016 16:59:49 +0000 Subject: [PATCH 12/25] Merged 5.2.N (5.2.1) to HEAD (5.2) 132542 sglover: REPO-1505 "Add trashcan cleaner dependency to 5.2.N platform pom" git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@132674 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index f9d586762f..0672021a46 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,12 @@ + + ${project.groupId} + alfresco-trashcan-cleaner + ${dependency.alfresco-trashcan-cleaner.version} + + ${project.groupId} alfresco-remote-api From d8e17a3f2837cc63739030edbe55a5a6011291df Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Dec 2016 17:03:07 +0000 Subject: [PATCH 13/25] Merged 5.2.0 (5.2.0) to HEAD (5.2) 132913 kroast: Merged DEV/5.2.N_SUPPORTTOOLS to 5.2.N (5.2.1) 132731-132912 kroast: REPO-491 - Support Tools Productisation REPO-1560 Support tools part of the Administration Console code base REPO-1212 Merge in current Support Tools refactoring REPO-519 Improve CSS REPO-1075 Support Tools JMX Screen should include button to download a JMX Dump REPO-1076 Message should be added to the Active Sessions page about the limits of logging out a repo user Code cleanup Remove old _es translations (before full L10N pass) Removal of code duplications and includes More refactoring of pages, removal of duplicated code, removal of poor quality code and practices. Remove more l10n files that will be replaced. REPO-502 Localisation and language - pt1 REPO-502 Localisation and language - pt2 REPO-502 Localisation and language - pt3 REPO-502 Localisation and language - pt4 REPO-506 Unit and integration testing git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@133367 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- source/web/scripts/FileSaver.js | 260 ++++++++++++ source/web/scripts/smoothie.js | 691 ++++++++++++++++++++++++++++++++ 2 files changed, 951 insertions(+) create mode 100644 source/web/scripts/FileSaver.js create mode 100644 source/web/scripts/smoothie.js diff --git a/source/web/scripts/FileSaver.js b/source/web/scripts/FileSaver.js new file mode 100644 index 0000000000..963680c0fd --- /dev/null +++ b/source/web/scripts/FileSaver.js @@ -0,0 +1,260 @@ +/* FileSaver.js + * A saveAs() FileSaver implementation. + * 2013-10-21 + * + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * + * MIT/X11 license + * --------------- + * + * Copyright © 2011 [Eli Grey][1]. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * + * [1]: http://eligrey.com + * + * + * + * + */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs + || (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator)) + || (function(view) { + "use strict"; + var + doc = view.document + // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , URL = view.URL || view.webkitURL || view + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = !view.externalHost && "download" in save_link + , click = function(node) { + var event = doc.createEvent("MouseEvents"); + event.initMouseEvent( + "click", true, false, view, 0, 0, 0, 0, 0 + , false, false, false, false, 0, null + ); + node.dispatchEvent(event); + } + , webkit_req_fs = view.webkitRequestFileSystem + , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem + , throw_outside = function (ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + , fs_min_size = 0 + , deletion_queue = [] + , process_deletion_queue = function() { + var i = deletion_queue.length; + while (i--) { + var file = deletion_queue[i]; + if (typeof file === "string") { // file is an object URL + URL.revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + } + deletion_queue.length = 0; // clear queue + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , FileSaver = function(blob, name) { + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , blob_changed = false + , object_url + , target_view + , get_object_url = function() { + var object_url = get_URL().createObjectURL(blob); + deletion_queue.push(object_url); + return object_url; + } + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + // don't create more object URLs than needed + if (blob_changed || !object_url) { + object_url = get_object_url(blob); + } + if (target_view) { + target_view.location.href = object_url; + } else { + window.open(object_url, "_blank"); + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + } + , abortable = function(func) { + return function() { + if (filesaver.readyState !== filesaver.DONE) { + return func.apply(this, arguments); + } + }; + } + , create_if_not_found = {create: true, exclusive: false} + , slice + ; + filesaver.readyState = filesaver.INIT; + if (!name) { + name = "download"; + } + if (can_use_save_link) { + object_url = get_object_url(blob); + // FF for Android has a nasty garbage collection mechanism + // that turns all objects that are not pure javascript into 'deadObject' + // this means `doc` and `save_link` are unusable and need to be recreated + // `view` is usable though: + doc = view.document; + save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"); + save_link.href = object_url; + save_link.download = name; + var event = doc.createEvent("MouseEvents"); + event.initMouseEvent( + "click", true, false, view, 0, 0, 0, 0, 0 + , false, false, false, false, 0, null + ); + save_link.dispatchEvent(event); + filesaver.readyState = filesaver.DONE; + dispatch_all(); + return; + } + // Object and web filesystem URLs have a problem saving in Google Chrome when + // viewed in a tab, so I force save with application/octet-stream + // http://code.google.com/p/chromium/issues/detail?id=91158 + if (view.chrome && type && type !== force_saveable_type) { + slice = blob.slice || blob.webkitSlice; + blob = slice.call(blob, 0, blob.size, force_saveable_type); + blob_changed = true; + } + // Since I can't be sure that the guessed media type will trigger a download + // in WebKit, I append .download to the filename. + // https://bugs.webkit.org/show_bug.cgi?id=65440 + if (webkit_req_fs && name !== "download") { + name += ".download"; + } + if (type === force_saveable_type || webkit_req_fs) { + target_view = view; + } + if (!req_fs) { + fs_error(); + return; + } + fs_min_size += blob.size; + req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { + fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { + var save = function() { + dir.getFile(name, create_if_not_found, abortable(function(file) { + file.createWriter(abortable(function(writer) { + writer.onwriteend = function(event) { + target_view.location.href = file.toURL(); + deletion_queue.push(file); + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "writeend", event); + }; + writer.onerror = function() { + var error = writer.error; + if (error.code !== error.ABORT_ERR) { + fs_error(); + } + }; + "writestart progress write abort".split(" ").forEach(function(event) { + writer["on" + event] = filesaver["on" + event]; + }); + writer.write(blob); + filesaver.abort = function() { + writer.abort(); + filesaver.readyState = filesaver.DONE; + }; + filesaver.readyState = filesaver.WRITING; + }), fs_error); + }), fs_error); + }; + dir.getFile(name, {create: false}, abortable(function(file) { + // delete file if it already exists + file.remove(); + save(); + }), abortable(function(ex) { + if (ex.code === ex.NOT_FOUND_ERR) { + save(); + } else { + fs_error(); + } + })); + }), fs_error); + }), fs_error); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name) { + return new FileSaver(blob, name); + } + ; + FS_proto.abort = function() { + var filesaver = this; + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "abort"); + }; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + view.addEventListener("unload", process_deletion_queue, false); + return saveAs; +}(this.self || this.window || this.content)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if (typeof module !== 'undefined') module.exports = saveAs; diff --git a/source/web/scripts/smoothie.js b/source/web/scripts/smoothie.js new file mode 100644 index 0000000000..7616ed93b9 --- /dev/null +++ b/source/web/scripts/smoothie.js @@ -0,0 +1,691 @@ +// MIT License: +// +// Copyright (c) 2010-2013, Joe Walnes +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +/** + * Smoothie Charts - http://smoothiecharts.org/ + * (c) 2010-2013, Joe Walnes + * 2013, Drew Noakes + * + * v1.0: Main charting library, by Joe Walnes + * v1.1: Auto scaling of axis, by Neil Dunn + * v1.2: fps (frames per second) option, by Mathias Petterson + * v1.3: Fix for divide by zero, by Paul Nikitochkin + * v1.4: Set minimum, top-scale padding, remove timeseries, add optional timer to reset bounds, by Kelley Reynolds + * v1.5: Set default frames per second to 50... smoother. + * .start(), .stop() methods for conserving CPU, by Dmitry Vyal + * options.interpolation = 'bezier' or 'line', by Dmitry Vyal + * options.maxValue to fix scale, by Dmitry Vyal + * v1.6: minValue/maxValue will always get converted to floats, by Przemek Matylla + * v1.7: options.grid.fillStyle may be a transparent color, by Dmitry A. Shashkin + * Smooth rescaling, by Kostas Michalopoulos + * v1.8: Set max length to customize number of live points in the dataset with options.maxDataSetLength, by Krishna Narni + * v1.9: Display timestamps along the bottom, by Nick and Stev-io + * (https://groups.google.com/forum/?fromgroups#!topic/smoothie-charts/-Ywse8FCpKI%5B1-25%5D) + * Refactored by Krishna Narni, to support timestamp formatting function + * v1.10: Switch to requestAnimationFrame, removed the now obsoleted options.fps, by Gergely Imreh + * v1.11: options.grid.sharpLines option added, by @drewnoakes + * Addressed warning seen in Firefox when seriesOption.fillStyle undefined, by @drewnoakes + * v1.12: Support for horizontalLines added, by @drewnoakes + * Support for yRangeFunction callback added, by @drewnoakes + * v1.13: Fixed typo (#32), by @alnikitich + * v1.14: Timer cleared when last TimeSeries removed (#23), by @davidgaleano + * Fixed diagonal line on chart at start/end of data stream, by @drewnoakes + * v1.15: Support for npm package (#18), by @dominictarr + * Fixed broken removeTimeSeries function (#24) by @davidgaleano + * Minor performance and tidying, by @drewnoakes + * v1.16: Bug fix introduced in v1.14 relating to timer creation/clearance (#23), by @drewnoakes + * TimeSeries.append now deals with out-of-order timestamps, and can merge duplicates, by @zacwitte (#12) + * Documentation and some local variable renaming for clarity, by @drewnoakes + * v1.17: Allow control over font size (#10), by @drewnoakes + * Timestamp text won't overlap, by @drewnoakes + * v1.18: Allow control of max/min label precision, by @drewnoakes + * Added 'borderVisible' chart option, by @drewnoakes + * Allow drawing series with fill but no stroke (line), by @drewnoakes + * + * v.1.18.Alfresco by Antonio Soler + * Added different functions for date formatting depending on timescales for dates, hours or seconds + * Also added sieve: true to the chartoptions to use the alternative trim of timeseries ("sieve") + */ + +;(function(exports) { + + var Util = { + extend: function() { + arguments[0] = arguments[0] || {}; + for (var i = 1; i < arguments.length; i++) + { + for (var key in arguments[i]) + { + if (arguments[i].hasOwnProperty(key)) + { + if (typeof(arguments[i][key]) === 'object') { + if (arguments[i][key] instanceof Array) { + arguments[0][key] = arguments[i][key]; + } else { + arguments[0][key] = Util.extend(arguments[0][key], arguments[i][key]); + } + } else { + arguments[0][key] = arguments[i][key]; + } + } + } + } + return arguments[0]; + } + }; + + /** + * Initialises a new TimeSeries with optional data options. + * + * Options are of the form (defaults shown): + * + *
+   * {
+   *   resetBounds: true,        // enables/disables automatic scaling of the y-axis
+   *   resetBoundsInterval: 3000 // the period between scaling calculations, in millis
+   * }
+   * 
+ * + * Presentation options for TimeSeries are specified as an argument to SmoothieChart.addTimeSeries. + * + * @constructor + */ + function TimeSeries(options) { + this.options = Util.extend({}, TimeSeries.defaultOptions, options); + this.data = []; + this.maxValue = Number.NaN; // The maximum value ever seen in this TimeSeries. + this.minValue = Number.NaN; // The minimum value ever seen in this TimeSeries. + this.removedIndex = 0; + } + + TimeSeries.defaultOptions = { + resetBoundsInterval: 3000, + resetBounds: true + }; + + /** + * Recalculate the min/max values for this TimeSeries object. + * + * This causes the graph to scale itself in the y-axis. + */ + TimeSeries.prototype.resetBounds = function() { + if (this.data.length) { + // Walk through all data points, finding the min/max value + this.maxValue = this.data[0][1]; + this.minValue = this.data[0][1]; + for (var i = 1; i < this.data.length; i++) { + var value = this.data[i][1]; + if (value > this.maxValue) { + this.maxValue = value; + } + if (value < this.minValue) { + this.minValue = value; + } + } + } else { + // No data exists, so set min/max to NaN + this.maxValue = Number.NaN; + this.minValue = Number.NaN; + } + }; + + /** + * Adds a new data point to the TimeSeries, preserving chronological order. + * + * @param timestamp the position, in time, of this data point + * @param value the value of this data point + * @param sumRepeatedTimeStampValues if timestamp has an exact match in the series, this flag controls + * whether it is replaced, or the values summed (defaults to false.) + */ + TimeSeries.prototype.append = function(timestamp, value, sumRepeatedTimeStampValues) { + // Rewind until we hit an older timestamp + var i = this.data.length - 1; + while (i > 0 && this.data[i][0] > timestamp) { + i--; + } + + if (this.data.length > 0 && this.data[i][0] === timestamp) { + // Update existing values in the array + if (sumRepeatedTimeStampValues) { + // Sum this value into the existing 'bucket' + this.data[i][1] += value; + value = this.data[i][1]; + } else { + // Replace the previous value + this.data[i][1] = value; + } + } else if (i < this.data.length - 1) { + // Splice into the correct position to keep timestamps in order + this.data.splice(i + 1, 0, [timestamp, value]); + } else { + // Add to the end of the array + this.data.push([timestamp, value]); + } + + this.maxValue = isNaN(this.maxValue) ? value : Math.max(this.maxValue, value); + this.minValue = isNaN(this.minValue) ? value : Math.min(this.minValue, value); + }; + + TimeSeries.prototype.dropOldData = function(oldestValidTime, maxDataSetLength) { + // We must always keep one expired data point as we need this to draw the + // line that comes into the chart from the left, but any points prior to that can be removed. + var removeCount = 0; + while (this.data.length - removeCount >= maxDataSetLength && this.data[removeCount + 1][0] < oldestValidTime) { + removeCount++; + } + if (removeCount !== 0) { + this.data.splice(0, removeCount); + } + }; + + TimeSeries.prototype.sieve = function(thiswidth) { + // on my particular use case I don't need a lot of definition on data over 10 minutes + // and I cannot trim the array if I want to retrace after changing timescale + // so I can save some memory deleting some random data on older values + + while (this.data.length > thiswidth*6 ){ + this.data.splice(Math.floor(Math.random()*thiswidth + Math.random()*thiswidth*2 ),1); + this.removedIndex++ + } + }; + + /** + * Initialises a new SmoothieChart. + * + * Options are optional, and should be of the form below. Just specify the values you + * need and the rest will be given sensible defaults as shown: + * + *
+   * {
+   *   minValue: undefined,        // specify to clamp the lower y-axis to a given value
+   *   maxValue: undefined,        // specify to clamp the upper y-axis to a given value
+   *   maxValueScale: 1,           // allows proportional padding to be added above the chart. for 10% padding, specify 1.1.
+   *   yRangeFunction: undefined,  // function({min: , max: }) { return {min: , max: }; }
+   *   scaleSmoothing: 0.125,      // controls the rate at which y-value zoom animation occurs
+   *   millisPerPixel: 20,         // sets the speed at which the chart pans by
+   *   maxDataSetLength: 2,
+   *   interpolation: 'bezier'     // or 'linear'
+   *   timestampFormatter: null,   // Optional function to format time stamps for bottom of chart. You may use SmoothieChart.timeFormatter, or your own: function(date) { return ''; }
+   *   horizontalLines: [],        // [ { value: 0, color: '#ffffff', lineWidth: 1 } ],
+   *   grid:
+   *   {
+   *     fillStyle: '#000000',     // the background colour of the chart
+   *     lineWidth: 1,             // the pixel width of grid lines
+   *     strokeStyle: '#777777',   // colour of grid lines
+   *     millisPerLine: 1000,      // distance between vertical grid lines
+   *     sharpLines: false,        // controls whether grid lines are 1px sharp, or softened
+   *     verticalSections: 2,      // number of vertical sections marked out by horizontal grid lines
+   *     borderVisible: true       // whether the grid lines trace the border of the chart or not
+   *   },
+   *   labels
+   *   {
+   *     disabled: false,          // enables/disables labels showing the min/max values
+   *     fillStyle: '#ffffff',     // colour for text of labels,
+   *     fontSize: 15,
+   *     fontFamily: 'sans-serif',
+   *     precision: 2
+   *   },
+   * }
+   * 
+ * + * @constructor + */ + function SmoothieChart(options) { + this.options = Util.extend({}, SmoothieChart.defaultChartOptions, options); + this.seriesSet = []; + this.currentValueRange = 1; + this.currentVisMinValue = 0; + } + + SmoothieChart.defaultChartOptions = { + millisPerPixel: 20, + maxValueScale: 1, + interpolation: 'bezier', + scaleSmoothing: 0.125, + maxDataSetLength: 2, + grid: { + fillStyle: '#000000', + strokeStyle: '#777777', + lineWidth: 1, + sharpLines: false, + millisPerLine: 1000, + verticalSections: 2, + borderVisible: true + }, + labels: { + fillStyle: '#ffffff', + disabled: false, + fontSize: 10, + fontFamily: 'monospace', + precision: 2 + }, + horizontalLines: [] + }; + + // Based on http://inspirit.github.com/jsfeat/js/compatibility.js + SmoothieChart.AnimateCompatibility = (function() { + // TODO this global variable will cause bugs if more than one chart is used and the browser does not support *requestAnimationFrame natively + var lastTime = 0, + requestAnimationFrame = function(callback, element) { + var requestAnimationFrame = + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback) { + var currTime = new Date().getTime(), + timeToCall = Math.max(0, 16 - (currTime - lastTime)), + id = window.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + return requestAnimationFrame.call(window, callback, element); + }, + cancelAnimationFrame = function(id) { + var cancelAnimationFrame = + window.cancelAnimationFrame || + function(id) { + clearTimeout(id); + }; + return cancelAnimationFrame.call(window, id); + }; + + return { + requestAnimationFrame: requestAnimationFrame, + cancelAnimationFrame: cancelAnimationFrame + }; + })(); + + SmoothieChart.defaultSeriesPresentationOptions = { + lineWidth: 1, + strokeStyle: '#ffffff' + }; + + /** + * Adds a TimeSeries to this chart, with optional presentation options. + * + * Presentation options should be of the form (defaults shown): + * + *
+   * {
+   *   lineWidth: 1,
+   *   strokeStyle: '#ffffff',
+   *   fillStyle: undefined
+   * }
+   * 
+ */ + SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) { + this.seriesSet.push({timeSeries: timeSeries, options: Util.extend({}, SmoothieChart.defaultSeriesPresentationOptions, options)}); + if (timeSeries.options.resetBounds && timeSeries.options.resetBoundsInterval > 0) { + timeSeries.resetBoundsTimerId = setInterval( + function() { + timeSeries.resetBounds(); + }, + timeSeries.options.resetBoundsInterval + ); + } + }; + + /** + * Removes the specified TimeSeries from the chart. + */ + SmoothieChart.prototype.removeTimeSeries = function(timeSeries) { + // Find the correct timeseries to remove, and remove it + var numSeries = this.seriesSet.length; + for (var i = 0; i < numSeries; i++) { + if (this.seriesSet[i].timeSeries === timeSeries) { + this.seriesSet.splice(i, 1); + break; + } + } + // If a timer was operating for that timeseries, remove it + if (timeSeries.resetBoundsTimerId) { + // Stop resetting the bounds, if we were + clearInterval(timeSeries.resetBoundsTimerId); + } + }; + + /** + * Instructs the SmoothieChart to start rendering to the provided canvas, with specified delay. + * + * @param canvas the target canvas element + * @param delayMillis an amount of time to wait before a data point is shown. This can prevent the end of the series + * from appearing on screen, with new values flashing into view, at the expense of some latency. + */ + SmoothieChart.prototype.streamTo = function(canvas, delayMillis) { + this.canvas = canvas; + this.delay = delayMillis; + this.start(); + }; + + /** + * Starts the animation of this chart. + */ + SmoothieChart.prototype.start = function() { + if (this.frame) { + // We're already running, so just return + return; + } + + // Renders a frame, and queues the next frame for later rendering + var animate = function() { + this.frame = SmoothieChart.AnimateCompatibility.requestAnimationFrame(function() { + this.render(); + animate(); + }.bind(this)); + }.bind(this); + + animate(); + }; + + /** + * Stops the animation of this chart. + */ + SmoothieChart.prototype.stop = function() { + if (this.frame) { + SmoothieChart.AnimateCompatibility.cancelAnimationFrame(this.frame); + delete this.frame; + } + }; + + SmoothieChart.prototype.updateValueRange = function() { + // Calculate the current scale of the chart, from all time series. + var chartOptions = this.options, + chartMaxValue = Number.NaN, + chartMinValue = Number.NaN; + + for (var d = 0; d < this.seriesSet.length; d++) { + // TODO(ndunn): We could calculate / track these values as they stream in. + var timeSeries = this.seriesSet[d].timeSeries; + if (!isNaN(timeSeries.maxValue)) { + chartMaxValue = !isNaN(chartMaxValue) ? Math.max(chartMaxValue, timeSeries.maxValue) : timeSeries.maxValue; + } + + if (!isNaN(timeSeries.minValue)) { + chartMinValue = !isNaN(chartMinValue) ? Math.min(chartMinValue, timeSeries.minValue) : timeSeries.minValue; + } + } + + // Scale the chartMaxValue to add padding at the top if required + if (chartOptions.maxValue != null) { + chartMaxValue = chartOptions.maxValue; + } else { + chartMaxValue *= chartOptions.maxValueScale; + } + + // Set the minimum if we've specified one + if (chartOptions.minValue != null) { + chartMinValue = chartOptions.minValue; + } + + // If a custom range function is set, call it + if (this.options.yRangeFunction) { + var range = this.options.yRangeFunction({min: chartMinValue, max: chartMaxValue}); + chartMinValue = range.min; + chartMaxValue = range.max; + } + + if (!isNaN(chartMaxValue) && !isNaN(chartMinValue)) { + var targetValueRange = chartMaxValue - chartMinValue; + this.currentValueRange += chartOptions.scaleSmoothing * (targetValueRange - this.currentValueRange); + this.currentVisMinValue += chartOptions.scaleSmoothing * (chartMinValue - this.currentVisMinValue); + } + + this.valueRange = { min: chartMinValue, max: chartMaxValue }; + }; + + SmoothieChart.prototype.render = function(canvas, time) { + canvas = canvas || this.canvas; + time = time || new Date().getTime() - (this.delay || 0); + + // TODO only render if the chart has moved at least 1px since the last rendered frame + + // Round time down to pixel granularity, so motion appears smoother. + time -= time % this.options.millisPerPixel; + + var context = canvas.getContext('2d'), + chartOptions = this.options, + dimensions = { top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight }, + // Calculate the threshold time for the oldest data points. + oldestValidTime = time - (dimensions.width * chartOptions.millisPerPixel), + valueToYPixel = function(value) { + var offset = value - this.currentVisMinValue; + return this.currentValueRange === 0 + ? dimensions.height + : dimensions.height - (Math.round((offset / this.currentValueRange) * dimensions.height)); + }.bind(this), + timeToXPixel = function(t) { + return Math.round(dimensions.width - ((time - t) / chartOptions.millisPerPixel)); + }; + + this.updateValueRange(); + + context.font = chartOptions.labels.fontSize + 'px ' + chartOptions.labels.fontFamily; + + // Save the state of the canvas context, any transformations applied in this method + // will get removed from the stack at the end of this method when .restore() is called. + context.save(); + + // Move the origin. + context.translate(dimensions.left, dimensions.top); + + // Create a clipped rectangle - anything we draw will be constrained to this rectangle. + // This prevents the occasional pixels from curves near the edges overrunning and creating + // screen cheese (that phrase should need no explanation). + context.beginPath(); + context.rect(0, 0, dimensions.width, dimensions.height); + context.clip(); + + // Clear the working area. + context.save(); + context.fillStyle = chartOptions.grid.fillStyle; + context.clearRect(0, 0, dimensions.width, dimensions.height); + context.fillRect(0, 0, dimensions.width, dimensions.height); + context.restore(); + + // Grid lines... + context.save(); + context.lineWidth = chartOptions.grid.lineWidth; + context.strokeStyle = chartOptions.grid.strokeStyle; + // Vertical (time) dividers. + if (chartOptions.grid.millisPerLine > 0) { + var textUntilX = dimensions.width - context.measureText(minValueString).width + 4; + for (var t = time - (time % chartOptions.grid.millisPerLine); + t >= oldestValidTime; + t -= chartOptions.grid.millisPerLine) { + var gx = timeToXPixel(t); + if (chartOptions.grid.sharpLines) { + gx -= 0.5; + } + context.beginPath(); + context.moveTo(gx, 0); + context.lineTo(gx, dimensions.height); + context.stroke(); + context.closePath(); + + // Display timestamp at bottom of this line if requested, and it won't overlap + if (chartOptions.timestampFormatter && gx < textUntilX) { + // Formats the timestamp based on user specified formatting function + // SmoothieChart.timeFormatter function above is one such formatting option + var tx = new Date(t), + ts = chartOptions.timestampFormatter(tx), + tsWidth = context.measureText(ts).width; + textUntilX = gx - tsWidth - 2; + context.fillStyle = chartOptions.labels.fillStyle; + context.fillText(ts, gx - tsWidth, dimensions.height - 2); + } + } + } + + // Horizontal (value) dividers. + for (var v = 1; v < chartOptions.grid.verticalSections; v++) { + var gy = Math.round(v * dimensions.height / chartOptions.grid.verticalSections); + if (chartOptions.grid.sharpLines) { + gy -= 0.5; + } + context.beginPath(); + context.moveTo(0, gy); + context.lineTo(dimensions.width, gy); + context.stroke(); + context.closePath(); + } + // Bounding rectangle. + if (chartOptions.grid.borderVisible) { + context.beginPath(); + context.strokeRect(0, 0, dimensions.width, dimensions.height); + context.closePath(); + } + context.restore(); + + // Draw any horizontal lines... + if (chartOptions.horizontalLines && chartOptions.horizontalLines.length) { + for (var hl = 0; hl < chartOptions.horizontalLines.length; hl++) { + var line = chartOptions.horizontalLines[hl], + hly = Math.round(valueToYPixel(line.value)) - 0.5; + context.strokeStyle = line.color || '#ffffff'; + context.lineWidth = line.lineWidth || 1; + context.beginPath(); + context.moveTo(0, hly); + context.lineTo(dimensions.width, hly); + context.stroke(); + context.closePath(); + } + } + + // For each data set... + for (var d = 0; d < this.seriesSet.length; d++) { + context.save(); + var timeSeries = this.seriesSet[d].timeSeries, + dataSet = timeSeries.data, + seriesOptions = this.seriesSet[d].options; + + // Delete old data that's moved off the left of the chart. + if (chartOptions.sieve){ + timeSeries.sieve(dimensions.width); + } + else{ + timeSeries.dropOldData(oldestValidTime , chartOptions.maxDataSetLength); + } + // Set style for this dataSet. + context.lineWidth = seriesOptions.lineWidth; + context.strokeStyle = seriesOptions.strokeStyle; + // Draw the line... + context.beginPath(); + // Retain lastX, lastY for calculating the control points of bezier curves. + var firstX = 0, lastX = 0, lastY = 0; + for (var i = 0; i < dataSet.length && dataSet.length !== 1; i++) { + var x = timeToXPixel(dataSet[i][0]), + y = valueToYPixel(dataSet[i][1]); + + if (i === 0) { + firstX = x; + context.moveTo(x, y); + } else { + switch (chartOptions.interpolation) { + case "linear": + case "line": { + context.lineTo(x,y); + break; + } + case "bezier": + default: { + // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/Bezier_curve#Quadratic_curves + // + // Assuming A was the last point in the line plotted and B is the new point, + // we draw a curve with control points P and Q as below. + // + // A---P + // | + // | + // | + // Q---B + // + // Importantly, A and P are at the same y coordinate, as are B and Q. This is + // so adjacent curves appear to flow as one. + // + context.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop + Math.round((lastX + x) / 2), lastY, // controlPoint1 (P) + Math.round((lastX + x)) / 2, y, // controlPoint2 (Q) + x, y); // endPoint (B) + break; + } + } + } + + lastX = x; lastY = y; + } + + if (dataSet.length > 1) { + if (seriesOptions.fillStyle) { + // Close up the fill region. + context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY); + context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1); + context.lineTo(firstX, dimensions.height + seriesOptions.lineWidth); + context.fillStyle = seriesOptions.fillStyle; + context.fill(); + } + + if (seriesOptions.strokeStyle && seriesOptions.strokeStyle !== 'none') { + context.stroke(); + } + context.closePath(); + } + context.restore(); + } + + // Draw the axis values on the chart. + if (!chartOptions.labels.disabled && !isNaN(this.valueRange.min) && !isNaN(this.valueRange.max)) { + var maxValueString = parseFloat(this.valueRange.max).toFixed(chartOptions.labels.precision), + minValueString = parseFloat(this.valueRange.min).toFixed(chartOptions.labels.precision); + context.fillStyle = chartOptions.labels.fillStyle; + context.fillText(maxValueString, dimensions.width - context.measureText(maxValueString).width - 2, chartOptions.labels.fontSize); + context.fillText(minValueString, dimensions.width - context.measureText(minValueString).width - 2, dimensions.height - 2); + } + context.restore(); // See .save() above. + }; + + // Sample timestamp formatting function + SmoothieChart.timeFormatter = function(date) { + function pad2(number) { return (number < 10 ? '0' : '') + number } + //return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + pad2(date.getSeconds()); + return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) ; + }; + + SmoothieChart.secondsFormatter = function(date) { + function pad2(number) { return (number < 10 ? '0' : '') + number } + //return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + pad2(date.getSeconds()); + return "'"+pad2(date.getSeconds()) ; + }; + + SmoothieChart.dateFormatter = function(date) { + function pad2(number) { return (number < 10 ? '0' : '') + number } + //return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + pad2(date.getSeconds()); + return pad2(date.getMonth()+1) + '/' + pad2(date.getDate()) ; + }; + + exports.TimeSeries = TimeSeries; + exports.SmoothieChart = SmoothieChart; + +})(typeof exports === 'undefined' ? this : exports); From f24a151ad1a59846beca25332b94e1d243898027 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 6 Dec 2016 17:17:10 +0000 Subject: [PATCH 14/25] Merged 5.2.0 (5.2.0) to HEAD (5.2) 133050 amorarasu: REPO-1541: Revert changes done to web.xml in MNT-16334 due to Servlet 2.5 limitation - removed placeholders for AOSM. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@133385 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- source/web/WEB-INF/web.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index b940b845da..1412d0a039 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -104,7 +104,6 @@ org.springframework.extensions.webscripts.servlet.CSRFFilter - - @@ -431,8 +428,6 @@ - - @@ -528,8 +523,6 @@ CMISTCK --> - - From 3cb36e9724b95a3c1f9fd154ef0355008cfaf9ca Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Fri, 13 Jan 2017 13:58:04 +0000 Subject: [PATCH 15/25] ALF-21809 - The Community admin console isn't using the CSRF prevention token git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@134344 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- source/web/WEB-INF/web.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml index 1412d0a039..b03a2196bc 100644 --- a/source/web/WEB-INF/web.xml +++ b/source/web/WEB-INF/web.xml @@ -246,6 +246,16 @@ CSRF Token Filter /s/enterprise/admin/* + + + CSRF Token Filter + /service/admin/* + + + + CSRF Token Filter + /s/admin/* + From d6da8d3084552e51ddc558c60816105b29462bc3 Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Tue, 7 Feb 2017 15:04:27 +0000 Subject: [PATCH 16/25] Merged 5.2.0 (5.2.0) to HEAD (5.2) 134319 kroast: Merged 134318 Copyright 2017 on Alfresco repo web app index page git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@134969 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- source/web/index.jsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/web/index.jsp b/source/web/index.jsp index 7d11dbfe34..33b0b1d455 100644 --- a/source/web/index.jsp +++ b/source/web/index.jsp @@ -122,7 +122,7 @@ ModuleDetails shareServicesModule = moduleService.getModule("alfresco-share-serv
From 2b5212551b5c1a568d7af448ad3e58829a891d5a Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Mon, 13 Feb 2017 16:36:11 +0000 Subject: [PATCH 17/25] ALF-21809 - The Community admin console isn't using the CSRF prevention token pt2 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@135119 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/web-client-security-config.xml | 60 +++++++++++++++++++ source/web/WEB-INF/web.xml | 20 +++++++ 2 files changed, 80 insertions(+) diff --git a/config/alfresco/web-client-security-config.xml b/config/alfresco/web-client-security-config.xml index 226b1e6075..87f6dd1a7c 100644 --- a/config/alfresco/web-client-security-config.xml +++ b/config/alfresco/web-client-security-config.xml @@ -79,6 +79,66 @@ {token} + + + GET + /wcservice/enterprise/admin/.* + + + {token} + {token} + + + + + GET + /wcs/enterprise/admin/.* + + + {token} + {token} + + + + + GET + /service/admin/.* + + + {token} + {token} + + + + + GET + /s/admin/.* + + + {token} + {token} + + + + + GET + /wcservice/admin/.* + + + {token} + {token} + + + + + GET + /wcs/admin/.* + + + {token} + {token} + + From 3dd3ed370dc153a190f5c61f0f8d04d7a435475e Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Wed, 14 Jun 2017 17:13:32 +0000 Subject: [PATCH 18/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 135848 anechifor: 135848 anechifor: REPO-1193 MNT-16734: Added a new release version alfresco-messaging-repo 1.2.8 Resolve security issue CVE-2014-3612 updating ActiveMQ 5.13.0. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137418 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 80 ++++++++++----------------------------------------------- 1 file changed, 13 insertions(+), 67 deletions(-) diff --git a/pom.xml b/pom.xml index 0672021a46..5664090954 100644 --- a/pom.xml +++ b/pom.xml @@ -13,19 +13,11 @@ /alfresco - UTF-8 ${tomcat.default.alfresco.port} ${tomcat.default.alfresco.ssl.port} - 5.1.1 - - ${project.groupId} - alfresco-trashcan-cleaner - ${dependency.alfresco-trashcan-cleaner.version} - - ${project.groupId} alfresco-remote-api @@ -94,11 +86,16 @@ standard 1.1.2 + + org.apache.chemistry.opencmis + chemistry-opencmis-test-browser + ${dependency.opencmis.version} + javax.servlet - javax.servlet-api + servlet-api provided @@ -116,14 +113,14 @@ org.alfresco.services alfresco-messaging-repo - 1.2.5 + 1.2.8 com.thetransactioncompany cors-filter - 2.5 + 1.9.3 @@ -161,7 +158,7 @@ org.apache.shale shale-test - 1.0.5 + 1.0.4 test @@ -229,7 +226,7 @@ maven-antrun-plugin - + fetch-jmxrmi-properties @@ -322,15 +319,7 @@ true ${runtime.tomcat.conf.folder}/solr-context.xml - - org.alfresco - api-explorer - ${dependency.api-explorer.version} - /api-explorer - war - true - - + @@ -350,51 +339,8 @@ mysql mysql-connector-java - + - - withShare - - - org.alfresco - alfresco-share-services - ${runner.share.version} - amp - - - - - - maven-war-plugin - - - - org.alfresco - alfresco-share-services - amp - - - - - - org.apache.tomcat.maven - tomcat7-maven-plugin - - - - org.alfresco - share - /share - ${runner.share.version} - war - true - - - - - - - - + From 04321e40d7c48a04e0c0e61e72e3f8fa85d56476 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 10:55:43 +0000 Subject: [PATCH 19/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 135862 amorarasu: Reverse merged 5.2.N (5.2.1) 135848 anechifor: REPO-1193 MNT-16734: Added a new release version alfresco-messaging-repo 1.2.8 Resolve security issue CVE-2014-3612 updating ActiveMQ 5.13.0. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137428 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 80 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 5664090954..0672021a46 100644 --- a/pom.xml +++ b/pom.xml @@ -13,11 +13,19 @@ /alfresco + UTF-8 ${tomcat.default.alfresco.port} ${tomcat.default.alfresco.ssl.port} + 5.1.1 + + ${project.groupId} + alfresco-trashcan-cleaner + ${dependency.alfresco-trashcan-cleaner.version} + + ${project.groupId} alfresco-remote-api @@ -86,16 +94,11 @@ standard 1.1.2 - - org.apache.chemistry.opencmis - chemistry-opencmis-test-browser - ${dependency.opencmis.version} - javax.servlet - servlet-api + javax.servlet-api provided @@ -113,14 +116,14 @@ org.alfresco.services alfresco-messaging-repo - 1.2.8 + 1.2.5 com.thetransactioncompany cors-filter - 1.9.3 + 2.5 @@ -158,7 +161,7 @@ org.apache.shale shale-test - 1.0.4 + 1.0.5 test @@ -226,7 +229,7 @@ maven-antrun-plugin - + fetch-jmxrmi-properties @@ -319,7 +322,15 @@ true ${runtime.tomcat.conf.folder}/solr-context.xml - + + org.alfresco + api-explorer + ${dependency.api-explorer.version} + /api-explorer + war + true + + @@ -339,8 +350,51 @@ mysql mysql-connector-java - + - + + withShare + + + org.alfresco + alfresco-share-services + ${runner.share.version} + amp + + + + + + maven-war-plugin + + + + org.alfresco + alfresco-share-services + amp + + + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + + + + org.alfresco + share + /share + ${runner.share.version} + war + true + + + + + + + + From 4618a8a05cbe785a45bbbe2dfff6e4ba6578b947 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 10:55:50 +0000 Subject: [PATCH 20/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 135863 anechifor: REPO-1193 MNT-16734: Added a new release version alfresco-messaging-repo 1.2.8 Resolve security issue CVE-2014-3612 updating ActiveMQ 5.13.0. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137429 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0672021a46..94fd3a8612 100644 --- a/pom.xml +++ b/pom.xml @@ -116,8 +116,8 @@ org.alfresco.services alfresco-messaging-repo - 1.2.5 - + 1.2.8 +
From ea3812d23986ca6785ff53db5b9b2cbbd17ae982 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 11:01:47 +0000 Subject: [PATCH 21/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 136190 gjames: Merged searchbcr (5.2.1) to 5.2.N (5.2.1) 135868 gjames: Adding a solr4 profile to toggle Alfresco Search Services on/off By default, solr4 is used. If you have ASS running independently then you can run it -DwithAss or turnoff solr4 profile using !solr4. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137479 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- pom.xml | 59 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 94fd3a8612..6f30453391 100644 --- a/pom.xml +++ b/pom.xml @@ -283,17 +283,12 @@
+ solr6 + 8983 ${dir.root} - solr4 localhost none - 8080 - 0 - 0 - ${runtime.solr.folder} - ${runtime.solr.folder}/alfrescoModels - ${runtime.solr.folder}/content false true @@ -312,16 +307,6 @@ ${project.build.directory}/tomcat/webapps/alfresco-server-root/META-INF/context.xml - - - org.alfresco - alfresco-solr4 - ${project.version} - /solr4 - war - true - ${runtime.tomcat.conf.folder}/solr-context.xml - org.alfresco api-explorer @@ -396,5 +381,45 @@ + + solr4 + + + withAss + !true + + + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + + + solr4 + 8080 + 0 + 0 + ${runtime.solr.folder} + ${runtime.solr.folder}/alfrescoModels + ${runtime.solr.folder}/content + + + + + org.alfresco + alfresco-solr4 + ${project.version} + /solr4 + war + true + ${runtime.tomcat.conf.folder}/solr-context.xml + + + + + + + From 20202564ba394c23f8c177a68ce0f7cc819adde9 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 11:06:35 +0000 Subject: [PATCH 22/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 136663 amukha: MNT-17850 Add configurable login page link to auth response page The new configuration property is giving an ability to configure a link to custom login page in Alfresco web app which is displayed on the page after failed auth: kerberos.authentication.sso.login.page.link git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137494 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../Authentication/kerberos/kerberos-filter-context.xml | 3 +++ .../Authentication/kerberos/kerberos-filter.properties | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter-context.xml b/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter-context.xml index 13f72d8c48..9ba2f4d0d5 100644 --- a/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter-context.xml +++ b/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter-context.xml @@ -147,6 +147,9 @@ + + ${kerberos.authentication.sso.login.page.link} + diff --git a/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter.properties b/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter.properties index 2653ffe37f..7fd57b6a92 100644 --- a/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter.properties +++ b/config/alfresco/subsystems/Authentication/kerberos/kerberos-filter.properties @@ -2,4 +2,5 @@ kerberos.authentication.http.configEntryName=AlfrescoHTTP kerberos.authentication.http.password=secret kerberos.authentication.sso.enabled=true kerberos.authentication.browser.ticketLogons=true -kerberos.authentication.sso.fallback.enabled=true \ No newline at end of file +kerberos.authentication.sso.fallback.enabled=true +kerberos.authentication.sso.login.page.link=/webdav \ No newline at end of file From ad1f01c12f437474424c842832c3306d92120484 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 11:08:14 +0000 Subject: [PATCH 23/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 136782 amukha: MNT-17850 Stop auto refresh of login link page git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137508 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/web/app/servlet/BaseServlet.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java index 8352b803a3..2139664dd5 100644 --- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java +++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository WAR Community - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Repository WAR Community + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.web.app.servlet; import java.io.IOException; @@ -304,7 +304,8 @@ public abstract class BaseServlet extends HttpServlet final PrintWriter out = res.getWriter(); out.println(""); - out.println(""); + // Remove the auto refresh to avoid refresh loop, MNT-16931 +// out.println(""); out.println("

Please log in.

"); out.println(""); out.close(); From 403c9469799b066d541870524a1133d2f760fd4c Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 11:23:32 +0000 Subject: [PATCH 24/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 137126 jvonka: CLD-79 - Minor update to Cloud Admin Node Browser to show "Source Associations" - TODO merge to 5.2.N-CLOUD44 & additional change on CLOUD44 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137637 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/bean/admin/AdminNodeBrowseBean.java | 86 +++++++++++++------ 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java b/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java index fc3f32b91e..f6218e72df 100644 --- a/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java +++ b/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository WAR Community - * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - * #L% - */ +/* + * #%L + * Alfresco Repository WAR Community + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ package org.alfresco.web.bean.admin; import java.io.Serializable; @@ -107,6 +107,7 @@ public class AdminNodeBrowseBean implements Serializable transient private DataModel properties = null; transient private DataModel children = null; transient private DataModel assocs = null; + transient private DataModel sourceAssocs = null; transient private DataModel permissions = null; transient private DataModel permissionMasks = null; @@ -454,6 +455,28 @@ public class AdminNodeBrowseBean implements Serializable return assocs; } + /** + * Gets the current source associations + * + * @return associations + */ + public DataModel getSourceAssocs() + { + if (sourceAssocs == null) + { + try + { + List assocRefs = getNodeService().getSourceAssocs(getNodeRef(), RegexQNamePattern.MATCH_ALL); + sourceAssocs = new ListDataModel(assocRefs); + } + catch (UnsupportedOperationException err) + { + // some stores do not support associations + } + } + return sourceAssocs; + } + /** * Gets the current query language * @@ -588,6 +611,19 @@ public class AdminNodeBrowseBean implements Serializable return "success"; } + /** + * Action to select association From node + * + * @return next action + */ + public String selectFromNode() + { + AssociationRef assocRef = (AssociationRef) getSourceAssocs().getRowData(); + NodeRef sourceRef = assocRef.getSourceRef(); + setNodeRef(sourceRef); + return "success"; + } + /** * Action to select node property * From f82e7c721125c9f1951580adad526657b4897d16 Mon Sep 17 00:00:00 2001 From: Andrei Rebegea Date: Thu, 15 Jun 2017 11:23:52 +0000 Subject: [PATCH 25/25] Merged 5.2.N (5.2.2) to HEAD (5.2) 137132 jvonka: CLD-79 - Minor update to Cloud Admin Node Browser to show "Source Associations" - follow-on to clear "sourceAssocs" when setting new nodeRef git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137640 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java | 1 + 1 file changed, 1 insertion(+) diff --git a/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java b/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java index f6218e72df..0d93f9ea2d 100644 --- a/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java +++ b/source/java/org/alfresco/web/bean/admin/AdminNodeBrowseBean.java @@ -267,6 +267,7 @@ public class AdminNodeBrowseBean implements Serializable properties = null; children = null; assocs = null; + sourceAssocs = null; inheritPermissions = null; permissions = null; permissionMasks = null;