ATS-488 : Remove alfresco-core dependency (#90)

- remove *alfresco-core* dependency
- remove *alfresco-data-model* dependency
- replace _TempFileProvider_ with local implementation
- duplicate _RuntimeExec_ and _ExecParameterTokenizer_ from alfresco-core
- partially duplicate _MimetypeMap_ from alfresco-data-model
This commit is contained in:
CezarLeahu 2019-08-20 10:05:39 +03:00 committed by GitHub
parent 1f47cd47b4
commit bb187dc00f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1597 additions and 329 deletions

View File

@ -46,24 +46,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,34 +0,0 @@
# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
#-------------------------------------------------------------------------------
# Already used licenses in project :
# - Apache 2
# - Apache 2.0
# - Apache License 2.0
# - Apache License, Version 2.0
# - Apache License, version 2.0
# - BSD 3-clause New License
# - CDDL + GPLv2 with classpath exception
# - CDDL 1.1
# - CDDL+GPL License
# - CDDL/GPLv2+CE
# - Eclipse Distribution License - v 1.0
# - Eclipse Public License - v 1.0
# - GNU Lesser General Public License
# - GNU Lesser General Public License v2.1
# - GPL2 w/ CPE
# - MIT License
# - MIT license
# - Public Domain, per Creative Commons CC0
# - Sun Binary Code License Agreement
# - The Apache License, Version 2.0
# - The Apache Software License, Version 2.0
# - The JSON License
# - The MIT License
#-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies :
#
#
#Tue Jul 09 13:35:12 EEST 2019
javax.transaction--jta--1.1=Sun Binary Code License Agreement
commons-httpclient--commons-httpclient--3.1-HTTPCLIENT-1265=Apache License 2.0
org.codehaus.guessencoding--guessencoding--1.4=Apache License 2.0

View File

@ -29,7 +29,6 @@ package org.alfresco.transformer.executors;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.util.exec.RuntimeExec;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**

View File

@ -26,6 +26,7 @@
*/ */
package org.alfresco.transformer; package org.alfresco.transformer;
import static org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -58,10 +59,9 @@ import java.util.UUID;
import org.alfresco.transform.client.model.TransformReply; import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.executors.PdfRendererCommandExecutor; import org.alfresco.transformer.executors.PdfRendererCommandExecutor;
import org.alfresco.transformer.executors.RuntimeExec;
import org.alfresco.transformer.model.FileRefEntity; import org.alfresco.transformer.model.FileRefEntity;
import org.alfresco.transformer.model.FileRefResponse; import org.alfresco.transformer.model.FileRefResponse;
import org.alfresco.util.exec.RuntimeExec;
import org.alfresco.util.exec.RuntimeExec.ExecutionResult;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

View File

@ -46,24 +46,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,34 +0,0 @@
# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
#-------------------------------------------------------------------------------
# Already used licenses in project :
# - Apache 2
# - Apache 2.0
# - Apache License 2.0
# - Apache License, Version 2.0
# - Apache License, version 2.0
# - BSD 3-clause New License
# - CDDL + GPLv2 with classpath exception
# - CDDL 1.1
# - CDDL+GPL License
# - CDDL/GPLv2+CE
# - Eclipse Distribution License - v 1.0
# - Eclipse Public License - v 1.0
# - GNU Lesser General Public License
# - GNU Lesser General Public License v2.1
# - GPL2 w/ CPE
# - MIT License
# - MIT license
# - Public Domain, per Creative Commons CC0
# - Sun Binary Code License Agreement
# - The Apache License, Version 2.0
# - The Apache Software License, Version 2.0
# - The JSON License
# - The MIT License
#-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies :
#
#
#Tue Jul 09 13:35:40 EEST 2019
javax.transaction--jta--1.1=Sun Binary Code License Agreement
commons-httpclient--commons-httpclient--3.1-HTTPCLIENT-1265=Apache License 2.0
org.codehaus.guessencoding--guessencoding--1.4=Apache License 2.0

View File

@ -29,7 +29,6 @@ package org.alfresco.transformer.executors;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.util.exec.RuntimeExec;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**

View File

@ -26,6 +26,7 @@
*/ */
package org.alfresco.transformer; package org.alfresco.transformer;
import static org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -57,9 +58,9 @@ import java.util.UUID;
import org.alfresco.transform.client.model.TransformReply; import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.executors.ImageMagickCommandExecutor; import org.alfresco.transformer.executors.ImageMagickCommandExecutor;
import org.alfresco.transformer.executors.RuntimeExec;
import org.alfresco.transformer.model.FileRefEntity; import org.alfresco.transformer.model.FileRefEntity;
import org.alfresco.transformer.model.FileRefResponse; import org.alfresco.transformer.model.FileRefResponse;
import org.alfresco.util.exec.RuntimeExec;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -85,7 +86,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
public class ImageMagickControllerTest extends AbstractTransformerControllerTest public class ImageMagickControllerTest extends AbstractTransformerControllerTest
{ {
@Mock @Mock
private RuntimeExec.ExecutionResult mockExecutionResult; private ExecutionResult mockExecutionResult;
@Mock @Mock
private RuntimeExec mockTransformCommand; private RuntimeExec mockTransformCommand;

View File

@ -46,24 +46,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,34 +0,0 @@
# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
#-------------------------------------------------------------------------------
# Already used licenses in project :
# - Apache 2
# - Apache 2.0
# - Apache License 2.0
# - Apache License, Version 2.0
# - Apache License, version 2.0
# - BSD 3-clause New License
# - CDDL + GPLv2 with classpath exception
# - CDDL 1.1
# - CDDL+GPL License
# - CDDL/GPLv2+CE
# - Eclipse Distribution License - v 1.0
# - Eclipse Public License - v 1.0
# - GNU Lesser General Public License
# - GNU Lesser General Public License v2.1
# - GPL2 w/ CPE
# - MIT License
# - MIT license
# - Public Domain, per Creative Commons CC0
# - Sun Binary Code License Agreement
# - The Apache License, Version 2.0
# - The Apache Software License, Version 2.0
# - The JSON License
# - The MIT License
#-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies :
#
#
#Tue Jul 09 13:36:53 EEST 2019
javax.transaction--jta--1.1=Sun Binary Code License Agreement
commons-httpclient--commons-httpclient--3.1-HTTPCLIENT-1265=Apache License 2.0
org.codehaus.guessencoding--guessencoding--1.4=Apache License 2.0

View File

@ -37,7 +37,6 @@ import java.util.StringTokenizer;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import org.alfresco.error.AlfrescoRuntimeException;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration; import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeException; import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeManager; import org.artofsolving.jodconverter.office.OfficeManager;
@ -163,7 +162,7 @@ public class JodConverterSharedInstance implements JodConverter
File tmp = new File(templateProfileDir); File tmp = new File(templateProfileDir);
if (!tmp.isDirectory()) if (!tmp.isDirectory())
{ {
throw new AlfrescoRuntimeException( throw new RuntimeException(
"OpenOffice template profile directory " + templateProfileDir + " does not exist."); "OpenOffice template profile directory " + templateProfileDir + " does not exist.");
} }
this.templateProfileDir = tmp; this.templateProfileDir = tmp;

View File

@ -26,6 +26,7 @@
*/ */
package org.alfresco.transformer; package org.alfresco.transformer;
import static org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -56,7 +57,6 @@ import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.executors.LibreOfficeJavaExecutor; import org.alfresco.transformer.executors.LibreOfficeJavaExecutor;
import org.alfresco.transformer.model.FileRefEntity; import org.alfresco.transformer.model.FileRefEntity;
import org.alfresco.transformer.model.FileRefResponse; import org.alfresco.transformer.model.FileRefResponse;
import org.alfresco.util.exec.RuntimeExec;
import org.artofsolving.jodconverter.office.OfficeException; import org.artofsolving.jodconverter.office.OfficeException;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -81,7 +81,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
public class LibreOfficeControllerTest extends AbstractTransformerControllerTest public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
{ {
@Mock @Mock
private RuntimeExec.ExecutionResult mockExecutionResult; private ExecutionResult mockExecutionResult;
@SpyBean @SpyBean
private LibreOfficeJavaExecutor javaExecutor; private LibreOfficeJavaExecutor javaExecutor;

View File

@ -47,29 +47,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-data-model</artifactId>
</dependency> </dependency>
<!-- Tika --> <!-- Tika -->

View File

@ -2,8 +2,6 @@
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Already used licenses in project : # Already used licenses in project :
# - (MIT-style) netCDF C library license # - (MIT-style) netCDF C library license
# - Apache 1.1
# - Apache 2
# - Apache 2.0 # - Apache 2.0
# - Apache License 2.0 # - Apache License 2.0
# - Apache License v2.0 # - Apache License v2.0
@ -13,21 +11,14 @@
# - BSD # - BSD
# - BSD 3-clause New License # - BSD 3-clause New License
# - BSD License # - BSD License
# - BSD licence
# - Bouncy Castle Licence # - Bouncy Castle Licence
# - CDDL + GPLv2 with classpath exception # - CDDL + GPLv2 with classpath exception
# - CDDL 1.1
# - CDDL+GPL License
# - CDDL, v1.0 # - CDDL, v1.0
# - CDDL/GPLv2+CE
# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
# - CPL
# - EPL 2.0 # - EPL 2.0
# - Eclipse Distribution License - v 1.0
# - Eclipse Public License - v 1.0 # - Eclipse Public License - v 1.0
# - GNU General Public Library # - Eclipse Public License, Version 1.0
# - GNU Lesser General Public License # - GNU Lesser General Public License
# - GNU Lesser General Public License v2.1 # - GNU Lesser General Public License, Version 2.1
# - GPL2 w/ CPE # - GPL2 w/ CPE
# - LGPL, v2.1 or later # - LGPL, v2.1 or later
# - LGPL, version 2.1 # - LGPL, version 2.1
@ -42,24 +33,14 @@
# - Public Domain, per Creative Commons CC0 # - Public Domain, per Creative Commons CC0
# - Similar to Apache License but with the acknowledgment clause removed # - Similar to Apache License but with the acknowledgment clause removed
# - Specification License # - Specification License
# - Sun Binary Code License Agreement
# - The Apache License, Version 2.0 # - The Apache License, Version 2.0
# - The Apache Software License, Version 2.0 # - The Apache Software License, Version 2.0
# - The BSD License # - The BSD License
# - The JSON License
# - The MIT License # - The MIT License
# - The SAX License
# - The W3C License
# - UnRar License # - UnRar License
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies : # Please fill the missing licenses for dependencies :
# #
# #
#Tue Jul 09 13:34:27 EEST 2019 #Mon Aug 19 18:06:38 EEST 2019
org.acegisecurity--acegi-security--0.8.2_patched=Apache License 2.0
net.jcip--jcip-annotations--1.0=Public net.jcip--jcip-annotations--1.0=Public
xerces--xercesImpl--2.11.0-alfresco-patched-20180402=Apache License 2.0
javax.transaction--jta--1.1=Sun Binary Code License Agreement
commons-httpclient--commons-httpclient--3.1-HTTPCLIENT-1265=Apache License 2.0
xpp3--xpp3--1.1.3_8=Apache 1.1
org.codehaus.guessencoding--guessencoding--1.4=Apache License 2.0

View File

@ -26,7 +26,6 @@
*/ */
package org.alfresco.transformer; package org.alfresco.transformer;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.transformer.executors.Tika.INCLUDE_CONTENTS; import static org.alfresco.transformer.executors.Tika.INCLUDE_CONTENTS;
import static org.alfresco.transformer.executors.Tika.NOT_EXTRACT_BOOKMARKS_TEXT; import static org.alfresco.transformer.executors.Tika.NOT_EXTRACT_BOOKMARKS_TEXT;
import static org.alfresco.transformer.executors.Tika.PDF_BOX; import static org.alfresco.transformer.executors.Tika.PDF_BOX;
@ -37,6 +36,7 @@ import static org.alfresco.transformer.fs.FileManager.createAttachment;
import static org.alfresco.transformer.fs.FileManager.createSourceFile; import static org.alfresco.transformer.fs.FileManager.createSourceFile;
import static org.alfresco.transformer.fs.FileManager.createTargetFile; import static org.alfresco.transformer.fs.FileManager.createTargetFile;
import static org.alfresco.transformer.fs.FileManager.createTargetFileName; import static org.alfresco.transformer.fs.FileManager.createTargetFileName;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.transformer.util.Util.stringToBoolean; import static org.alfresco.transformer.util.Util.stringToBoolean;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.OK;

View File

@ -26,14 +26,14 @@
*/ */
package org.alfresco.transformer.executors; package org.alfresco.transformer.executors;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_HTML; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_HTML;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_IMAGE_JPEG; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_IMAGE_JPEG;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_IMAGE_PNG; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_IMAGE_PNG;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_IMAGE_TIFF; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_IMAGE_TIFF;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_TEXT_CSV; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_TEXT_CSV;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_TEXT_PLAIN; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_XHTML; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_XHTML;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_XML; import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_XML;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedWriter; import java.io.BufferedWriter;

View File

@ -26,18 +26,6 @@
*/ */
package org.alfresco.transformer; package org.alfresco.transformer;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_HTML;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_OPENXML_PRESENTATION;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_OPENXML_SPREADSHEET;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_OPENXML_WORDPROCESSING;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_OUTLOOK_MSG;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_PDF;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_TEXT_CSV;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_WORD;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_XHTML;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_XML;
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_ZIP;
import static org.alfresco.transformer.executors.Tika.ARCHIVE; import static org.alfresco.transformer.executors.Tika.ARCHIVE;
import static org.alfresco.transformer.executors.Tika.CSV; import static org.alfresco.transformer.executors.Tika.CSV;
import static org.alfresco.transformer.executors.Tika.DOC; import static org.alfresco.transformer.executors.Tika.DOC;
@ -58,6 +46,18 @@ import static org.alfresco.transformer.executors.Tika.XHTML;
import static org.alfresco.transformer.executors.Tika.XML; import static org.alfresco.transformer.executors.Tika.XML;
import static org.alfresco.transformer.executors.Tika.XSLX; import static org.alfresco.transformer.executors.Tika.XSLX;
import static org.alfresco.transformer.executors.Tika.ZIP; import static org.alfresco.transformer.executors.Tika.ZIP;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_HTML;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_OPENXML_PRESENTATION;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_OPENXML_SPREADSHEET;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_OPENXML_WORDPROCESSING;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_OUTLOOK_MSG;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_PDF;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_TEXT_CSV;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_WORD;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_XHTML;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_XML;
import static org.alfresco.transformer.util.MimetypeMap.MIMETYPE_ZIP;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -87,10 +87,10 @@ import java.util.UUID;
import org.alfresco.transform.client.model.TransformReply; import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.executors.RuntimeExec;
import org.alfresco.transformer.executors.TikaJavaExecutor; import org.alfresco.transformer.executors.TikaJavaExecutor;
import org.alfresco.transformer.model.FileRefEntity; import org.alfresco.transformer.model.FileRefEntity;
import org.alfresco.transformer.model.FileRefResponse; import org.alfresco.transformer.model.FileRefResponse;
import org.alfresco.util.exec.RuntimeExec;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

View File

@ -48,24 +48,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency> </dependency>
<!-- HtmlParserContentTransformer --> <!-- HtmlParserContentTransformer -->

View File

@ -1,36 +0,0 @@
# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
#-------------------------------------------------------------------------------
# Already used licenses in project :
# - Apache 2
# - Apache 2.0
# - Apache License 2.0
# - Apache License, Version 2.0
# - Apache License, version 2.0
# - BSD 3-clause New License
# - BSD License
# - CDDL + GPLv2 with classpath exception
# - CDDL 1.1
# - CDDL+GPL License
# - CDDL/GPLv2+CE
# - Common Public License
# - Eclipse Distribution License - v 1.0
# - Eclipse Public License - v 1.0
# - GNU Lesser General Public License
# - GNU Lesser General Public License v2.1
# - GPL2 w/ CPE
# - MIT License
# - MIT license
# - Public Domain, per Creative Commons CC0
# - Sun Binary Code License Agreement
# - The Apache License, Version 2.0
# - The Apache Software License, Version 2.0
# - The JSON License
# - The MIT License
#-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies :
#
#
#Tue Jul 09 13:38:31 EEST 2019
javax.transaction--jta--1.1=Sun Binary Code License Agreement
commons-httpclient--commons-httpclient--3.1-HTTPCLIENT-1265=Apache License 2.0
org.codehaus.guessencoding--guessencoding--1.4=Apache License 2.0

View File

@ -40,7 +40,6 @@ import java.nio.file.StandardCopyOption;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -113,13 +112,13 @@ public class AppleIWorksContentTransformer implements SelectableTransformer
if (!found) if (!found)
{ {
throw new AlfrescoRuntimeException( throw new RuntimeException(
"The source " + sourceMimetype + " file did not contain a " + targetMimetype + " preview"); "The source " + sourceMimetype + " file did not contain a " + targetMimetype + " preview");
} }
} }
catch (IOException e) catch (IOException e)
{ {
throw new AlfrescoRuntimeException( throw new RuntimeException(
"Unable to transform " + sourceMimetype + " file. It should have been a zip format file.", "Unable to transform " + sourceMimetype + " file. It should have been a zip format file.",
e); e);
} }

View File

@ -55,7 +55,6 @@ import java.nio.file.StandardCopyOption;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
@ -148,7 +147,7 @@ public class OOXMLThumbnailContentTransformer implements SelectableTransformer
} }
catch (IOException e) catch (IOException e)
{ {
throw new AlfrescoRuntimeException("Unable to transform file.", e); throw new RuntimeException("Unable to transform file.", e);
} }
} }

View File

@ -34,7 +34,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.transform.exceptions.TransformException; import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.transformer.logging.LogEntry; import org.alfresco.transformer.logging.LogEntry;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -117,7 +116,7 @@ public class SelectingTransformer
return transformer; return transformer;
} }
} }
throw new AlfrescoRuntimeException( throw new RuntimeException(
"Could not select a transformer for sourceMimetype=" + sourceMimetype "Could not select a transformer for sourceMimetype=" + sourceMimetype
+ " targetMimetype=" + targetMimetype); + " targetMimetype=" + targetMimetype);
} }

View File

@ -46,7 +46,6 @@ import java.nio.charset.Charset;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -86,7 +85,7 @@ public class TextToPdfContentTransformer implements SelectableTransformer
} }
catch (Throwable e) catch (Throwable e)
{ {
throw new AlfrescoRuntimeException( throw new RuntimeException(
"Unable to set Standard Font for PDF generation: " + fontName, e); "Unable to set Standard Font for PDF generation: " + fontName, e);
} }
} }
@ -99,7 +98,7 @@ public class TextToPdfContentTransformer implements SelectableTransformer
} }
catch (Throwable e) catch (Throwable e)
{ {
throw new AlfrescoRuntimeException( throw new RuntimeException(
"Unable to set Font Size for PDF generation: " + fontSize); "Unable to set Font Size for PDF generation: " + fontSize);
} }
} }

View File

@ -45,7 +45,6 @@ import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.transformers.SelectingTransformer; import org.alfresco.transformer.transformers.SelectingTransformer;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
@ -165,7 +164,7 @@ public class MiscControllerTest extends AbstractTransformerControllerTest
} }
catch (UnsupportedEncodingException e) catch (UnsupportedEncodingException e)
{ {
throw new AlfrescoRuntimeException("Encoding not recognised", e); throw new RuntimeException("Encoding not recognised", e);
} }
MvcResult result = sendText("txt", MvcResult result = sendText("txt",

View File

@ -40,24 +40,9 @@
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -27,6 +27,7 @@
package org.alfresco.transformer; package org.alfresco.transformer;
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;
import static org.alfresco.transformer.fs.FileManager.TempFileProvider.createTempFile;
import static org.alfresco.transformer.fs.FileManager.buildFile; import static org.alfresco.transformer.fs.FileManager.buildFile;
import static org.alfresco.transformer.fs.FileManager.createTargetFileName; import static org.alfresco.transformer.fs.FileManager.createTargetFileName;
import static org.alfresco.transformer.fs.FileManager.deleteFile; import static org.alfresco.transformer.fs.FileManager.deleteFile;
@ -51,7 +52,6 @@ import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.transformer.clients.AlfrescoSharedFileStoreClient; import org.alfresco.transformer.clients.AlfrescoSharedFileStoreClient;
import org.alfresco.transformer.logging.LogEntry; import org.alfresco.transformer.logging.LogEntry;
import org.alfresco.transformer.model.FileRefResponse; import org.alfresco.transformer.model.FileRefResponse;
import org.alfresco.util.TempFileProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -324,7 +324,7 @@ public abstract class AbstractTransformerController implements TransformControll
logger.warn(message); logger.warn(message);
throw new TransformException(BAD_REQUEST.value(), message); throw new TransformException(BAD_REQUEST.value(), message);
} }
File file = TempFileProvider.createTempFile("source_", "." + extension); final File file = createTempFile("source_", "." + extension);
logger.debug("Read source content {} length={} contentType={}", logger.debug("Read source content {} length={} contentType={}",
sourceReference, size, contentType); sourceReference, size, contentType);

View File

@ -26,6 +26,7 @@
*/ */
package org.alfresco.transformer.executors; package org.alfresco.transformer.executors;
import static org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
@ -33,8 +34,6 @@ import java.io.File;
import java.util.Map; import java.util.Map;
import org.alfresco.transform.exceptions.TransformException; import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.util.exec.RuntimeExec;
import org.alfresco.util.exec.RuntimeExec.ExecutionResult;
/** /**
* *

View File

@ -0,0 +1,360 @@
/*
* #%L
* Alfresco Transform Core
* %%
* Copyright (C) 2005 - 2019 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.transformer.executors;
import static java.util.Collections.singletonList;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.StringTokenizer;
/**
* DUPLICATED FROM *alfresco-core*.
*
* This class is used to tokenize strings used as parameters for {@link RuntimeExec} objects.
* Examples of such strings are as follows (ImageMagick-like parameters):
* <ul>
* <li><tt>-font Helvetica -pointsize 50</tt></li>
* <li><tt>-font Helvetica -pointsize 50 -draw "circle 100,100 150,150"</tt></li>
* <li><tt>-font Helvetica -pointsize 50 -draw "gravity south fill black text 0,12 'CopyRight'"</tt></li>
* </ul>
* The first is the simple case which would be parsed into Strings as follows:
* <tt>"-font", "Helvetica", "-pointsize", "50"</tt>
* <p/>
* The second is more complex in that it includes a quoted parameter, which would be parsed as a single String:
* <tt>"-font", "Helvetica", "-pointsize", "50", "circle 100,100 150,150"</tt>
* Note however that the quotation characters will be stripped from the token.
* <p/>
* The third shows an example with embedded quotation marks, which would parse to:
* <tt>"-font", "Helvetica", "-pointsize", "50", "gravity south fill black text 0,12 'CopyRight'"</tt>
* In this case, the embedded quotation marks (which must be different from those surrounding the parameter)
* are preserved in the extracted token.
* <p/>
* The class does not understand escaped quotes such as <tt>p1 p2 "a b c \"hello\" d" p4</tt>
*
* @author Neil Mc Erlean
* @since 3.4.2
*/
public class ExecParameterTokenizer
{
/**
* The string to be tokenized.
*/
private final String str;
/**
* The list of tokens, which will take account of quoted sections.
*/
private List<String> tokens;
public ExecParameterTokenizer(String str)
{
this.str = str;
}
/**
* This method returns the tokens in a parameter string.
* Any tokens not contained within single or double quotes will be tokenized in the normal
* way i.e. by using whitespace separators and the standard StringTokenizer algorithm.
* Any tokens which are contained within single or double quotes will be returned as single
* String instances and will have their quote marks removed.
* <p/>
* See above for examples.
*
* @throws NullPointerException if the string to be tokenized was null.
*/
public List<String> getAllTokens()
{
if (this.str == null)
{
throw new NullPointerException("Illegal null string cannot be tokenized.");
}
if (tokens == null)
{
tokens = new ArrayList<>();
// Preserve original behaviour from RuntimeExec.
if (str.indexOf('\'') == -1 && str.indexOf('"') == -1)
{
// Contains no quotes.
for (StringTokenizer standardTokenizer = new StringTokenizer(
str); standardTokenizer.hasMoreTokens(); )
{
tokens.add(standardTokenizer.nextToken());
}
}
else
{
// There are either single or double quotes or both.
// So we need to identify the quoted regions within the string.
List<Pair<Integer, Integer>> quotedRegions = new ArrayList<>();
for (Pair<Integer, Integer> next = identifyNextQuotedRegion(str, 0); next != null; )
{
quotedRegions.add(next);
next = identifyNextQuotedRegion(str, next.getSecond() + 1);
}
// Now we've got a List of index pairs identifying the quoted regions.
// We need to get substrings of quoted and unquoted blocks, whilst maintaining order.
List<Substring> substrings = getSubstrings(str, quotedRegions);
for (Substring r : substrings)
{
tokens.addAll(r.getTokens());
}
}
}
return this.tokens;
}
/**
* The substrings will be a list of quoted and unquoted substrings.
* The unquoted ones need to be further tokenized in the normal way.
* The quoted ones must not be tokenized, but need their quotes stripped off.
*/
private List<Substring> getSubstrings(String str,
List<Pair<Integer, Integer>> quotedRegionIndices)
{
List<Substring> result = new ArrayList<>();
int cursorPosition = 0;
for (Pair<Integer, Integer> nextQuotedRegionIndices : quotedRegionIndices)
{
if (cursorPosition < nextQuotedRegionIndices.getFirst())
{
int startIndexOfNextQuotedRegion = nextQuotedRegionIndices.getFirst() - 1;
result.add(new UnquotedSubstring(
str.substring(cursorPosition, startIndexOfNextQuotedRegion)));
}
result.add(new QuotedSubstring(str.substring(nextQuotedRegionIndices.getFirst(),
nextQuotedRegionIndices.getSecond())));
cursorPosition = nextQuotedRegionIndices.getSecond();
}
// We've processed all the quoted regions, but there may be a final unquoted region
if (cursorPosition < str.length() - 1)
{
result.add(new UnquotedSubstring(str.substring(cursorPosition, str.length() - 1)));
}
return result;
}
private Pair<Integer, Integer> identifyNextQuotedRegion(String str, int startingIndex)
{
int indexOfNextSingleQuote = str.indexOf('\'', startingIndex);
int indexOfNextDoubleQuote = str.indexOf('"', startingIndex);
if (indexOfNextSingleQuote == -1 && indexOfNextDoubleQuote == -1)
{
// If there are no more quoted regions
return null;
}
else if (indexOfNextSingleQuote > -1 && indexOfNextDoubleQuote > -1)
{
// If there are both single and double quotes in the remainder of the string
// Then select the closest quote.
int indexOfNextQuote = Math.min(indexOfNextSingleQuote, indexOfNextDoubleQuote);
char quoteChar = str.charAt(indexOfNextQuote);
return findIndexOfClosingQuote(str, indexOfNextQuote, quoteChar);
}
else
{
// Only one of the quote characters is present.
int indexOfNextQuote = Math.max(indexOfNextSingleQuote, indexOfNextDoubleQuote);
char quoteChar = str.charAt(indexOfNextQuote);
return findIndexOfClosingQuote(str, indexOfNextQuote, quoteChar);
}
}
private Pair<Integer, Integer> findIndexOfClosingQuote(String str, int indexOfStartingQuote,
char quoteChar)
{
// So we know which type of quote char we're dealing with. Either ' or ".
// Now we need to find the closing quote.
int indexAfterClosingQuote = str.indexOf(quoteChar,
indexOfStartingQuote + 1) + 1; // + 1 to search after opening quote. + 1 to give result including closing quote.
if (indexAfterClosingQuote == 0) // -1 + 1
{
// If no closing quote.
throw new IllegalArgumentException("No closing " + quoteChar + "quote in" + str);
}
return new Pair<>(indexOfStartingQuote, indexAfterClosingQuote);
}
/**
* Utility interface for a substring in a parameter string.
*/
public interface Substring
{
/**
* Gets all the tokens in a parameter string.
*/
List<String> getTokens();
}
/**
* A substring that is not surrounded by (single or double) quotes.
*/
public class UnquotedSubstring implements Substring
{
private final String regionString;
public UnquotedSubstring(String str)
{
this.regionString = str;
}
public List<String> getTokens()
{
StringTokenizer t = new StringTokenizer(regionString);
List<String> result = new ArrayList<>();
while (t.hasMoreTokens())
{
result.add(t.nextToken());
}
return result;
}
public String toString()
{
return UnquotedSubstring.class.getSimpleName() + ": '" + regionString + '\'';
}
}
/**
* A substring that is surrounded by (single or double) quotes.
*/
public class QuotedSubstring implements Substring
{
private final String regionString;
public QuotedSubstring(String str)
{
this.regionString = str;
}
public List<String> getTokens()
{
String stringWithoutQuotes = regionString.substring(1, regionString.length() - 1);
return singletonList(stringWithoutQuotes);
}
public String toString()
{
return QuotedSubstring.class.getSimpleName() + ": '" + regionString + '\'';
}
}
public static final class Pair<F, S> implements Serializable
{
private static final long serialVersionUID = -7406248421185630612L;
/**
* The first member of the pair.
*/
private F first;
/**
* The second member of the pair.
*/
private S second;
/**
* Make a new one.
*
* @param first The first member.
* @param second The second member.
*/
public Pair(F first, S second)
{
this.first = first;
this.second = second;
}
/**
* Get the first member of the tuple.
*
* @return The first member.
*/
public final F getFirst()
{
return first;
}
/**
* Get the second member of the tuple.
*
* @return The second member.
*/
public final S getSecond()
{
return second;
}
public final void setFirst(F first)
{
this.first = first;
}
public final void setSecond(S second)
{
this.second = second;
}
@Override public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
return Objects.equals(first, pair.first) &&
Objects.equals(second, pair.second);
}
@Override public int hashCode()
{
return Objects.hash(first, second);
}
@Override
public String toString()
{
return "(" + first + ", " + second + ")";
}
}
}

View File

@ -0,0 +1,986 @@
/*
* #%L
* Alfresco Transform Core
* %%
* Copyright (C) 2005 - 2019 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.transformer.executors;
import static java.util.Collections.emptyMap;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* DUPLICATED FROM *alfresco-core*.
*
* This acts as a session similar to the <code>java.lang.Process</code>, but
* logs the system standard and error streams.
* <p>
* The bean can be configured to execute a command directly, or be given a map
* of commands keyed by the <i>os.name</i> Java system property. In this map,
* the default key that is used when no match is found is the
* <b>{@link #KEY_OS_DEFAULT *}</b> key.
* <p>
* Use the {@link #setProcessDirectory(String) processDirectory} property to change the default location
* from which the command executes. The process's environment can be configured using the
* {@link #setProcessProperties(Map) processProperties} property.
* <p>
* Commands may use placeholders, e.g.
* <pre><code>
* find
* -name
* ${filename}
* </code></pre>
* The <b>filename</b> property will be substituted for any supplied value prior to
* each execution of the command. Currently, no checks are made to get or check the
* properties contained within the command string. It is up to the client code to
* dynamically extract the properties required if the required properties are not
* known up front.
* <p>
* Sometimes, a variable may contain several arguments. . In this case, the arguments
* need to be tokenized using a standard <tt>StringTokenizer</tt>. To force tokenization
* of a value, use:
* <pre><code>
* SPLIT:${userArgs}
* </code></pre>
* You should not use this just to split up arguments that are known to require tokenization
* up front. The <b>SPLIT:</b> directive works for the entire argument and will not do anything
* if it is not at the beginning of the argument. Do not use <b>SPLIT:</b> to break up arguments
* that are fixed, so avoid doing this:
* <pre><code>
* SPLIT:ls -lih
* </code></pre>
* Instead, break the command up explicitly:
* <pre><code>
* ls
* -lih
* </code></pre>
*
* Tokenization of quoted parameter values is handled by ExecParameterTokenizer, which
* describes the support in more detail.
*
* @author Derek Hulley
*/
public class RuntimeExec
{
private static final Logger logger = LoggerFactory.getLogger(RuntimeExec.class);
/**
* the key to use when specifying a command for any other OS: <b>*</b>
*/
private static final String KEY_OS_DEFAULT = "*";
private static final String KEY_OS_NAME = "os.name";
private static final int BUFFER_SIZE = 1024;
private static final String VAR_OPEN = "${";
private static final String VAR_CLOSE = "}";
private static final String DIRECTIVE_SPLIT = "SPLIT:";
private String[] command;
private Charset charset = Charset.defaultCharset();
private boolean waitForCompletion = true;
private Map<String, String> defaultProperties = emptyMap();
private String[] processProperties;
private File processDirectory;
private final Set<Integer> errCodes;
private final Timer timer = new Timer(true);
/**
* Default constructor. Initialize this instance by setting individual properties.
*/
public RuntimeExec()
{
// set default error codes
errCodes = new HashSet<>(2);
errCodes.add(1);
errCodes.add(2);
}
public String toString()
{
final StringBuilder sb = new StringBuilder(256);
sb.append("RuntimeExec:\n").append(" command: ");
if (command == null)
{
// command is 'null', so there's nothing to toString
sb.append("'null'\n");
}
else
{
for (String cmdStr : command)
{
sb.append(cmdStr).append(" ");
}
sb.append("\n");
}
sb.append(" env props: ").append(Arrays.toString(processProperties)).append("\n")
.append(" dir: ").append(processDirectory).append("\n")
.append(" os: ").append(System.getProperty(KEY_OS_NAME)).append("\n");
return sb.toString();
}
/**
* Set the command to execute regardless of operating system
*
* @param command an array of strings representing the command (first entry) and arguments
* @since 3.0
*/
public void setCommand(String[] command)
{
this.command = command;
}
/**
* Sets the assumed charset of OUT and ERR streams generated by the executed command.
* This defaults to the system default charset: {@link Charset#defaultCharset()}.
*
* @param charsetCode a supported character set code
* @throws UnsupportedCharsetException if the characterset code is not recognised by Java
*/
public void setCharset(String charsetCode)
{
this.charset = Charset.forName(charsetCode);
}
/**
* Set whether to wait for completion of the command or not. If there is no wait for completion,
* then the return value of <i>out</i> and <i>err</i> buffers cannot be relied upon as the
* command may still be in progress. Failure is therefore not possible unless the calling thread
* waits for execution.
*
* @param waitForCompletion <tt>true</tt> (default) is to wait for the command to exit,
* or <tt>false</tt> to just return an exit code of 0 and whatever
* output is available at that point.
* @since 2.1
*/
public void setWaitForCompletion(boolean waitForCompletion)
{
this.waitForCompletion = waitForCompletion;
}
/**
* Supply a choice of commands to execute based on a mapping from the <i>os.name</i> system
* property to the command to execute. The {@link #KEY_OS_DEFAULT *} key can be used
* to get a command where there is not direct match to the operating system key.
* <p>
* Each command is an array of strings, the first of which represents the command and all subsequent
* entries in the array represent the arguments. All elements of the array will be checked for
* the presence of any substitution parameters (e.g. '{dir}'). The parameters can be set using the
* {@link #setDefaultProperties(Map) defaults} or by passing the substitution values into the
* {@link #execute(Map)} command.
* <p>
* If parameters passed may be multiple arguments, or if the values provided in the map are themselves
* collections of arguments (not recommended), then prefix the value with <b>SPLIT:</b> to ensure that
* the value is tokenized before being passed to the command. Any values that are not split, will be
* passed to the command as single arguments. For example:<br>
* '<b>SPLIT: dir . ..</b>' becomes '<b>dir</b>', '<b>.</b>' and '<b>..</b>'.<br>
* '<b>SPLIT: dir ${path}</b>' (if path is '<b>. ..</b>') becomes '<b>dir</b>', '<b>.</b>' and '<b>..</b>'.<br>
* The splitting occurs post-subtitution. Where the arguments are known, it is advisable to avoid
* <b>SPLIT:</b>.
*
* @param commandsByOS a map of command string arrays, keyed by operating system names
* @see #setDefaultProperties(Map)
* @since 3.0
*/
public void setCommandsAndArguments(Map<String, String[]> commandsByOS)
{
// get the current OS
String serverOs = System.getProperty(KEY_OS_NAME);
// attempt to find a match
String[] command = commandsByOS.get(serverOs);
if (command == null)
{
// go through the commands keys, looking for one that matches by regular expression matching
for (String osName : commandsByOS.keySet())
{
// Ignore * options. It is dealt with later.
if (osName.equals(KEY_OS_DEFAULT))
{
continue;
}
// Do regex match
if (serverOs.matches(osName))
{
command = commandsByOS.get(osName);
break;
}
}
// if there is still no command, then check for the wildcard
if (command == null)
{
command = commandsByOS.get(KEY_OS_DEFAULT);
}
}
// check
if (command == null)
{
throw new RuntimeException(
"No command found for OS " + serverOs + " or '" + KEY_OS_DEFAULT + "': \n" +
" commands: " + commandsByOS);
}
this.command = command;
}
/**
* Supply a choice of commands to execute based on a mapping from the <i>os.name</i> system
* property to the command to execute. The {@link #KEY_OS_DEFAULT *} key can be used
* to get a command where there is not direct match to the operating system key.
*
* @param commandsByOS a map of command string keyed by operating system names
* @deprecated Use {@link #setCommandsAndArguments(Map)}
*/
public void setCommandMap(Map<String, String> commandsByOS)
{
// This is deprecated, so issue a warning
logger.warn(
"The bean RuntimeExec property 'commandMap' has been deprecated;" +
" use 'commandsAndArguments' instead. See https://issues.alfresco.com/jira/browse/ETHREEOH-579.");
Map<String, String[]> fixed = new LinkedHashMap<>();
for (Map.Entry<String, String> entry : commandsByOS.entrySet())
{
String os = entry.getKey();
String unparsedCmd = entry.getValue();
StringTokenizer tokenizer = new StringTokenizer(unparsedCmd);
String[] cmd = new String[tokenizer.countTokens()];
for (int i = 0; i < cmd.length; i++)
{
cmd[i] = tokenizer.nextToken();
}
fixed.put(os, cmd);
}
setCommandsAndArguments(fixed);
}
/**
* Set the default command-line properties to use when executing the command.
* These are properties that substitute variables defined in the command string itself.
* Properties supplied during execution will overwrite the default properties.
* <p>
* <code>null</code> properties will be treated as an empty string for substitution
* purposes.
*
* @param defaultProperties property values
*/
public void setDefaultProperties(Map<String, String> defaultProperties)
{
this.defaultProperties = defaultProperties;
}
/**
* Set additional runtime properties (environment properties) that will used
* by the executing process.
* <p>
* Any keys or properties that start and end with <b>${...}</b> will be removed on the assumption
* that these are unset properties. <tt>null</tt> values are translated to empty strings.
* All keys and values are trimmed of leading and trailing whitespace.
*
* @param processProperties Runtime process properties
* @see Runtime#exec(String, String[], java.io.File)
*/
public void setProcessProperties(Map<String, String> processProperties)
{
ArrayList<String> processPropList = new ArrayList<>(processProperties.size());
boolean hasPath = false;
String systemPath = System.getenv("PATH");
for (Map.Entry<String, String> entry : processProperties.entrySet())
{
String key = entry.getKey();
String value = entry.getValue();
if (key == null)
{
continue;
}
if (value == null)
{
value = "";
}
key = key.trim();
value = value.trim();
if (key.startsWith(VAR_OPEN) && key.endsWith(VAR_CLOSE))
{
continue;
}
if (value.startsWith(VAR_OPEN) && value.endsWith(VAR_CLOSE))
{
continue;
}
// If a path is specified, prepend it to the existing path
if (key.equals("PATH"))
{
if (systemPath != null && systemPath.length() > 0)
{
processPropList.add(key + "=" + value + File.pathSeparator + systemPath);
}
else
{
processPropList.add(key + "=" + value);
}
hasPath = true;
}
else
{
processPropList.add(key + "=" + value);
}
}
// If a path was not specified, inherit the current one
if (!hasPath && systemPath != null && systemPath.length() > 0)
{
processPropList.add("PATH=" + systemPath);
}
this.processProperties = processPropList.toArray(new String[0]);
}
/**
* Adds a property to existed processProperties.
* Property should not be null or empty.
* If property with the same value already exists then no change is made.
* If property exists with a different value then old value is replaced with the new one.
*
* @param name - property name
* @param value - property value
*/
public void setProcessProperty(String name, String value)
{
boolean set = false;
if (name == null || value == null)
{
return;
}
name = name.trim();
value = value.trim();
if (name.isEmpty() || value.isEmpty())
{
return;
}
String property = name + "=" + value;
for (String prop : this.processProperties)
{
if (prop.equals(property))
{
set = true;
break;
}
if (prop.startsWith(name))
{
String oldValue = prop.split("=")[1];
prop.replace(oldValue, value);
set = true;
}
}
if (!set)
{
String[] existedProperties = this.processProperties;
int epl = existedProperties.length;
String[] newProperties = Arrays.copyOf(existedProperties, epl + 1);
newProperties[epl] = property;
this.processProperties = newProperties;
}
}
/**
* Set the runtime location from which the command is executed.
* <p>
* If the value is an unsubsititued variable (<b>${...}</b>) then it is ignored.
* If the location is not visible at the time of setting, a warning is issued only.
*
* @param processDirectory the runtime location from which to execute the command
*/
public void setProcessDirectory(String processDirectory)
{
if (processDirectory.startsWith(VAR_OPEN) && processDirectory.endsWith(VAR_CLOSE))
{
this.processDirectory = null;
}
else
{
this.processDirectory = new File(processDirectory);
if (!this.processDirectory.exists())
{
logger.warn(
"The runtime process directory is not visible when setting property " +
"'processDirectory': \n{}", this);
}
}
}
/**
* A comma or space separated list of values that, if returned by the executed command,
* indicate an error value. This defaults to <b>"1, 2"</b>.
*
* @param errCodesStr the error codes for the execution
*/
public void setErrorCodes(String errCodesStr)
{
errCodes.clear();
StringTokenizer tokenizer = new StringTokenizer(errCodesStr, " ,");
while (tokenizer.hasMoreElements())
{
String errCodeStr = tokenizer.nextToken();
// attempt to convert it to an integer
try
{
int errCode = Integer.parseInt(errCodeStr);
this.errCodes.add(errCode);
}
catch (NumberFormatException e)
{
throw new RuntimeException(
"Property 'errorCodes' must be comma-separated list of integers: " + errCodesStr);
}
}
}
/**
* Executes the command using the default properties
*
* @see #execute(Map)
*/
public ExecutionResult execute()
{
return execute(defaultProperties);
}
/**
* Executes the statement that this instance was constructed with.
*
* @param properties the properties that the command might be executed with.
* <code>null</code> properties will be treated as an empty string for substitution
* purposes.
* @return Returns the full execution results
*/
public ExecutionResult execute(Map<String, String> properties)
{
return execute(properties, -1);
}
/**
* Executes the statement that this instance was constructed with an optional
* timeout after which the command is asked to
*
* @param properties the properties that the command might be executed with.
* <code>null</code> properties will be treated as an empty string for substitution
* purposes.
* @param timeoutMs a timeout after which {@link Process#destroy()} is called.
* ignored if less than or equal to zero. Note this method does not guarantee
* to terminate the process (it is not a kill -9).
* @return Returns the full execution results
*/
public ExecutionResult execute(Map<String, String> properties, final long timeoutMs)
{
int defaultFailureExitValue = errCodes.size() > 0 ? ((Integer) errCodes.toArray()[0]) : 1;
// check that the command has been set
if (command == null)
{
throw new RuntimeException("Runtime command has not been set: \n" + this);
}
// create the properties
Runtime runtime = Runtime.getRuntime();
Process process;
String[] commandToExecute = null;
try
{
// execute the command with full property replacement
commandToExecute = getCommand(properties);
final Process thisProcess = runtime.exec(commandToExecute, processProperties,
processDirectory);
process = thisProcess;
if (timeoutMs > 0)
{
final String[] command = commandToExecute;
timer.schedule(new TimerTask()
{
@Override
public void run()
{
// Only try to kill the process if it is still running
try
{
thisProcess.exitValue();
}
catch (IllegalThreadStateException stillRunning)
{
logger.debug(
"Process has taken too long ({} seconds). Killing process {}",
timeoutMs / 1000, Arrays.deepToString(command));
}
}
}, timeoutMs);
}
}
catch (IOException e)
{
// The process could not be executed here, so just drop out with an appropriate error state
String execOut = "";
String execErr = e.getMessage();
ExecutionResult result = new ExecutionResult(null, commandToExecute, errCodes,
defaultFailureExitValue, execOut, execErr);
logFullEnvironmentDump(result);
return result;
}
// create the stream gobblers
InputStreamReaderThread stdOutGobbler = new InputStreamReaderThread(
process.getInputStream(), charset);
InputStreamReaderThread stdErrGobbler = new InputStreamReaderThread(
process.getErrorStream(), charset);
// start gobbling
stdOutGobbler.start();
stdErrGobbler.start();
// wait for the process to finish
int exitValue = 0;
try
{
if (waitForCompletion)
{
exitValue = process.waitFor();
}
}
catch (InterruptedException e)
{
// process was interrupted - generate an error message
stdErrGobbler.addToBuffer(e.toString());
exitValue = defaultFailureExitValue;
}
if (waitForCompletion)
{
// ensure that the stream gobblers get to finish
stdOutGobbler.waitForCompletion();
stdErrGobbler.waitForCompletion();
}
// get the stream values
String execOut = stdOutGobbler.getBuffer();
String execErr = stdErrGobbler.getBuffer();
// construct the return value
ExecutionResult result = new ExecutionResult(process, commandToExecute, errCodes, exitValue,
execOut, execErr);
// done
logFullEnvironmentDump(result);
return result;
}
/**
* Dump the full environment in debug mode
*/
private void logFullEnvironmentDump(ExecutionResult result)
{
if (logger.isTraceEnabled())
{
StringBuilder sb = new StringBuilder();
sb.append(result);
// Environment variables modified by Alfresco
if (processProperties != null && processProperties.length > 0)
{
sb.append("\n modified environment: ");
for (String property : processProperties)
{
sb.append("\n ");
sb.append(property);
}
}
// Dump the full environment
sb.append("\n existing environment: ");
Map<String, String> envVariables = System.getenv();
for (Map.Entry<String, String> entry : envVariables.entrySet())
{
String name = entry.getKey();
String value = entry.getValue();
sb.append("\n ");
sb.append(name).append("=").append(value);
}
logger.trace(sb.toString());
}
logger.debug("Result: " + result.toString());
// close output stream (connected to input stream of native subprocess)
}
/**
* @return Returns the command that will be executed if no additional properties
* were to be supplied
*/
public String[] getCommand()
{
return getCommand(defaultProperties);
}
/**
* Get the command that will be executed post substitution.
* <p>
* <code>null</code> properties will be treated as an empty string for substitution
* purposes.
*
* @param properties the properties that the command might be executed with
* @return Returns the command that will be executed should the additional properties
* be supplied
*/
public String[] getCommand(Map<String, String> properties)
{
Map<String, String> execProperties;
if (properties == defaultProperties)
{
// we are just using the default properties
execProperties = defaultProperties;
}
else
{
execProperties = new HashMap<>(defaultProperties);
// overlay the supplied properties
execProperties.putAll(properties);
}
// Perform the substitution for each element of the command
ArrayList<String> adjustedCommandElements = new ArrayList<>(20);
for (String s : command)
{
StringBuilder sb = new StringBuilder(s);
for (Map.Entry<String, String> entry : execProperties.entrySet())
{
String key = entry.getKey();
String value = entry.getValue();
// ignore null
if (value == null)
{
value = "";
}
// progressively replace the property in the command
key = (VAR_OPEN + key + VAR_CLOSE);
int index = sb.indexOf(key);
while (index > -1)
{
// replace
sb.replace(index, index + key.length(), value);
// get the next one
index = sb.indexOf(key, index + 1);
}
}
String adjustedValue = sb.toString();
// Now SPLIT: it
if (adjustedValue.startsWith(DIRECTIVE_SPLIT))
{
String unsplitAdjustedValue = sb.substring(DIRECTIVE_SPLIT.length());
// There may be quoted arguments here (see ALF-7482)
ExecParameterTokenizer quoteAwareTokenizer = new ExecParameterTokenizer(
unsplitAdjustedValue);
List<String> tokens = quoteAwareTokenizer.getAllTokens();
adjustedCommandElements.addAll(tokens);
}
else
{
adjustedCommandElements.add(adjustedValue);
}
}
// done
return adjustedCommandElements.toArray(new String[0]);
}
/**
* Object to carry the results of an execution to the caller.
*
* @author Derek Hulley
*/
public static class ExecutionResult
{
private final Process process;
private final String[] command;
private final Set<Integer> errCodes;
private final int exitValue;
private final String stdOut;
private final String stdErr;
/**
* @param process the process attached to Java - <tt>null</tt> is allowed
*/
private ExecutionResult(
final Process process,
final String[] command,
final Set<Integer> errCodes,
final int exitValue,
final String stdOut,
final String stdErr)
{
this.process = process;
this.command = command;
this.errCodes = errCodes;
this.exitValue = exitValue;
this.stdOut = stdOut;
this.stdErr = stdErr;
}
@Override
public String toString()
{
String out = stdOut.length() > 250 ? stdOut.substring(0, 250) : stdOut;
String err = stdErr.length() > 250 ? stdErr.substring(0, 250) : stdErr;
StringBuilder sb = new StringBuilder(128);
sb.append("Execution result: \n")
.append(" os: ").append(System.getProperty(KEY_OS_NAME)).append("\n")
.append(" command: ");
appendCommand(sb, command).append("\n")
.append(" succeeded: ").append(getSuccess()).append("\n")
.append(" exit code: ").append(exitValue).append("\n")
.append(" out: ").append(out).append("\n")
.append(" err: ").append(err);
return sb.toString();
}
/**
* Appends the command in a form that make running from the command line simpler.
* It is not a real attempt at making a command given all the operating system
* and shell options, but makes copy, paste and edit a bit simpler.
*/
private StringBuilder appendCommand(StringBuilder sb, String[] command)
{
boolean arg = false;
for (String element : command)
{
if (element == null)
{
continue;
}
if (arg)
{
sb.append(' ');
}
else
{
arg = true;
}
boolean escape = element.indexOf(' ') != -1 || element.indexOf('>') != -1;
if (escape)
{
sb.append("\"");
}
sb.append(element);
if (escape)
{
sb.append("\"");
}
}
return sb;
}
/**
* A helper method to force a kill of the process that generated this result. This is
* useful in cases where the process started is not expected to exit, or doesn't exit
* quickly. If the {@linkplain RuntimeExec#setWaitForCompletion(boolean) "wait for completion"}
* flag is <tt>false</tt> then the process may still be running when this result is returned.
*
* @return <tt>true</tt> if the process was killed, otherwise <tt>false</tt>
*/
public boolean killProcess()
{
if (process == null)
{
return true;
}
try
{
process.destroy();
return true;
}
catch (Throwable e)
{
logger.warn(e.getMessage());
return false;
}
}
/**
* @param exitValue the command exit value
* @return Returns true if the code is a listed failure code
* @see #setErrorCodes(String)
*/
private boolean isFailureCode(int exitValue)
{
return errCodes.contains(exitValue);
}
/**
* @return Returns true if the command was deemed to be successful according to the
* failure codes returned by the execution.
*/
public boolean getSuccess()
{
return !isFailureCode(exitValue);
}
public int getExitValue()
{
return exitValue;
}
public String getStdOut()
{
return stdOut;
}
public String getStdErr()
{
return stdErr;
}
}
/**
* Gobbles an <code>InputStream</code> and writes it into a
* <code>StringBuffer</code>
* <p>
* The reading of the input stream is buffered.
*/
public static class InputStreamReaderThread extends Thread
{
private final InputStream is;
private final Charset charset;
private final StringBuffer buffer; // we require the synchronization
private boolean completed;
/**
* @param is an input stream to read - it will be wrapped in a buffer
* for reading
*/
public InputStreamReaderThread(InputStream is, Charset charset)
{
super();
setDaemon(true); // must not hold up the VM if it is terminating
this.is = is;
this.charset = charset;
this.buffer = new StringBuffer(BUFFER_SIZE);
this.completed = false;
}
public synchronized void run()
{
completed = false;
byte[] bytes = new byte[BUFFER_SIZE];
try (InputStream tempIs = new BufferedInputStream(is, BUFFER_SIZE))
{
int count = -2;
while (count != -1)
{
// do we have something previously read?
if (count > 0)
{
String toWrite = new String(bytes, 0, count, charset.name());
buffer.append(toWrite);
}
// read the next set of bytes
count = tempIs.read(bytes);
}
// done
}
catch (IOException e)
{
throw new RuntimeException("Unable to read stream", e);
}
finally
{
// The thread has finished consuming the stream
completed = true;
// Notify waiters
this.notifyAll(); // Note: Method is synchronized
}
}
/**
* Waits for the run to complete.
* <p>
* <b>Remember to <code>start</code> the thread first
*/
public synchronized void waitForCompletion()
{
while (!completed)
{
try
{
// release our lock and wait a bit
this.wait(1000L); // 200 ms
}
catch (InterruptedException ignore)
{
}
}
}
/**
* @param msg the message to add to the buffer
*/
public void addToBuffer(String msg)
{
buffer.append(msg);
}
public boolean isComplete()
{
return completed;
}
/**
* @return Returns the current state of the buffer
*/
public String getBuffer()
{
return buffer.toString();
}
}
}

View File

@ -44,7 +44,6 @@ import javax.servlet.http.HttpServletRequest;
import org.alfresco.transform.exceptions.TransformException; import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.transformer.logging.LogEntry; import org.alfresco.transformer.logging.LogEntry;
import org.alfresco.util.TempFileProvider;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource; import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@ -241,4 +240,44 @@ public class FileManager
return ResponseEntity.ok().header(CONTENT_DISPOSITION, return ResponseEntity.ok().header(CONTENT_DISPOSITION,
"attachment; filename*= UTF-8''" + targetFilename).body(targetResource); "attachment; filename*= UTF-8''" + targetFilename).body(targetResource);
} }
/**
* TempFileProvider - Duplicated and adapted from alfresco-core.
*/
public static class TempFileProvider
{
public static File createTempFile(final String prefix, final String suffix)
{
final File directory = getTempDir();
try
{
return File.createTempFile(prefix, suffix, directory);
}
catch (IOException e)
{
throw new RuntimeException(
"Failed to created temp file: \n prefix: " + prefix +
"\n suffix: " + suffix + "\n directory: " + directory, e);
}
}
private static File getTempDir()
{
final String dirName = "Alfresco";
final String systemTempDirPath = System.getProperty("java.io.tmpdir");
if (systemTempDirPath == null)
{
throw new RuntimeException("System property not available: java.io.tmpdir");
}
final File systemTempDir = new File(systemTempDirPath);
final File tempDir = new File(systemTempDir, dirName);
if (!tempDir.exists() && !tempDir.mkdirs() && !tempDir.exists())
{
throw new RuntimeException("Failed to create temp directory: " + tempDir);
}
return tempDir;
}
}
} }

View File

@ -28,6 +28,7 @@ package org.alfresco.transformer.probes;
import static org.alfresco.transformer.fs.FileManager.SOURCE_FILE; import static org.alfresco.transformer.fs.FileManager.SOURCE_FILE;
import static org.alfresco.transformer.fs.FileManager.TARGET_FILE; import static org.alfresco.transformer.fs.FileManager.TARGET_FILE;
import static org.alfresco.transformer.fs.FileManager.TempFileProvider.createTempFile;
import static org.springframework.http.HttpStatus.INSUFFICIENT_STORAGE; import static org.springframework.http.HttpStatus.INSUFFICIENT_STORAGE;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.OK;
@ -46,7 +47,6 @@ import javax.servlet.http.HttpServletRequest;
import org.alfresco.transform.exceptions.TransformException; import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.transformer.AbstractTransformerController; import org.alfresco.transformer.AbstractTransformerController;
import org.alfresco.transformer.logging.LogEntry; import org.alfresco.transformer.logging.LogEntry;
import org.alfresco.util.TempFileProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -263,7 +263,7 @@ public abstract class ProbeTestTransform
private File getSourceFile(HttpServletRequest request, boolean isLiveProbe) private File getSourceFile(HttpServletRequest request, boolean isLiveProbe)
{ {
incrementTransformerCount(); incrementTransformerCount();
File sourceFile = TempFileProvider.createTempFile("source_", "_" + sourceFilename); File sourceFile = createTempFile("source_", "_" + sourceFilename);
request.setAttribute(SOURCE_FILE, sourceFile); request.setAttribute(SOURCE_FILE, sourceFile);
try (InputStream inputStream = this.getClass().getResourceAsStream('/' + sourceFilename)) try (InputStream inputStream = this.getClass().getResourceAsStream('/' + sourceFilename))
{ {
@ -281,7 +281,7 @@ public abstract class ProbeTestTransform
private File getTargetFile(HttpServletRequest request) private File getTargetFile(HttpServletRequest request)
{ {
File targetFile = TempFileProvider.createTempFile("target_", "_" + targetFilename); File targetFile = createTempFile("target_", "_" + targetFilename);
request.setAttribute(TARGET_FILE, targetFile); request.setAttribute(TARGET_FILE, targetFile);
LogEntry.setTarget(targetFilename); LogEntry.setTarget(targetFilename);
return targetFile; return targetFile;

View File

@ -0,0 +1,165 @@
/*
* #%L
* Alfresco Transform Core
* %%
* Copyright (C) 2005 - 2019 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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.transformer.util;
/**
* Partially duplicated from *alfresco-data-model*.
*/
public interface MimetypeMap
{
String PREFIX_APPLICATION = "application/";
String PREFIX_AUDIO = "audio/";
String PREFIX_IMAGE = "image/";
String PREFIX_MESSAGE = "message/";
String PREFIX_MODEL = "model/";
String PREFIX_MULTIPART = "multipart/";
String PREFIX_TEXT = "text/";
String PREFIX_VIDEO = "video/";
String EXTENSION_BINARY = "bin";
String MACOS_RESOURCE_FORK_FILE_NAME_PREFIX = "._";
String MIMETYPE_MULTIPART_ALTERNATIVE = "multipart/alternative";
String MIMETYPE_TEXT_PLAIN = "text/plain";
String MIMETYPE_TEXT_MEDIAWIKI = "text/mediawiki";
String MIMETYPE_TEXT_CSS = "text/css";
String MIMETYPE_TEXT_CSV = "text/csv";
String MIMETYPE_TEXT_JAVASCRIPT = "text/javascript";
String MIMETYPE_XML = "text/xml";
String MIMETYPE_HTML = "text/html";
String MIMETYPE_XHTML = "application/xhtml+xml";
String MIMETYPE_PDF = "application/pdf";
String MIMETYPE_JSON = "application/json";
String MIMETYPE_WORD = "application/msword";
String MIMETYPE_EXCEL = "application/vnd.ms-excel";
String MIMETYPE_BINARY = "application/octet-stream";
String MIMETYPE_PPT = "application/vnd.ms-powerpoint";
String MIMETYPE_APP_DWG = "application/dwg";
String MIMETYPE_IMG_DWG = "image/vnd.dwg";
String MIMETYPE_VIDEO_AVI = "video/x-msvideo";
String MIMETYPE_VIDEO_QUICKTIME = "video/quicktime";
String MIMETYPE_VIDEO_WMV = "video/x-ms-wmv";
String MIMETYPE_VIDEO_3GP = "video/3gpp";
String MIMETYPE_VIDEO_3GP2 = "video/3gpp2";
String MIMETYPE_DITA = "application/dita+xml";
String MIMETYPE_FLASH = "application/x-shockwave-flash";
String MIMETYPE_VIDEO_FLV = "video/x-flv";
String MIMETYPE_APPLICATION_FLA = "application/x-fla";
String MIMETYPE_VIDEO_MPG = "video/mpeg";
String MIMETYPE_VIDEO_MP4 = "video/mp4";
String MIMETYPE_IMAGE_GIF = "image/gif";
String MIMETYPE_IMAGE_JPEG = "image/jpeg";
String MIMETYPE_IMAGE_RGB = "image/x-rgb";
String MIMETYPE_IMAGE_SVG = "image/svg+xml";
String MIMETYPE_IMAGE_PNG = "image/png";
String MIMETYPE_IMAGE_TIFF = "image/tiff";
String MIMETYPE_IMAGE_RAW_DNG = "image/x-raw-adobe";
String MIMETYPE_IMAGE_RAW_3FR = "image/x-raw-hasselblad";
String MIMETYPE_IMAGE_RAW_RAF = "image/x-raw-fuji";
String MIMETYPE_IMAGE_RAW_CR2 = "image/x-raw-canon";
String MIMETYPE_IMAGE_RAW_K25 = "image/x-raw-kodak";
String MIMETYPE_IMAGE_RAW_MRW = "image/x-raw-minolta";
String MIMETYPE_IMAGE_RAW_NEF = "image/x-raw-nikon";
String MIMETYPE_IMAGE_RAW_ORF = "image/x-raw-olympus";
String MIMETYPE_IMAGE_RAW_PEF = "image/x-raw-pentax";
String MIMETYPE_IMAGE_RAW_ARW = "image/x-raw-sony";
String MIMETYPE_IMAGE_RAW_X3F = "image/x-raw-sigma";
String MIMETYPE_IMAGE_RAW_RW2 = "image/x-raw-panasonic";
String MIMETYPE_IMAGE_RAW_RWL = "image/x-raw-leica";
String MIMETYPE_IMAGE_RAW_R3D = "image/x-raw-red";
String MIMETYPE_IMAGE_DWT = "image/x-dwt";
String MIMETYPE_APPLICATION_EPS = "application/eps";
String MIMETYPE_APPLICATION_PS = "application/postscript";
String MIMETYPE_JAVASCRIPT = "application/x-javascript";
String MIMETYPE_ZIP = "application/zip";
String MIMETYPE_OPENSEARCH_DESCRIPTION = "application/opensearchdescription+xml";
String MIMETYPE_ATOM = "application/atom+xml";
String MIMETYPE_RSS = "application/rss+xml";
String MIMETYPE_RFC822 = "message/rfc822";
String MIMETYPE_OUTLOOK_MSG = "application/vnd.ms-outlook";
String MIMETYPE_VISIO = "application/vnd.visio";
String MIMETYPE_VISIO_2013 = "application/vnd.visio2013";
String MIMETYPE_APPLICATION_ILLUSTRATOR = "application/illustrator";
String MIMETYPE_APPLICATION_PHOTOSHOP = "image/vnd.adobe.photoshop";
String MIMETYPE_ENCRYPTED_OFFICE = "application/x-tika-ooxml-protected";
String MIMETYPE_OPENDOCUMENT_TEXT = "application/vnd.oasis.opendocument.text";
String MIMETYPE_OPENDOCUMENT_TEXT_TEMPLATE = "application/vnd.oasis.opendocument.text-template";
String MIMETYPE_OPENDOCUMENT_GRAPHICS = "application/vnd.oasis.opendocument.graphics";
String MIMETYPE_OPENDOCUMENT_GRAPHICS_TEMPLATE = "application/vnd.oasis.opendocument.graphics-template";
String MIMETYPE_OPENDOCUMENT_PRESENTATION = "application/vnd.oasis.opendocument.presentation";
String MIMETYPE_OPENDOCUMENT_PRESENTATION_TEMPLATE = "application/vnd.oasis.opendocument.presentation-template";
String MIMETYPE_OPENDOCUMENT_SPREADSHEET = "application/vnd.oasis.opendocument.spreadsheet";
String MIMETYPE_OPENDOCUMENT_SPREADSHEET_TEMPLATE = "application/vnd.oasis.opendocument.spreadsheet-template";
String MIMETYPE_OPENDOCUMENT_CHART = "application/vnd.oasis.opendocument.chart";
String MIMETYPE_OPENDOCUMENT_CHART_TEMPLATE = "applicationvnd.oasis.opendocument.chart-template";
String MIMETYPE_OPENDOCUMENT_IMAGE = "application/vnd.oasis.opendocument.image";
String MIMETYPE_OPENDOCUMENT_IMAGE_TEMPLATE = "applicationvnd.oasis.opendocument.image-template";
String MIMETYPE_OPENDOCUMENT_FORMULA = "application/vnd.oasis.opendocument.formula";
String MIMETYPE_OPENDOCUMENT_FORMULA_TEMPLATE = "applicationvnd.oasis.opendocument.formula-template";
String MIMETYPE_OPENDOCUMENT_TEXT_MASTER = "application/vnd.oasis.opendocument.text-master";
String MIMETYPE_OPENDOCUMENT_TEXT_WEB = "application/vnd.oasis.opendocument.text-web";
String MIMETYPE_OPENDOCUMENT_DATABASE = "application/vnd.oasis.opendocument.database";
String MIMETYPE_OPENOFFICE1_WRITER = "application/vnd.sun.xml.writer";
String MIMETYPE_OPENOFFICE1_CALC = "application/vnd.sun.xml.calc";
String MIMETYPE_OPENOFFICE1_DRAW = "application/vnd.sun.xml.draw";
String MIMETYPE_OPENOFFICE1_IMPRESS = "application/vnd.sun.xml.impress";
String MIMETYPE_OPENXML_WORDPROCESSING = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
String MIMETYPE_OPENXML_WORDPROCESSING_MACRO = "application/vnd.ms-word.document.macroenabled.12";
String MIMETYPE_OPENXML_WORD_TEMPLATE = "application/vnd.openxmlformats-officedocument.wordprocessingml.template";
String MIMETYPE_OPENXML_WORD_TEMPLATE_MACRO = "application/vnd.ms-word.template.macroenabled.12";
String MIMETYPE_OPENXML_SPREADSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
String MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE = "application/vnd.openxmlformats-officedocument.spreadsheetml.template";
String MIMETYPE_OPENXML_SPREADSHEET_MACRO = "application/vnd.ms-excel.sheet.macroenabled.12";
String MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO = "application/vnd.ms-excel.template.macroenabled.12";
String MIMETYPE_OPENXML_SPREADSHEET_ADDIN_MACRO = "application/vnd.ms-excel.addin.macroenabled.12";
String MIMETYPE_OPENXML_SPREADSHEET_BINARY_MACRO = "application/vnd.ms-excel.sheet.binary.macroenabled.12";
String MIMETYPE_OPENXML_PRESENTATION = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
String MIMETYPE_OPENXML_PRESENTATION_MACRO = "application/vnd.ms-powerpoint.presentation.macroenabled.12";
String MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW = "application/vnd.openxmlformats-officedocument.presentationml.slideshow";
String MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO = "application/vnd.ms-powerpoint.slideshow.macroenabled.12";
String MIMETYPE_OPENXML_PRESENTATION_TEMPLATE = "application/vnd.openxmlformats-officedocument.presentationml.template";
String MIMETYPE_OPENXML_PRESENTATION_TEMPLATE_MACRO = "application/vnd.ms-powerpoint.template.macroenabled.12";
String MIMETYPE_OPENXML_PRESENTATION_ADDIN = "application/vnd.ms-powerpoint.addin.macroenabled.12";
String MIMETYPE_OPENXML_PRESENTATION_SLIDE = "application/vnd.openxmlformats-officedocument.presentationml.slide";
String MIMETYPE_OPENXML_PRESENTATION_SLIDE_MACRO = "application/vnd.ms-powerpoint.slide.macroenabled.12";
String MIMETYPE_STAROFFICE5_DRAW = "application/vnd.stardivision.draw";
String MIMETYPE_STAROFFICE5_CALC = "application/vnd.stardivision.calc";
String MIMETYPE_STAROFFICE5_IMPRESS = "application/vnd.stardivision.impress";
String MIMETYPE_STAROFFICE5_IMPRESS_PACKED = "application/vnd.stardivision.impress-packed";
String MIMETYPE_STAROFFICE5_CHART = "application/vnd.stardivision.chart";
String MIMETYPE_STAROFFICE5_WRITER = "application/vnd.stardivision.writer";
String MIMETYPE_STAROFFICE5_WRITER_GLOBAL = "application/vnd.stardivision.writer-global";
String MIMETYPE_STAROFFICE5_MATH = "application/vnd.stardivision.math";
String MIMETYPE_IWORK_KEYNOTE = "application/vnd.apple.keynote";
String MIMETYPE_IWORK_NUMBERS = "application/vnd.apple.numbers";
String MIMETYPE_IWORK_PAGES = "application/vnd.apple.pages";
String MIMETYPE_APPLEFILE = "application/applefile";
String MIMETYPE_WORDPERFECT = "application/wordperfect";
String MIMETYPE_MP3 = "audio/mpeg";
String MIMETYPE_AUDIO_MP4 = "audio/mp4";
String MIMETYPE_VORBIS = "audio/vorbis";
String MIMETYPE_FLAC = "audio/x-flac";
String MIMETYPE_ACP = "application/acp";
}

22
pom.xml
View File

@ -21,8 +21,6 @@
<image.tag>latest</image.tag> <image.tag>latest</image.tag>
<dependency.pdfbox.version>2.0.16</dependency.pdfbox.version> <dependency.pdfbox.version>2.0.16</dependency.pdfbox.version>
<dependency.alfresco-core.version>7.17</dependency.alfresco-core.version>
<dependency.alfresco-data-model.version>8.39</dependency.alfresco-data-model.version>
<dependency.alfresco-jodconverter-core.version>3.0.1.1</dependency.alfresco-jodconverter-core.version> <dependency.alfresco-jodconverter-core.version>3.0.1.1</dependency.alfresco-jodconverter-core.version>
<env.project_version>${project.version}</env.project_version> <env.project_version>${project.version}</env.project_version>
<dependency.alfresco-transform-model.version>1.0.2.3</dependency.alfresco-transform-model.version> <dependency.alfresco-transform-model.version>1.0.2.3</dependency.alfresco-transform-model.version>
@ -50,31 +48,11 @@
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-core</artifactId>
<version>${dependency.alfresco-core.version}</version>
<!--
TODO temp workaround for ATS-481 / REPO-4514 (exclude: dom4j.dom4j 1.6.1 / include org.dom4j.dom4j 2.1.1)
TODO remove this workaround once transitive dependencies have been fixed (surf-core-configservice -> alfresco-core)
-->
<exclusions>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.dom4j</groupId> <groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>2.1.1</version> <version>2.1.1</version>
</dependency> </dependency>
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-data-model</artifactId>
<version>${dependency.alfresco-data-model.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-jodconverter-core</artifactId> <artifactId>alfresco-jodconverter-core</artifactId>