mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2025-08-14 17:58:27 +00:00
Save point: [skip ci]
* cleaning up TransformController - more to do * wire up all transforms
This commit is contained in:
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 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.transform;
|
|
||||||
|
|
||||||
import org.alfresco.transform.config.TransformConfig;
|
|
||||||
import org.alfresco.transformer.probes.ProbeTestTransform;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The interface to the custom transform code applied on top of a base t-engine.
|
|
||||||
*/
|
|
||||||
public interface TransformEngine
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return the name of the t-engine. The t-router reads config from t-engines in name order.
|
|
||||||
*/
|
|
||||||
String getTransformEngineName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a definition of what the t-engine supports. Normally read from a json Resource on the classpath.
|
|
||||||
*/
|
|
||||||
TransformConfig getTransformConfig();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return actual transform codes.
|
|
||||||
*/
|
|
||||||
Set<CustomTransformer> getTransformers();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a ProbeTestTransform (will do a quick transform) for k8 liveness and readiness probes.
|
|
||||||
*/
|
|
||||||
ProbeTestTransform getLivenessAndReadinessProbeTestTransform();
|
|
||||||
}
|
|
@@ -36,12 +36,14 @@ import java.util.Map;
|
|||||||
* Interface to be implemented by transform specific code. The {@code transformerName} should match the transformerName
|
* Interface to be implemented by transform specific code. The {@code transformerName} should match the transformerName
|
||||||
* in the {@link TransformConfig} returned by the {@link TransformEngine}. So that it is automatically picked up, it
|
* in the {@link TransformConfig} returned by the {@link TransformEngine}. So that it is automatically picked up, it
|
||||||
* must exist in a package under {@code org.alfresco.transform} and have the Spring {@code @Component} annotation.
|
* must exist in a package under {@code org.alfresco.transform} and have the Spring {@code @Component} annotation.
|
||||||
|
*
|
||||||
|
* Implementations may also use the {@link TransformManager} if they wish to interact with the base t-engine.
|
||||||
*/
|
*/
|
||||||
public interface CustomTransformer
|
public interface CustomTransformer
|
||||||
{
|
{
|
||||||
String getTransformerName();
|
String getTransformerName();
|
||||||
|
|
||||||
void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
void transform(String sourceMimetype, InputStream inputStream,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
String targetMimetype, OutputStream outputStream,
|
||||||
Map<String, String> transformOptions) throws Exception;
|
Map<String, String> transformOptions, TransformManager transformManager) throws Exception;
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.base;
|
package org.alfresco.transform.base;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.fs.FileManager;
|
||||||
import org.alfresco.transform.base.probes.ProbeTestTransform;
|
import org.alfresco.transform.base.probes.ProbeTestTransform;
|
||||||
|
import org.alfresco.transform.base.util.OutputStreamLengthRecorder;
|
||||||
import org.alfresco.transform.common.TransformerDebug;
|
import org.alfresco.transform.common.TransformerDebug;
|
||||||
import org.alfresco.transform.client.model.InternalContext;
|
import org.alfresco.transform.client.model.InternalContext;
|
||||||
import org.alfresco.transform.client.model.TransformReply;
|
import org.alfresco.transform.client.model.TransformReply;
|
||||||
@@ -38,7 +40,6 @@ import org.alfresco.transform.common.TransformException;
|
|||||||
import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient;
|
import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient;
|
||||||
import org.alfresco.transform.base.logging.LogEntry;
|
import org.alfresco.transform.base.logging.LogEntry;
|
||||||
import org.alfresco.transform.base.model.FileRefResponse;
|
import org.alfresco.transform.base.model.FileRefResponse;
|
||||||
import org.codehaus.plexus.util.FileUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.TypeMismatchException;
|
import org.springframework.beans.TypeMismatchException;
|
||||||
@@ -65,13 +66,16 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.client.HttpClientErrorException;
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -82,6 +86,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
import static org.alfresco.transform.base.fs.FileManager.createTargetFile;
|
||||||
|
import static org.alfresco.transform.common.RequestParamMap.TARGET_ENCODING;
|
||||||
import static org.alfresco.transform.config.CoreVersionDecorator.setOrClearCoreVersion;
|
import static org.alfresco.transform.config.CoreVersionDecorator.setOrClearCoreVersion;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL;
|
import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.CONFIG_VERSION;
|
import static org.alfresco.transform.common.RequestParamMap.CONFIG_VERSION;
|
||||||
@@ -89,11 +95,7 @@ import static org.alfresco.transform.common.RequestParamMap.CONFIG_VERSION_DEFAU
|
|||||||
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
|
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG;
|
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG;
|
||||||
import static org.alfresco.transform.base.fs.FileManager.TempFileProvider.createTempFile;
|
import static org.alfresco.transform.base.fs.FileManager.TempFileProvider.createTempFile;
|
||||||
import static org.alfresco.transform.base.fs.FileManager.buildFile;
|
import static org.alfresco.transform.base.fs.FileManager.getDirectAccessUrlInputStream;
|
||||||
import static org.alfresco.transform.base.fs.FileManager.createAttachment;
|
|
||||||
import static org.alfresco.transform.base.fs.FileManager.createSourceFile;
|
|
||||||
import static org.alfresco.transform.base.fs.FileManager.createTargetFile;
|
|
||||||
import static org.alfresco.transform.base.fs.FileManager.createTargetFileName;
|
|
||||||
import static org.alfresco.transform.base.fs.FileManager.deleteFile;
|
import static org.alfresco.transform.base.fs.FileManager.deleteFile;
|
||||||
import static org.alfresco.transform.base.fs.FileManager.getFilenameFromContentDisposition;
|
import static org.alfresco.transform.base.fs.FileManager.getFilenameFromContentDisposition;
|
||||||
import static org.alfresco.transform.base.fs.FileManager.save;
|
import static org.alfresco.transform.base.fs.FileManager.save;
|
||||||
@@ -280,7 +282,7 @@ public class TransformController
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = ENDPOINT_TRANSFORM, consumes = MULTIPART_FORM_DATA_VALUE)
|
@PostMapping(value = ENDPOINT_TRANSFORM, consumes = MULTIPART_FORM_DATA_VALUE)
|
||||||
public ResponseEntity<Resource> transform(HttpServletRequest request,
|
public StreamingResponseBody transform(HttpServletRequest request,
|
||||||
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,
|
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,
|
||||||
@RequestParam(value = SOURCE_MIMETYPE, required = false) String sourceMimetype,
|
@RequestParam(value = SOURCE_MIMETYPE, required = false) String sourceMimetype,
|
||||||
@RequestParam(value = TARGET_MIMETYPE, required = false) String targetMimetype,
|
@RequestParam(value = TARGET_MIMETYPE, required = false) String targetMimetype,
|
||||||
@@ -291,51 +293,55 @@ public class TransformController
|
|||||||
logger.debug("Processing request via HTTP endpoint. Params: sourceMimetype: '{}', targetMimetype: '{}', "
|
logger.debug("Processing request via HTTP endpoint. Params: sourceMimetype: '{}', targetMimetype: '{}', "
|
||||||
+ "requestParameters: {}", sourceMimetype, targetMimetype, requestParameters);
|
+ "requestParameters: {}", sourceMimetype, targetMimetype, requestParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, "");
|
|
||||||
|
|
||||||
File sourceFile;
|
|
||||||
String sourceFilename;
|
|
||||||
if (directUrl.isBlank())
|
|
||||||
{
|
|
||||||
if (sourceMultipartFile == null)
|
|
||||||
{
|
|
||||||
throw new TransformException(BAD_REQUEST.value(), "Required request part 'file' is not present");
|
|
||||||
}
|
|
||||||
sourceFile = createSourceFile(request, sourceMultipartFile);
|
|
||||||
sourceFilename = sourceMultipartFile.getOriginalFilename();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sourceFile = getSourceFileFromDirectUrl(directUrl);
|
|
||||||
sourceFilename = sourceFile.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
final String targetFilename = createTargetFileName(sourceFilename, sourceMimetype, targetMimetype);
|
|
||||||
probeTestTransform.incrementTransformerCount();
|
probeTestTransform.incrementTransformerCount();
|
||||||
final File targetFile = createTargetFile(request, targetFilename);
|
|
||||||
|
|
||||||
|
// Obtain the source
|
||||||
|
final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, "");
|
||||||
|
InputStream inputStream = directUrl.isBlank()
|
||||||
|
? FileManager.getMultipartFileInputStream(sourceMultipartFile)
|
||||||
|
: getDirectAccessUrlInputStream(directUrl);
|
||||||
|
long sourceSizeInBytes = -1L; // TODO pass in t-options or just ignore for http request as the repo will have checked.
|
||||||
Map<String, String> transformOptions = getTransformOptions(requestParameters);
|
Map<String, String> transformOptions = getTransformOptions(requestParameters);
|
||||||
String transformName = getTransformerName(sourceFile, sourceMimetype, targetMimetype, transformOptions);
|
String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions);
|
||||||
|
CustomTransformer customTransformer = getCustomTransformer(transformName);
|
||||||
|
String sourceEncoding = transformOptions.get(SOURCE_ENCODING);
|
||||||
|
String targetEncoding = transformOptions.get(TARGET_ENCODING); // TODO not normally set
|
||||||
String reference = "e"+httpRequestCount.getAndIncrement();
|
String reference = "e"+httpRequestCount.getAndIncrement();
|
||||||
transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceFile, transformName);
|
transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformName);
|
||||||
transformerDebug.logOptions(reference, requestParameters);
|
transformerDebug.logOptions(reference, requestParameters);
|
||||||
|
|
||||||
|
return os -> {
|
||||||
|
OutputStreamLengthRecorder outputStream = new OutputStreamLengthRecorder(os);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
transformImpl(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
TransformManagerImpl transformManager = TransformManagerImpl.builder()
|
||||||
|
.withRequest(request)
|
||||||
|
.withSourceMimetype(sourceMimetype)
|
||||||
|
.withTargetMimetype(targetMimetype)
|
||||||
|
.withInputStream(inputStream)
|
||||||
|
.withOutputStream(outputStream)
|
||||||
|
.build();
|
||||||
|
|
||||||
final ResponseEntity<Resource> body = createAttachment(targetFilename, targetFile);
|
customTransformer.transform(sourceMimetype, inputStream,
|
||||||
LogEntry.setTargetSize(targetFile.length());
|
targetMimetype, outputStream, transformOptions, transformManager);
|
||||||
|
|
||||||
|
transformManager.ifUsedCopyTargetFileToOutputStream();
|
||||||
|
|
||||||
|
LogEntry.setTargetSize(outputStream.getLength());
|
||||||
long time = LogEntry.setStatusCodeAndMessage(OK.value(), "Success");
|
long time = LogEntry.setStatusCodeAndMessage(OK.value(), "Success");
|
||||||
|
|
||||||
|
transformManager.deleteSourceFileIfExists();
|
||||||
|
transformManager.deleteTargetFileIfExists();
|
||||||
|
|
||||||
probeTestTransform.recordTransformTime(time);
|
probeTestTransform.recordTransformTime(time);
|
||||||
transformerDebug.popTransform(reference, time);
|
transformerDebug.popTransform(reference, time);
|
||||||
return body;
|
|
||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
transformerDebug.logFailure(reference, t.getMessage());
|
transformerDebug.logFailure(reference, e.getMessage());
|
||||||
throw t;
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -353,89 +359,68 @@ public class TransformController
|
|||||||
public ResponseEntity<TransformReply> transform(@RequestBody TransformRequest request,
|
public ResponseEntity<TransformReply> transform(@RequestBody TransformRequest request,
|
||||||
@RequestParam(value = "timeout", required = false) Long timeout)
|
@RequestParam(value = "timeout", required = false) Long timeout)
|
||||||
{
|
{
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
logger.trace("Received {}, timeout {} ms", request, timeout);
|
logger.trace("Received {}, timeout {} ms", request, timeout);
|
||||||
|
probeTestTransform.incrementTransformerCount();
|
||||||
|
TransformReply reply = createBasicTransformReply(request);
|
||||||
|
|
||||||
final TransformReply reply = new TransformReply();
|
if (isTransformRequestValid(request, reply) == false)
|
||||||
reply.setRequestId(request.getRequestId());
|
|
||||||
reply.setSourceReference(request.getSourceReference());
|
|
||||||
reply.setSchema(request.getSchema());
|
|
||||||
reply.setClientData(request.getClientData());
|
|
||||||
|
|
||||||
final Errors errors = validateTransformRequest(request);
|
|
||||||
validateInternalContext(request, errors);
|
|
||||||
initialiseContext(request);
|
|
||||||
reply.setInternalContext(request.getInternalContext());
|
|
||||||
if (!errors.getAllErrors().isEmpty())
|
|
||||||
{
|
{
|
||||||
reply.setStatus(BAD_REQUEST.value());
|
|
||||||
reply.setErrorDetails(errors
|
|
||||||
.getAllErrors()
|
|
||||||
.stream()
|
|
||||||
.map(Object::toString)
|
|
||||||
.collect(joining(", ")));
|
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
|
||||||
logger.trace("Invalid request, sending {}", reply);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
|
||||||
}
|
|
||||||
transformerDebug.pushTransform(request);
|
|
||||||
|
|
||||||
// Load the source file
|
|
||||||
File sourceFile;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
final String directUrl = request.getTransformRequestOptions().getOrDefault(DIRECT_ACCESS_URL, "");
|
|
||||||
if (directUrl.isBlank())
|
|
||||||
{
|
|
||||||
sourceFile = loadSourceFile(request.getSourceReference(), request.getSourceExtension());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sourceFile = getSourceFileFromDirectUrl(directUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (TransformException e)
|
|
||||||
{
|
|
||||||
reply.setStatus(e.getStatusCode());
|
|
||||||
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
|
||||||
logger.trace("Failed to load source file (TransformException), sending " + reply);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
|
||||||
}
|
|
||||||
catch (HttpClientErrorException e)
|
|
||||||
{
|
|
||||||
reply.setStatus(e.getStatusCode().value());
|
|
||||||
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
|
||||||
logger.trace("Failed to load source file (HttpClientErrorException), sending " + reply, e);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
reply.setStatus(INTERNAL_SERVER_ERROR.value());
|
|
||||||
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
|
||||||
logger.trace("Failed to load source file (Exception), sending " + reply, e);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create local temp target file in order to run the transformation
|
InputStream inputStream = getInputStream(request, reply);
|
||||||
final String targetFilename = createTargetFileName(sourceFile.getName(), request.getTargetMediaType(), request.getSourceMediaType());
|
if (inputStream == null)
|
||||||
final File targetFile = buildFile(targetFilename);
|
|
||||||
|
|
||||||
// Run the transformation
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||||
|
}
|
||||||
|
|
||||||
String targetMimetype = request.getTargetMediaType();
|
String targetMimetype = request.getTargetMediaType();
|
||||||
String sourceMimetype = request.getSourceMediaType();
|
String sourceMimetype = request.getSourceMediaType();
|
||||||
|
File targetFile = createTargetFile(null, sourceMimetype, targetMimetype);
|
||||||
|
transformerDebug.pushTransform(request);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OutputStreamLengthRecorder outputStream =
|
||||||
|
new OutputStreamLengthRecorder(new BufferedOutputStream(new FileOutputStream(targetFile)));
|
||||||
|
|
||||||
|
long sourceSizeInBytes = request.getSourceSize();
|
||||||
Map<String, String> transformOptions = getTransformOptions(request.getTransformRequestOptions());
|
Map<String, String> transformOptions = getTransformOptions(request.getTransformRequestOptions());
|
||||||
|
String sourceEncoding = transformOptions.get(SOURCE_ENCODING);
|
||||||
|
String targetEncoding = transformOptions.get(TARGET_ENCODING); // TODO not normally set
|
||||||
transformerDebug.logOptions(request);
|
transformerDebug.logOptions(request);
|
||||||
String transformName = getTransformerName(sourceFile, sourceMimetype, targetMimetype, transformOptions);
|
String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions);
|
||||||
transformImpl(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
CustomTransformer customTransformer = getCustomTransformer(transformName);
|
||||||
reply.getInternalContext().setCurrentSourceSize(targetFile.length());
|
|
||||||
|
TransformManagerImpl transformManager = TransformManagerImpl.builder()
|
||||||
|
.withSourceMimetype(sourceMimetype)
|
||||||
|
.withTargetMimetype(targetMimetype)
|
||||||
|
.withInputStream(inputStream)
|
||||||
|
.withOutputStream(outputStream)
|
||||||
|
.withTargetFile(targetFile)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
customTransformer.transform(sourceMimetype, inputStream,
|
||||||
|
targetMimetype, outputStream, transformOptions, transformManager);
|
||||||
|
|
||||||
|
transformManager.ifUsedCopyTargetFileToOutputStream();
|
||||||
|
|
||||||
|
reply.getInternalContext().setCurrentSourceSize(outputStream.getLength());
|
||||||
|
|
||||||
|
if (saveTargetFileInSharedFileStore(targetFile, reply) == false)
|
||||||
|
{
|
||||||
|
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||||
|
}
|
||||||
|
|
||||||
|
transformManager.deleteSourceFileIfExists();
|
||||||
|
transformManager.deleteTargetFileIfExists();
|
||||||
|
|
||||||
|
probeTestTransform.recordTransformTime(System.currentTimeMillis()-start);
|
||||||
|
transformerDebug.popTransform(reply);
|
||||||
|
|
||||||
|
logger.trace("Sending successful {}, timeout {} ms", reply, timeout);
|
||||||
|
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||||
}
|
}
|
||||||
catch (TransformException e)
|
catch (TransformException e)
|
||||||
{
|
{
|
||||||
@@ -455,65 +440,38 @@ public class TransformController
|
|||||||
logger.trace("Failed to perform transform (Exception), sending " + reply, e);
|
logger.trace("Failed to perform transform (Exception), sending " + reply, e);
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the target file
|
|
||||||
FileRefResponse targetRef;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
targetRef = alfrescoSharedFileStoreClient.saveFile(targetFile);
|
|
||||||
}
|
}
|
||||||
catch (TransformException e)
|
|
||||||
|
private boolean isTransformRequestValid(TransformRequest request, TransformReply reply)
|
||||||
{
|
{
|
||||||
reply.setStatus(e.getStatusCode());
|
final Errors errors = validateTransformRequest(request);
|
||||||
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file", e));
|
validateInternalContext(request, errors);
|
||||||
|
reply.setInternalContext(request.getInternalContext());
|
||||||
|
if (!errors.getAllErrors().isEmpty())
|
||||||
|
{
|
||||||
|
reply.setStatus(BAD_REQUEST.value());
|
||||||
|
reply.setErrorDetails(errors
|
||||||
|
.getAllErrors()
|
||||||
|
.stream()
|
||||||
|
.map(Object::toString)
|
||||||
|
.collect(joining(", ")));
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
transformerDebug.logFailure(reply);
|
||||||
logger.trace("Failed to save target file (TransformException), sending " + reply, e);
|
logger.trace("Invalid request, sending {}", reply);
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
return false;
|
||||||
}
|
}
|
||||||
catch (HttpClientErrorException e)
|
return true;
|
||||||
{
|
|
||||||
reply.setStatus(e.getStatusCode().value());
|
|
||||||
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
|
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
|
||||||
logger.trace("Failed to save target file (HttpClientErrorException), sending " + reply, e);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
reply.setStatus(INTERNAL_SERVER_ERROR.value());
|
|
||||||
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
|
|
||||||
|
|
||||||
transformerDebug.logFailure(reply);
|
|
||||||
logger.trace("Failed to save target file (Exception), sending " + reply, e);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
private TransformReply createBasicTransformReply(TransformRequest request)
|
||||||
{
|
{
|
||||||
deleteFile(targetFile);
|
TransformReply reply = new TransformReply();
|
||||||
}
|
reply.setRequestId(request.getRequestId());
|
||||||
catch (Exception e)
|
reply.setSourceReference(request.getSourceReference());
|
||||||
{
|
reply.setSchema(request.getSchema());
|
||||||
logger.error("Failed to delete local temp target file '{}'. Error will be ignored ",
|
reply.setClientData(request.getClientData());
|
||||||
targetFile, e);
|
reply.setInternalContext(request.getInternalContext());
|
||||||
}
|
return reply;
|
||||||
try
|
|
||||||
{
|
|
||||||
deleteFile(sourceFile);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.error("Failed to delete source local temp file " + sourceFile, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
reply.setTargetReference(targetRef.getEntry().getFileRef());
|
|
||||||
reply.setStatus(CREATED.value());
|
|
||||||
|
|
||||||
transformerDebug.popTransform(reply);
|
|
||||||
logger.trace("Sending successful {}, timeout {} ms", reply, timeout);
|
|
||||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Errors validateTransformRequest(final TransformRequest transformRequest)
|
private Errors validateTransformRequest(final TransformRequest transformRequest)
|
||||||
@@ -530,6 +488,7 @@ public class TransformController
|
|||||||
{
|
{
|
||||||
errors.rejectValue("internalContext", null, errorMessage);
|
errors.rejectValue("internalContext", null, errorMessage);
|
||||||
}
|
}
|
||||||
|
initialiseContext(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialiseContext(TransformRequest request)
|
private void initialiseContext(TransformRequest request)
|
||||||
@@ -538,25 +497,6 @@ public class TransformController
|
|||||||
request.setInternalContext(InternalContext.initialise(request.getInternalContext()));
|
request.setInternalContext(InternalContext.initialise(request.getInternalContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getSourceFileFromDirectUrl(String directUrl)
|
|
||||||
{
|
|
||||||
File sourceFile = createTempFile("tmp", ".tmp");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
FileUtils.copyURLToFile(new URL(directUrl), sourceFile);
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
throw new TransformException(BAD_REQUEST.value(), "Direct Access Url is invalid.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new TransformException(BAD_REQUEST.value(), "Direct Access Url not found.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sourceFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Map<String, String> getTransformOptions(Map<String, String> requestParameters)
|
protected Map<String, String> getTransformOptions(Map<String, String> requestParameters)
|
||||||
{
|
{
|
||||||
Map<String, String> transformOptions = new HashMap<>(requestParameters);
|
Map<String, String> transformOptions = new HashMap<>(requestParameters);
|
||||||
@@ -565,6 +505,108 @@ public class TransformController
|
|||||||
return transformOptions;
|
return transformOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InputStream getSharedFileStoreInputStream(String sourceReference)
|
||||||
|
{
|
||||||
|
ResponseEntity<Resource> responseEntity = alfrescoSharedFileStoreClient.retrieveFile(sourceReference);
|
||||||
|
final Resource body = responseEntity.getBody();
|
||||||
|
if (body == null)
|
||||||
|
{
|
||||||
|
String message = "Source file with reference: " + sourceReference + " is null or empty.";
|
||||||
|
logger.warn(message);
|
||||||
|
throw new TransformException(BAD_REQUEST.value(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return body.getInputStream();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
String message = "Shared File Store reference is invalid.";
|
||||||
|
logger.warn(message);
|
||||||
|
throw new TransformException(BAD_REQUEST.value(), message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getInputStream(TransformRequest request, TransformReply reply)
|
||||||
|
{
|
||||||
|
final String directUrl = request.getTransformRequestOptions().getOrDefault(DIRECT_ACCESS_URL, "");
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inputStream = directUrl.isBlank()
|
||||||
|
? getSharedFileStoreInputStream(request.getSourceReference())
|
||||||
|
: getDirectAccessUrlInputStream(directUrl);
|
||||||
|
}
|
||||||
|
catch (TransformException e)
|
||||||
|
{
|
||||||
|
reply.setStatus(e.getStatusCode());
|
||||||
|
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
||||||
|
|
||||||
|
transformerDebug.logFailure(reply);
|
||||||
|
logger.trace("Failed to load source file (TransformException), sending " + reply);
|
||||||
|
}
|
||||||
|
catch (HttpClientErrorException e)
|
||||||
|
{
|
||||||
|
reply.setStatus(e.getStatusCode().value());
|
||||||
|
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
||||||
|
|
||||||
|
transformerDebug.logFailure(reply);
|
||||||
|
logger.trace("Failed to load source file (HttpClientErrorException), sending " + reply, e);
|
||||||
|
}
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean saveTargetFileInSharedFileStore(File targetFile, TransformReply reply)
|
||||||
|
{
|
||||||
|
FileRefResponse targetRef;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
targetRef = alfrescoSharedFileStoreClient.saveFile(targetFile);
|
||||||
|
}
|
||||||
|
catch (TransformException e)
|
||||||
|
{
|
||||||
|
reply.setStatus(e.getStatusCode());
|
||||||
|
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file", e));
|
||||||
|
|
||||||
|
transformerDebug.logFailure(reply);
|
||||||
|
logger.trace("Failed to save target file (TransformException), sending " + reply, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (HttpClientErrorException e)
|
||||||
|
{
|
||||||
|
reply.setStatus(e.getStatusCode().value());
|
||||||
|
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
|
||||||
|
|
||||||
|
transformerDebug.logFailure(reply);
|
||||||
|
logger.trace("Failed to save target file (HttpClientErrorException), sending " + reply, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
reply.setStatus(INTERNAL_SERVER_ERROR.value());
|
||||||
|
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
|
||||||
|
|
||||||
|
transformerDebug.logFailure(reply);
|
||||||
|
logger.trace("Failed to save target file (Exception), sending " + reply, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
deleteFile(targetFile);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.error("Failed to delete local temp target file. Error will be ignored ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.setTargetReference(targetRef.getEntry().getFileRef());
|
||||||
|
reply.setStatus(CREATED.value());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the file with the specified sourceReference from Alfresco Shared File Store
|
* Loads the file with the specified sourceReference from Alfresco Shared File Store
|
||||||
*
|
*
|
||||||
@@ -574,9 +616,7 @@ public class TransformController
|
|||||||
*/
|
*/
|
||||||
private File loadSourceFile(final String sourceReference, final String sourceExtension)
|
private File loadSourceFile(final String sourceReference, final String sourceExtension)
|
||||||
{
|
{
|
||||||
ResponseEntity<Resource> responseEntity = alfrescoSharedFileStoreClient
|
ResponseEntity<Resource> responseEntity = alfrescoSharedFileStoreClient.retrieveFile(sourceReference);
|
||||||
.retrieveFile(sourceReference);
|
|
||||||
probeTestTransform.incrementTransformerCount();
|
|
||||||
|
|
||||||
HttpHeaders headers = responseEntity.getHeaders();
|
HttpHeaders headers = responseEntity.getHeaders();
|
||||||
String filename = getFilenameFromContentDisposition(headers);
|
String filename = getFilenameFromContentDisposition(headers);
|
||||||
@@ -621,7 +661,7 @@ public class TransformController
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTransformerName(final File sourceFile, final String sourceMimetype,
|
private String getTransformerName(long sourceSizeInBytes, final String sourceMimetype,
|
||||||
final String targetMimetype, final Map<String, String> transformOptions)
|
final String targetMimetype, final Map<String, String> transformOptions)
|
||||||
{
|
{
|
||||||
// The transformOptions always contains sourceEncoding when sent to a T-Engine, even though it should not be
|
// The transformOptions always contains sourceEncoding when sent to a T-Engine, even though it should not be
|
||||||
@@ -630,7 +670,6 @@ public class TransformController
|
|||||||
String sourceEncoding = transformOptions.remove(SOURCE_ENCODING);
|
String sourceEncoding = transformOptions.remove(SOURCE_ENCODING);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
final long sourceSizeInBytes = sourceFile.length();
|
|
||||||
final String transformerName = transformRegistry.findTransformerName(sourceMimetype,
|
final String transformerName = transformRegistry.findTransformerName(sourceMimetype,
|
||||||
sourceSizeInBytes, targetMimetype, transformOptions, null);
|
sourceSizeInBytes, targetMimetype, transformOptions, null);
|
||||||
if (transformerName == null)
|
if (transformerName == null)
|
||||||
@@ -648,6 +687,16 @@ public class TransformController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CustomTransformer getCustomTransformer(String transformName)
|
||||||
|
{
|
||||||
|
CustomTransformer customTransformer = customTransformersByName.get(transformName);
|
||||||
|
if (customTransformer == null)
|
||||||
|
{
|
||||||
|
throw new TransformException(BAD_REQUEST.value(), "Custom Transformer "+customTransformer+" not found");
|
||||||
|
}
|
||||||
|
return customTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
||||||
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
||||||
{
|
{
|
||||||
|
@@ -33,7 +33,8 @@ import org.alfresco.transform.base.probes.ProbeTestTransform;
|
|||||||
/**
|
/**
|
||||||
* Interface to be implemented by transform specific code. Provides information about the t-engine as a whole.
|
* Interface to be implemented by transform specific code. Provides information about the t-engine as a whole.
|
||||||
* Also see {@link CustomTransformer} which provides the code that performs transformation. There may be several
|
* Also see {@link CustomTransformer} which provides the code that performs transformation. There may be several
|
||||||
* in a single t-engine.
|
* in a single t-engine. So that it is automatically picked up, it must exist in a package under
|
||||||
|
* {@code org.alfresco.transform} and have the Spring {@code @Component} annotation.
|
||||||
*/
|
*/
|
||||||
public interface TransformEngine
|
public interface TransformEngine
|
||||||
{
|
{
|
||||||
|
@@ -55,7 +55,6 @@ public class TransformInterceptor extends HandlerInterceptorAdapter
|
|||||||
public void afterCompletion(HttpServletRequest request,
|
public void afterCompletion(HttpServletRequest request,
|
||||||
HttpServletResponse response, Object handler, Exception ex)
|
HttpServletResponse response, Object handler, Exception ex)
|
||||||
{
|
{
|
||||||
// TargetFile cannot be deleted until completion, otherwise 0 bytes are sent.
|
|
||||||
deleteFile(request, SOURCE_FILE);
|
deleteFile(request, SOURCE_FILE);
|
||||||
deleteFile(request, TARGET_FILE);
|
deleteFile(request, TARGET_FILE);
|
||||||
|
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 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.transform.base;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows {@link CustomTransformer} implementations to interact with the base t-engine.
|
||||||
|
*/
|
||||||
|
public interface TransformManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Allows a {@link CustomTransformer} to use a local source {@code File} rather than the supplied {@code InputStream}.
|
||||||
|
* The file will be deleted once the request is completed.
|
||||||
|
* If possible this method should be avoided as it is better not to leave content on disk.
|
||||||
|
* @throws IllegalStateException if this method has already been called.
|
||||||
|
*/
|
||||||
|
File createSourceFile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a {@link CustomTransformer} to use a local target {@code File} rather than the supplied {@code OutputStream}.
|
||||||
|
* The file will be deleted once the request is completed.
|
||||||
|
* If possible this method should be avoided as it is better not to leave content on disk.
|
||||||
|
* @throws IllegalStateException if this method has already been called. A call to {@link #respondWithFragment(Integer)}
|
||||||
|
* allows the method to be called again.
|
||||||
|
*/
|
||||||
|
File createTargetFile();
|
||||||
|
|
||||||
|
// TODO: Do we want to support the following?
|
||||||
|
/**
|
||||||
|
* Allows a single transform request to have multiple transform responses. For example images from a video at
|
||||||
|
* different time offsets or different pages of a document. Following a call to this method a transform response is
|
||||||
|
* made with output that has already been generated. The {@code CustomTransformer} may then use the returned
|
||||||
|
* {@code outputStream} to generate more output for the next transform response.
|
||||||
|
* {@code CustomTransformer} to throw an {@code Exception} when it finds it has no more output.
|
||||||
|
* @param index returned with the response, so that it may be distinguished from other responses. Renditions
|
||||||
|
* use the index as an offset into elements. A {@code null} value indicates that there is no more output
|
||||||
|
* so there should not be another transform reply once the
|
||||||
|
* {@link CustomTransformer#transform(String, InputStream, String, OutputStream, Map, TransformManager)}
|
||||||
|
* returns.
|
||||||
|
* @throws IllegalStateException if a synchronous (http) request has been made as this only works with messages
|
||||||
|
* on queues.
|
||||||
|
*/
|
||||||
|
// This works because all the state is in the TransformResponse and the t-router will just see each response as
|
||||||
|
// something to either return to the client or pass to the next stage in a pipeline. We might be able to enhance
|
||||||
|
// the logging to include the index. We may also wish to modify the client data or just make the index available
|
||||||
|
// in the message.
|
||||||
|
OutputStream respondWithFragment(Integer index);
|
||||||
|
}
|
@@ -0,0 +1,245 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 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.transform.base;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.fs.FileManager;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TransformManagerImpl implements TransformManager
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(TransformManagerImpl.class);
|
||||||
|
|
||||||
|
private HttpServletRequest request;
|
||||||
|
private InputStream inputStream;
|
||||||
|
private OutputStream outputStream;
|
||||||
|
private String sourceMimetype;
|
||||||
|
private String targetMimetype;
|
||||||
|
private File sourceFile;
|
||||||
|
private File targetFile;
|
||||||
|
private boolean createSourceFileCalled;
|
||||||
|
private boolean createTargetFileCalled;
|
||||||
|
private boolean targetFileCreated;
|
||||||
|
|
||||||
|
private TransformManagerImpl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
request = null;
|
||||||
|
inputStream = null;
|
||||||
|
outputStream = null;
|
||||||
|
sourceFile = null;
|
||||||
|
targetFile = null;
|
||||||
|
createSourceFileCalled = false;
|
||||||
|
createTargetFileCalled = false;
|
||||||
|
targetFileCreated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequest(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputStream(InputStream inputStream)
|
||||||
|
{
|
||||||
|
this.inputStream = inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutputStream(OutputStream outputStream)
|
||||||
|
{
|
||||||
|
this.outputStream = outputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceMimetype(String sourceMimetype)
|
||||||
|
{
|
||||||
|
this.sourceMimetype = sourceMimetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetMimetype(String targetMimetype)
|
||||||
|
{
|
||||||
|
this.targetMimetype = targetMimetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getSourceFile()
|
||||||
|
{
|
||||||
|
return sourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceFile(File sourceFile)
|
||||||
|
{
|
||||||
|
this.sourceFile = sourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getTargetFile() {
|
||||||
|
return targetFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTargetFile(File targetFile)
|
||||||
|
{
|
||||||
|
this.targetFile = targetFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreateSourceFileCalled()
|
||||||
|
{
|
||||||
|
return createSourceFileCalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreateTargetFileCalled()
|
||||||
|
{
|
||||||
|
return createTargetFileCalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public File createSourceFile()
|
||||||
|
{
|
||||||
|
if (createSourceFileCalled)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("createSourceFile has already been called");
|
||||||
|
}
|
||||||
|
createSourceFileCalled = true;
|
||||||
|
|
||||||
|
if (sourceFile == null)
|
||||||
|
{
|
||||||
|
sourceFile = FileManager.createSourceFile(request, inputStream, sourceMimetype);
|
||||||
|
}
|
||||||
|
return sourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public File createTargetFile()
|
||||||
|
{
|
||||||
|
if (createTargetFileCalled)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("createTargetFile has already been called");
|
||||||
|
}
|
||||||
|
createTargetFileCalled = true;
|
||||||
|
|
||||||
|
if (targetFile == null)
|
||||||
|
{
|
||||||
|
targetFile = FileManager.createTargetFile(request, sourceMimetype, targetMimetype);
|
||||||
|
targetFileCreated = true;
|
||||||
|
}
|
||||||
|
return targetFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ifUsedCopyTargetFileToOutputStream()
|
||||||
|
{
|
||||||
|
if (targetFileCreated)
|
||||||
|
{
|
||||||
|
FileManager.copyFileToOutputStream(targetFile, outputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteSourceFileIfExists()
|
||||||
|
{
|
||||||
|
if (sourceFile != null && sourceFile.delete() == false)
|
||||||
|
{
|
||||||
|
logger.error("Failed to delete temporary source file "+sourceFile.getPath());
|
||||||
|
}
|
||||||
|
sourceFile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteTargetFileIfExists()
|
||||||
|
{
|
||||||
|
if (targetFile != null && targetFile.delete() == false)
|
||||||
|
{
|
||||||
|
logger.error("Failed to delete temporary target file "+targetFile.getPath());
|
||||||
|
}
|
||||||
|
targetFile = null;
|
||||||
|
targetFileCreated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream respondWithFragment(Integer index)
|
||||||
|
{
|
||||||
|
if (request != null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException(
|
||||||
|
" Fragments may only be sent with asynchronous requests. This a synchronous http request");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnsupportedOperationException("Not currently supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder()
|
||||||
|
{
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder
|
||||||
|
{
|
||||||
|
private final TransformManagerImpl transformManager = new TransformManagerImpl();
|
||||||
|
|
||||||
|
public TransformManagerImpl build()
|
||||||
|
{
|
||||||
|
return transformManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withSourceMimetype(String sourceMimetype)
|
||||||
|
{
|
||||||
|
transformManager.sourceMimetype = sourceMimetype;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withTargetMimetype(String targetMimetype)
|
||||||
|
{
|
||||||
|
transformManager.targetMimetype = targetMimetype;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withInputStream(InputStream inputStream)
|
||||||
|
{
|
||||||
|
transformManager.inputStream = inputStream;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withOutputStream(OutputStream outputStream)
|
||||||
|
{
|
||||||
|
transformManager.outputStream = outputStream;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withRequest(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
transformManager.request = request;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withTargetFile(File targetFile)
|
||||||
|
{
|
||||||
|
transformManager.targetFile = targetFile;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -26,6 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.base.fs;
|
package org.alfresco.transform.base.fs;
|
||||||
|
|
||||||
|
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||||
|
import static org.alfresco.transform.common.ExtensionService.getExtensionForMimetype;
|
||||||
import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION;
|
import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION;
|
||||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
import static org.springframework.http.HttpStatus.INSUFFICIENT_STORAGE;
|
import static org.springframework.http.HttpStatus.INSUFFICIENT_STORAGE;
|
||||||
@@ -35,9 +37,11 @@ import static org.springframework.util.StringUtils.getFilenameExtension;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@@ -58,12 +62,44 @@ public class FileManager
|
|||||||
public static final String TARGET_FILE = "targetFile";
|
public static final String TARGET_FILE = "targetFile";
|
||||||
private static final String FILENAME = "filename=";
|
private static final String FILENAME = "filename=";
|
||||||
|
|
||||||
public static File createTargetFile(HttpServletRequest request, String filename)
|
public static File createSourceFile(HttpServletRequest request, InputStream inputStream, String sourceMimetype)
|
||||||
{
|
{
|
||||||
File file = buildFile(filename);
|
try
|
||||||
request.setAttribute(TARGET_FILE, file);
|
{
|
||||||
|
String extension = "."+getExtensionForMimetype(sourceMimetype);
|
||||||
|
File file = TempFileProvider.createTempFile("source_", extension);
|
||||||
|
Files.copy(inputStream, file.toPath(), REPLACE_EXISTING);
|
||||||
|
if (request != null)
|
||||||
|
{
|
||||||
|
request.setAttribute(SOURCE_FILE, file);
|
||||||
|
}
|
||||||
|
LogEntry.setSource(file.getName(), file.length());
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new TransformException(INSUFFICIENT_STORAGE.value(), "Failed to store the source file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File createTargetFile(HttpServletRequest request, String sourceMimetype, String targetMimetype)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String extension = "."+ExtensionService.getExtensionForTargetMimetype(targetMimetype, sourceMimetype);
|
||||||
|
File file = TempFileProvider.createTempFile("target_", extension);
|
||||||
|
if (request != null)
|
||||||
|
{
|
||||||
|
request.setAttribute(TARGET_FILE, file);
|
||||||
|
}
|
||||||
|
LogEntry.setTarget(file.getName());
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new TransformException(INSUFFICIENT_STORAGE.value(), "Failed to create the target file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static File buildFile(String filename)
|
public static File buildFile(String filename)
|
||||||
{
|
{
|
||||||
@@ -97,8 +133,7 @@ public class FileManager
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Files.copy(multipartFile.getInputStream(), file.toPath(),
|
Files.copy(multipartFile.getInputStream(), file.toPath(), REPLACE_EXISTING);
|
||||||
StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
@@ -111,7 +146,7 @@ public class FileManager
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Files.copy(body.getInputStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(body.getInputStream(), file.toPath(), REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
@@ -176,16 +211,46 @@ public class FileManager
|
|||||||
return sourceFilename.substring(0, sourceFilename.length() - ext.length() - 1) + '.' + targetExtension;
|
return sourceFilename.substring(0, sourceFilename.length() - ext.length() - 1) + '.' + targetExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File createSourceFile(HttpServletRequest request, MultipartFile multipartFile)
|
public static InputStream getMultipartFileInputStream(MultipartFile sourceMultipartFile)
|
||||||
{
|
{
|
||||||
String filename = multipartFile.getOriginalFilename();
|
InputStream inputStream;
|
||||||
long size = multipartFile.getSize();
|
if (sourceMultipartFile == null)
|
||||||
filename = checkFilename(true, filename);
|
{
|
||||||
File file = TempFileProvider.createTempFile("source_", "_" + filename);
|
throw new TransformException(BAD_REQUEST.value(), "Required request part 'file' is not present");
|
||||||
request.setAttribute(SOURCE_FILE, file);
|
}
|
||||||
save(multipartFile, file);
|
try
|
||||||
LogEntry.setSource(filename, size);
|
{
|
||||||
return file;
|
inputStream = sourceMultipartFile.getInputStream();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new TransformException(BAD_REQUEST.value(), "Unable to read the sourceMultipartFile.", e);
|
||||||
|
}
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream getDirectAccessUrlInputStream(String directUrl)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new URL(directUrl).openStream();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new TransformException(BAD_REQUEST.value(), "Direct Access Url is invalid.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copyFileToOutputStream(File targetFile, OutputStream outputStream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Files.copy(targetFile.toPath(), outputStream);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new TransformException(INTERNAL_SERVER_ERROR.value(), "Failed to copy targetFile to outputStream.", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
@@ -30,7 +30,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.CustomTransformer;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -51,7 +51,7 @@ import java.util.Set;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import static org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor.Type.EXTRACTOR;
|
import static org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor.Type.EMBEDDER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper methods for metadata extract and embed.
|
* Helper methods for metadata extract and embed.
|
||||||
@@ -151,16 +151,30 @@ public abstract class AbstractMetadataExtractor implements CustomTransformer
|
|||||||
return getClass().getSimpleName();
|
return getClass().getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Map<String, Serializable> extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
@Override
|
||||||
File sourceFile) throws Exception;
|
public void transform(String sourceMimetype, InputStream inputStream,
|
||||||
|
String targetMimetype, OutputStream outputStream,
|
||||||
public void embedMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
Map<String, String> transformOptions, TransformManager transformManager) throws Exception
|
||||||
String sourceEncoding, InputStream inputStream,
|
|
||||||
String targetEncoding, OutputStream outputStream) throws Exception
|
|
||||||
{
|
{
|
||||||
// TODO
|
if (type == EMBEDDER)
|
||||||
throw new TransformException(500, "TODO embedMetadata");
|
{
|
||||||
|
embedMetadata(sourceMimetype, inputStream, targetMimetype, outputStream, transformOptions, transformManager);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extractMetadata(sourceMimetype, inputStream, targetMimetype, outputStream, transformOptions, transformManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void embedMetadata(String sourceMimetype, InputStream inputStream,
|
||||||
|
String targetMimetype, OutputStream outputStream,
|
||||||
|
Map<String, String> transformOptions, TransformManager transformManager) throws Exception
|
||||||
|
{
|
||||||
|
File sourceFile = transformManager.createSourceFile();
|
||||||
|
File targetFile = transformManager.createTargetFile();
|
||||||
|
embedMetadata(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
||||||
|
}
|
||||||
|
|
||||||
public void embedMetadata(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
public void embedMetadata(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
File sourceFile, File targetFile) throws Exception
|
File sourceFile, File targetFile) throws Exception
|
||||||
{
|
{
|
||||||
@@ -493,27 +507,13 @@ public abstract class AbstractMetadataExtractor implements CustomTransformer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void extractMetadata(String sourceMimetype, InputStream inputStream,
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
String targetMimetype, OutputStream outputStream,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
Map<String, String> transformOptions, TransformManager transformManager) throws Exception
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
{
|
||||||
if (type == EXTRACTOR)
|
File sourceFile = transformManager.createSourceFile();
|
||||||
{
|
File targetFile = transformManager.createTargetFile();
|
||||||
extractMetadata(sourceMimetype, transformOptions, sourceEncoding, inputStream, targetEncoding, outputStream);
|
extractMetadata(sourceMimetype, transformOptions, sourceFile, targetFile);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
embedMetadata(sourceMimetype, transformOptions, sourceEncoding, inputStream, targetEncoding, outputStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
|
||||||
String sourceEncoding, InputStream inputStream,
|
|
||||||
String targetEncoding, OutputStream outputStream) throws Exception
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
throw new TransformException(500, "TODO extractMetadata");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -539,6 +539,9 @@ public abstract class AbstractMetadataExtractor implements CustomTransformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract Map<String, Serializable> extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
||||||
|
File sourceFile) throws Exception;
|
||||||
|
|
||||||
private Map<String, Set<String>> getExtractMappingFromOptions(Map<String, String> transformOptions, Map<String,
|
private Map<String, Set<String>> getExtractMappingFromOptions(Map<String, String> transformOptions, Map<String,
|
||||||
Set<String>> defaultExtractMapping)
|
Set<String>> defaultExtractMapping)
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 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.transform.base.util;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.CustomTransformer;
|
||||||
|
import org.alfresco.transform.base.TransformManager;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper interface for older code that uses Files rather than InputStreams and OutputStreams.
|
||||||
|
* If you, can refactor your code to NOT use Files.
|
||||||
|
*/
|
||||||
|
public interface CustomTransformerFileAdaptor extends CustomTransformer
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
default void transform(String sourceMimetype, InputStream inputStream,
|
||||||
|
String targetMimetype, OutputStream outputStream,
|
||||||
|
Map<String, String> transformOptions, TransformManager transformManager) throws Exception
|
||||||
|
{
|
||||||
|
File sourceFile = transformManager.createSourceFile();
|
||||||
|
File targetFile = transformManager.createTargetFile();
|
||||||
|
transform(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
|
File sourceFile, File targetFile) throws Exception;
|
||||||
|
}
|
@@ -24,15 +24,35 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform;
|
package org.alfresco.transform.base.util;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.FilterOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public interface CustomTransformer
|
public class OutputStreamLengthRecorder extends FilterOutputStream
|
||||||
{
|
{
|
||||||
void transform(String transformerName, String sourceMimetype, String targetMimetype,
|
private long byteCount;
|
||||||
Map<String, String> transformOptions,
|
|
||||||
InputStream inputStream, OutputStream outputStream) throws Exception;
|
public OutputStreamLengthRecorder(OutputStream outputStream)
|
||||||
|
{
|
||||||
|
super(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLength()
|
||||||
|
{
|
||||||
|
return byteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int b) throws IOException
|
||||||
|
{
|
||||||
|
super.write(b);
|
||||||
|
byteCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte b[], int off, int len) throws IOException
|
||||||
|
{
|
||||||
|
super.write(b, off, len);
|
||||||
|
byteCount += len;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -26,6 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.base.util;
|
package org.alfresco.transform.base.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class Util
|
public class Util
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@@ -26,11 +26,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.imagemagick.transformers;
|
package org.alfresco.transform.imagemagick.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.base.executors.AbstractCommandExecutor;
|
import org.alfresco.transform.base.executors.AbstractCommandExecutor;
|
||||||
import org.alfresco.transform.base.executors.RuntimeExec;
|
import org.alfresco.transform.base.executors.RuntimeExec;
|
||||||
import org.alfresco.transform.imagemagick.ImageMagickOptionsBuilder;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
|
import org.alfresco.transform.imagemagick.ImageMagickOptionsBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ import static org.alfresco.transform.common.RequestParamMap.THUMBNAIL;
|
|||||||
import static org.alfresco.transform.common.RequestParamMap.TIMEOUT;
|
import static org.alfresco.transform.common.RequestParamMap.TIMEOUT;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ImageMagickTransformer extends AbstractCommandExecutor implements CustomTransformer
|
public class ImageMagickTransformer extends AbstractCommandExecutor implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
@Value("${transform.core.imagemagick.exe}")
|
@Value("${transform.core.imagemagick.exe}")
|
||||||
private String exe;
|
private String exe;
|
||||||
@@ -150,14 +151,7 @@ public class ImageMagickTransformer extends AbstractCommandExecutor implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
public void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO ImageMagick transform");
|
|
||||||
}
|
|
||||||
public void transform(String transformName, String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> transformOptions,
|
|
||||||
File sourceFile, File targetFile) throws TransformException
|
File sourceFile, File targetFile) throws TransformException
|
||||||
{
|
{
|
||||||
final String options = ImageMagickOptionsBuilder
|
final String options = ImageMagickOptionsBuilder
|
||||||
|
@@ -28,7 +28,8 @@ package org.alfresco.transform.libreoffice.transformers;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.sun.star.task.ErrorCodeIOException;
|
import com.sun.star.task.ErrorCodeIOException;
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
@@ -58,7 +59,7 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
|
|||||||
* transformation logic in the same JVM (check the {@link JodConverter} implementation).
|
* transformation logic in the same JVM (check the {@link JodConverter} implementation).
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class LibreOfficeTransformer implements CustomTransformer
|
public class LibreOfficeTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeTransformer.class);
|
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeTransformer.class);
|
||||||
|
|
||||||
@@ -130,20 +131,8 @@ public class LibreOfficeTransformer implements CustomTransformer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
public void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO LibreOffice transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(String transformName, String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
|
||||||
File sourceFile, File targetFile)
|
File sourceFile, File targetFile)
|
||||||
{
|
|
||||||
call(sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void call(File sourceFile, File targetFile, String... args)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
package org.alfresco.transform.misc.metadataExtractors;
|
package org.alfresco.transform.misc.metadataExtractors;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.CustomTransformer;
|
||||||
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
|
import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -85,19 +86,6 @@ public class HtmlMetadataExtractor extends AbstractMetadataExtractor implements
|
|||||||
return getClass().getSimpleName();
|
return getClass().getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO HtmlMetadataExtractor transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extractMetadata(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
|
||||||
File sourceFile, File targetFile) throws Exception
|
|
||||||
{
|
|
||||||
extractMetadata(sourceMimetype, transformOptions, sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Serializable> extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
public Map<String, Serializable> extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
||||||
File sourceFile) throws Exception
|
File sourceFile) throws Exception
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
package org.alfresco.transform.misc.metadataExtractors;
|
package org.alfresco.transform.misc.metadataExtractors;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.CustomTransformer;
|
||||||
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
|
import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -87,19 +88,6 @@ public class RFC822MetadataExtractor extends AbstractMetadataExtractor implement
|
|||||||
super(EXTRACTOR, logger);
|
super(EXTRACTOR, logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO RFC822MetadataExtractor transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extractMetadata(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
|
||||||
File sourceFile, File targetFile) throws Exception
|
|
||||||
{
|
|
||||||
extractMetadata(sourceMimetype, transformOptions, sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Serializable> extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
public Map<String, Serializable> extractMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
||||||
File sourceFile) throws Exception
|
File sourceFile) throws Exception
|
||||||
|
@@ -27,8 +27,8 @@
|
|||||||
package org.alfresco.transform.misc.transformers;
|
package org.alfresco.transform.misc.transformers;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
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;
|
||||||
@@ -64,7 +64,7 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_JPEG;
|
|||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class AppleIWorksContentTransformer implements CustomTransformer
|
public class AppleIWorksContentTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(
|
private static final Logger logger = LoggerFactory.getLogger(
|
||||||
AppleIWorksContentTransformer.class);
|
AppleIWorksContentTransformer.class);
|
||||||
@@ -84,15 +84,9 @@ public class AppleIWorksContentTransformer implements CustomTransformer
|
|||||||
return "appleIWorks";
|
return "appleIWorks";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
@Override
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
public void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
Map<String, String> transformOptions) throws Exception
|
File sourceFile, File targetFile)
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO appleIWorks transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
|
||||||
final File sourceFile, final File targetFile)
|
|
||||||
{
|
{
|
||||||
logger.debug("Performing IWorks to jpeg transform with sourceMimetype={} targetMimetype={}",
|
logger.debug("Performing IWorks to jpeg transform with sourceMimetype={} targetMimetype={}",
|
||||||
sourceMimetype, targetMimetype);
|
sourceMimetype, targetMimetype);
|
||||||
|
@@ -26,9 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.misc.transformers;
|
package org.alfresco.transform.misc.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.base.fs.FileManager;
|
import org.alfresco.transform.base.fs.FileManager;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -69,7 +69,7 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class EMLTransformer implements CustomTransformer
|
public class EMLTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(EMLTransformer.class);
|
private static final Logger logger = LoggerFactory.getLogger(EMLTransformer.class);
|
||||||
|
|
||||||
@@ -82,15 +82,9 @@ public class EMLTransformer implements CustomTransformer
|
|||||||
return "rfc822";
|
return "rfc822";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
@Override
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
public void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
Map<String, String> transformOptions) throws Exception
|
File sourceFile, File targetFile) throws Exception
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO rfc822 transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
|
||||||
final File sourceFile, final File targetFile) throws Exception
|
|
||||||
{
|
{
|
||||||
logger.debug("Performing RFC822 to text transform.");
|
logger.debug("Performing RFC822 to text transform.");
|
||||||
// Use try with resource
|
// Use try with resource
|
||||||
|
@@ -26,8 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.misc.transformers;
|
package org.alfresco.transform.misc.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
|
||||||
import org.htmlparser.Parser;
|
import org.htmlparser.Parser;
|
||||||
import org.htmlparser.beans.StringBean;
|
import org.htmlparser.beans.StringBean;
|
||||||
import org.htmlparser.util.ParserException;
|
import org.htmlparser.util.ParserException;
|
||||||
@@ -38,8 +37,6 @@ import org.springframework.stereotype.Component;
|
|||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
@@ -77,7 +74,7 @@ import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING;
|
|||||||
* @see <a href="http://sourceforge.net/tracker/?func=detail&aid=1644504&group_id=24399&atid=381401">HTML Parser</a>
|
* @see <a href="http://sourceforge.net/tracker/?func=detail&aid=1644504&group_id=24399&atid=381401">HTML Parser</a>
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class HtmlParserContentTransformer implements CustomTransformer
|
public class HtmlParserContentTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(
|
private static final Logger logger = LoggerFactory.getLogger(
|
||||||
HtmlParserContentTransformer.class);
|
HtmlParserContentTransformer.class);
|
||||||
@@ -89,17 +86,11 @@ public class HtmlParserContentTransformer implements CustomTransformer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
public void transform(final String sourceMimetype, final String targetMimetype,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
final Map<String, String> transformOptions,
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO html transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
|
||||||
final File sourceFile, final File targetFile) throws Exception
|
final File sourceFile, final File targetFile) throws Exception
|
||||||
{
|
{
|
||||||
String sourceEncoding = parameters.get(SOURCE_ENCODING);
|
String sourceEncoding = transformOptions.get(SOURCE_ENCODING);
|
||||||
checkEncodingParameter(sourceEncoding, SOURCE_ENCODING);
|
checkEncodingParameter(sourceEncoding, SOURCE_ENCODING);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.misc.transformers;
|
package org.alfresco.transform.misc.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
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;
|
||||||
@@ -58,7 +58,7 @@ import java.util.Map;
|
|||||||
* @author eknizat
|
* @author eknizat
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class OOXMLThumbnailContentTransformer implements CustomTransformer
|
public class OOXMLThumbnailContentTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(
|
private static final Logger logger = LoggerFactory.getLogger(
|
||||||
OOXMLThumbnailContentTransformer.class);
|
OOXMLThumbnailContentTransformer.class);
|
||||||
@@ -69,13 +69,6 @@ public class OOXMLThumbnailContentTransformer implements CustomTransformer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO ooXmlThumbnail transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
||||||
final File sourceFile, final File targetFile) throws Exception
|
final File sourceFile, final File targetFile) throws Exception
|
||||||
{
|
{
|
||||||
|
@@ -26,8 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.misc.transformers;
|
package org.alfresco.transform.misc.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -37,9 +36,7 @@ import java.io.BufferedWriter;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
@@ -64,7 +61,7 @@ import static org.alfresco.transform.common.RequestParamMap.TARGET_ENCODING;
|
|||||||
* @author eknizat
|
* @author eknizat
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class StringExtractingContentTransformer implements CustomTransformer
|
public class StringExtractingContentTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(StringExtractingContentTransformer.class);
|
private static final Logger logger = LoggerFactory.getLogger(StringExtractingContentTransformer.class);
|
||||||
|
|
||||||
@@ -82,18 +79,11 @@ public class StringExtractingContentTransformer implements CustomTransformer
|
|||||||
* be unformatted but valid.
|
* be unformatted but valid.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> transformOptions,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO string transform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
|
||||||
final File sourceFile, final File targetFile) throws Exception
|
final File sourceFile, final File targetFile) throws Exception
|
||||||
{
|
{
|
||||||
String sourceEncoding = parameters.get(SOURCE_ENCODING);
|
String sourceEncoding = transformOptions.get(SOURCE_ENCODING);
|
||||||
String targetEncoding = parameters.get(TARGET_ENCODING);
|
String targetEncoding = transformOptions.get(TARGET_ENCODING);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.misc.transformers;
|
package org.alfresco.transform.misc.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
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;
|
||||||
@@ -66,7 +66,7 @@ import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING;
|
|||||||
* @author eknizat
|
* @author eknizat
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class TextToPdfContentTransformer implements CustomTransformer
|
public class TextToPdfContentTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TextToPdfContentTransformer.class);
|
private static final Logger logger = LoggerFactory.getLogger(TextToPdfContentTransformer.class);
|
||||||
|
|
||||||
@@ -113,17 +113,13 @@ public class TextToPdfContentTransformer implements CustomTransformer
|
|||||||
return "textToPdf";
|
return "textToPdf";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
@Override
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String,
|
||||||
Map<String, String> transformOptions) throws Exception
|
String> transformOptions,
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO textToPdf transform");
|
|
||||||
}
|
|
||||||
public void transform(final String sourceMimetype, final String targetMimetype, final Map<String, String> parameters,
|
|
||||||
final File sourceFile, final File targetFile) throws Exception
|
final File sourceFile, final File targetFile) throws Exception
|
||||||
{
|
{
|
||||||
String sourceEncoding = parameters.get(SOURCE_ENCODING);
|
String sourceEncoding = transformOptions.get(SOURCE_ENCODING);
|
||||||
String stringPageLimit = parameters.get(PAGE_LIMIT);
|
String stringPageLimit = transformOptions.get(PAGE_LIMIT);
|
||||||
int pageLimit = -1;
|
int pageLimit = -1;
|
||||||
if (stringPageLimit != null)
|
if (stringPageLimit != null)
|
||||||
{
|
{
|
||||||
|
@@ -26,9 +26,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.pdfrenderer.transformers;
|
package org.alfresco.transform.pdfrenderer.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.base.executors.AbstractCommandExecutor;
|
import org.alfresco.transform.base.executors.AbstractCommandExecutor;
|
||||||
import org.alfresco.transform.base.executors.RuntimeExec;
|
import org.alfresco.transform.base.executors.RuntimeExec;
|
||||||
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
import org.alfresco.transform.pdfrenderer.PdfRendererOptionsBuilder;
|
import org.alfresco.transform.pdfrenderer.PdfRendererOptionsBuilder;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -54,7 +55,7 @@ import static org.alfresco.transform.common.RequestParamMap.WIDTH_REQUEST_PARAM;
|
|||||||
* transformation logic as a separate Shell process.
|
* transformation logic as a separate Shell process.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class PdfRendererTransformer extends AbstractCommandExecutor implements CustomTransformer
|
public class PdfRendererTransformer extends AbstractCommandExecutor implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
@Value("${transform.core.pdfrenderer.exe}")
|
@Value("${transform.core.pdfrenderer.exe}")
|
||||||
private String exe;
|
private String exe;
|
||||||
@@ -103,14 +104,7 @@ public class PdfRendererTransformer extends AbstractCommandExecutor implements C
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
public void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
throw new TransformException(500, "TODO PdfRenderer transform");
|
|
||||||
}
|
|
||||||
public void transform(String transformName, String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> transformOptions,
|
|
||||||
File sourceFile, File targetFile) throws TransformException
|
File sourceFile, File targetFile) throws TransformException
|
||||||
{
|
{
|
||||||
final String options = PdfRendererOptionsBuilder
|
final String options = PdfRendererOptionsBuilder
|
||||||
|
@@ -26,9 +26,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.tika.metadataExtractors;
|
package org.alfresco.transform.tika.metadataExtractors;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
import org.alfresco.transform.base.TransformManager;
|
||||||
import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
|
import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
|
||||||
import org.alfresco.transform.common.TransformException;
|
|
||||||
import org.apache.tika.embedder.Embedder;
|
import org.apache.tika.embedder.Embedder;
|
||||||
import org.apache.tika.extractor.DocumentSelector;
|
import org.apache.tika.extractor.DocumentSelector;
|
||||||
import org.apache.tika.metadata.DublinCore;
|
import org.apache.tika.metadata.DublinCore;
|
||||||
@@ -54,7 +53,6 @@ import org.xml.sax.Locator;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -84,7 +82,7 @@ import java.util.stream.Stream;
|
|||||||
* @author Nick Burch
|
* @author Nick Burch
|
||||||
* @author adavis
|
* @author adavis
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractTikaMetadataExtractor extends AbstractMetadataExtractor implements CustomTransformer
|
public abstract class AbstractTikaMetadataExtractor extends AbstractMetadataExtractor
|
||||||
{
|
{
|
||||||
protected static final String KEY_AUTHOR = "author";
|
protected static final String KEY_AUTHOR = "author";
|
||||||
protected static final String KEY_TITLE = "title";
|
protected static final String KEY_TITLE = "title";
|
||||||
@@ -310,22 +308,15 @@ public abstract class AbstractTikaMetadataExtractor extends AbstractMetadataExtr
|
|||||||
return rawProperties;
|
return rawProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void embedMetadata(String sourceMimetype, Map<String, String> transformOptions,
|
|
||||||
String sourceEncoding, InputStream inputStream,
|
|
||||||
String targetEncoding, OutputStream outputStream) throws Exception
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
throw new TransformException(500, "TODO embedMetadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated The content repository's TikaPoweredMetadataExtracter provides no non test implementations.
|
* @deprecated The content repository's TikaPoweredMetadataExtracter provides no non test implementations.
|
||||||
* This code exists in case there are custom implementations, that need to be converted to T-Engines.
|
* This code exists in case there are custom implementations, that need to be converted to T-Engines.
|
||||||
* It is simply a copy and paste from the content repository and has received limited testing.
|
* It is simply a copy and paste from the content repository and has received limited testing.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void embedMetadata(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
public void embedMetadata(String sourceMimetype, InputStream inputStream,
|
||||||
File sourceFile, File targetFile) throws Exception
|
String targetMimetype, OutputStream outputStream,
|
||||||
|
Map<String, String> transformOptions, TransformManager transformManager) throws Exception
|
||||||
{
|
{
|
||||||
Embedder embedder = getEmbedder();
|
Embedder embedder = getEmbedder();
|
||||||
if (embedder == null)
|
if (embedder == null)
|
||||||
@@ -334,13 +325,8 @@ public abstract class AbstractTikaMetadataExtractor extends AbstractMetadataExtr
|
|||||||
}
|
}
|
||||||
|
|
||||||
Metadata metadataToEmbed = getTikaMetadata(transformOptions);
|
Metadata metadataToEmbed = getTikaMetadata(transformOptions);
|
||||||
|
|
||||||
try (InputStream inputStream = new FileInputStream(sourceFile);
|
|
||||||
OutputStream outputStream = new FileOutputStream(targetFile))
|
|
||||||
{
|
|
||||||
embedder.embed(metadataToEmbed, inputStream, outputStream, null);
|
embedder.embed(metadataToEmbed, inputStream, outputStream, null);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Metadata getTikaMetadata(Map<String, String> transformOptions)
|
private Metadata getTikaMetadata(Map<String, String> transformOptions)
|
||||||
{
|
{
|
||||||
|
@@ -26,10 +26,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.tika.transformers;
|
package org.alfresco.transform.tika.transformers;
|
||||||
|
|
||||||
import org.alfresco.transform.base.CustomTransformer;
|
|
||||||
import org.alfresco.transform.base.logging.LogEntry;
|
import org.alfresco.transform.base.logging.LogEntry;
|
||||||
|
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
|
||||||
import org.alfresco.transform.common.RequestParamMap;
|
import org.alfresco.transform.common.RequestParamMap;
|
||||||
import org.alfresco.transform.common.TransformException;
|
|
||||||
import org.apache.tika.extractor.DocumentSelector;
|
import org.apache.tika.extractor.DocumentSelector;
|
||||||
import org.apache.tika.parser.Parser;
|
import org.apache.tika.parser.Parser;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -38,21 +37,18 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
|
|
||||||
public abstract class GenericTikaTransformer implements CustomTransformer
|
public abstract class GenericTikaTransformer implements CustomTransformerFileAdaptor
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(GenericTikaTransformer.class);
|
private static final Logger logger = LoggerFactory.getLogger(GenericTikaTransformer.class);
|
||||||
|
|
||||||
@Value("${transform.core.tika.pdfBox.notExtractBookmarksTextDefault:false}")
|
@Value("${transform.core.tika.pdfBox.notExtractBookmarksTextDefault:false}")
|
||||||
boolean notExtractBookmarksTextDefault;
|
boolean notExtractBookmarksTextDefault;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected Tika tika;
|
protected Tika tika;
|
||||||
|
|
||||||
@@ -71,15 +67,7 @@ public abstract class GenericTikaTransformer implements CustomTransformer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
public void transform(String sourceMimetype, String targetMimetype,
|
||||||
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
|
||||||
Map<String, String> transformOptions) throws Exception
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
throw new TransformException(500, "TODO GenericTikaTransformer transform with InputStreams");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void transform(String transformName, String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
@@ -92,7 +80,8 @@ public abstract class GenericTikaTransformer implements CustomTransformer
|
|||||||
{
|
{
|
||||||
logger.trace("notExtractBookmarksText default value has been overridden to {}", notExtractBookmarksTextDefault);
|
logger.trace("notExtractBookmarksText default value has been overridden to {}", notExtractBookmarksTextDefault);
|
||||||
}
|
}
|
||||||
call(sourceFile, targetFile, transformName,
|
String transformerName = getTransformerName();
|
||||||
|
call(sourceFile, targetFile, transformerName,
|
||||||
includeContents ? Tika.INCLUDE_CONTENTS : null,
|
includeContents ? Tika.INCLUDE_CONTENTS : null,
|
||||||
notExtractBookmarksText ? Tika.NOT_EXTRACT_BOOKMARKS_TEXT : null,
|
notExtractBookmarksText ? Tika.NOT_EXTRACT_BOOKMARKS_TEXT : null,
|
||||||
Tika.TARGET_MIMETYPE + targetMimetype, Tika.TARGET_ENCODING + targetEncoding);
|
Tika.TARGET_MIMETYPE + targetMimetype, Tika.TARGET_ENCODING + targetEncoding);
|
||||||
|
@@ -49,7 +49,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class GenericTikaTransformerTest
|
public class GenericTikaTransformerTest
|
||||||
{
|
{
|
||||||
private class TikaTestTransformer extends GenericTikaTransformer
|
private static class TikaTestTransformer extends GenericTikaTransformer
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected Parser getParser()
|
protected Parser getParser()
|
||||||
@@ -61,7 +61,7 @@ public class GenericTikaTransformerTest
|
|||||||
{
|
{
|
||||||
this.notExtractBookmarksTextDefault = notExtractBookmarksTextDefault;
|
this.notExtractBookmarksTextDefault = notExtractBookmarksTextDefault;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotExtractBookmarkTextDefault() throws Exception
|
public void testNotExtractBookmarkTextDefault() throws Exception
|
||||||
@@ -83,9 +83,9 @@ public class GenericTikaTransformerTest
|
|||||||
Map<String, String> transformOptions = new HashMap<>();
|
Map<String, String> transformOptions = new HashMap<>();
|
||||||
|
|
||||||
// use empty transformOptions to test defaults
|
// use empty transformOptions to test defaults
|
||||||
executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions,
|
executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions,
|
||||||
mockSourceFile, mockTargetFile);
|
mockSourceFile, mockTargetFile);
|
||||||
executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions,
|
executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions,
|
||||||
mockSourceFile, mockTargetFile);
|
mockSourceFile, mockTargetFile);
|
||||||
|
|
||||||
// when default set to true, with no options passed we should get a call method with NOT_EXTRACT_BOOKMARKS_TEXT
|
// when default set to true, with no options passed we should get a call method with NOT_EXTRACT_BOOKMARKS_TEXT
|
||||||
@@ -99,9 +99,9 @@ public class GenericTikaTransformerTest
|
|||||||
// use transforms with notExtractBookmarksText set to true
|
// use transforms with notExtractBookmarksText set to true
|
||||||
clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse);
|
clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse);
|
||||||
transformOptions.put("notExtractBookmarksText", "true");
|
transformOptions.put("notExtractBookmarksText", "true");
|
||||||
executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions,
|
executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions,
|
||||||
mockSourceFile, mockTargetFile);
|
mockSourceFile, mockTargetFile);
|
||||||
executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions,
|
executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions,
|
||||||
mockSourceFile, mockTargetFile);
|
mockSourceFile, mockTargetFile);
|
||||||
|
|
||||||
// both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT
|
// both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT
|
||||||
@@ -114,8 +114,8 @@ public class GenericTikaTransformerTest
|
|||||||
// use transforms with notExtractBookmarksText set to false
|
// use transforms with notExtractBookmarksText set to false
|
||||||
clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse);
|
clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse);
|
||||||
transformOptions.replace("notExtractBookmarksText", "true", "false");
|
transformOptions.replace("notExtractBookmarksText", "true", "false");
|
||||||
executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
||||||
executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
||||||
|
|
||||||
// both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT
|
// both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT
|
||||||
verify(executorSpyDefaultTrue, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null,
|
verify(executorSpyDefaultTrue, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null,
|
||||||
@@ -124,11 +124,11 @@ public class GenericTikaTransformerTest
|
|||||||
verify(executorSpyDefaultFalse, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null,
|
verify(executorSpyDefaultFalse, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null,
|
||||||
TARGET_MIMETYPE + targetMimetype, TARGET_ENCODING + defaultEncoding);
|
TARGET_MIMETYPE + targetMimetype, TARGET_ENCODING + defaultEncoding);
|
||||||
|
|
||||||
// use full set of pdfbox transformOptions just to be safe
|
// useful set of pdfbox transformOptions just to be safe
|
||||||
clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse);
|
clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse);
|
||||||
transformOptions.put("targetEncoding", "anyEncoding");
|
transformOptions.put("targetEncoding", "anyEncoding");
|
||||||
executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
||||||
executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile);
|
||||||
|
|
||||||
// both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT but the encoding will change
|
// both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT but the encoding will change
|
||||||
verify(executorSpyDefaultTrue, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null,
|
verify(executorSpyDefaultTrue, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null,
|
||||||
|
@@ -79,10 +79,15 @@ public class TransformerDebug
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pushTransform(String reference, String sourceMimetype, String targetMimetype, File sourceFile, String transformerName)
|
public void pushTransform(String reference, String sourceMimetype, String targetMimetype, File sourceFile, String transformerName)
|
||||||
|
{
|
||||||
|
final long sourceSizeInBytes = sourceFile.length();
|
||||||
|
pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pushTransform(String reference, String sourceMimetype, String targetMimetype, long sourceSizeInBytes, String transformerName)
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
final long sourceSizeInBytes = sourceFile.length();
|
|
||||||
String message = getPaddedReference(reference) +
|
String message = getPaddedReference(reference) +
|
||||||
getMimetypeExt(sourceMimetype) +
|
getMimetypeExt(sourceMimetype) +
|
||||||
getTargetMimetypeExt(targetMimetype, sourceMimetype) + ' ' +
|
getTargetMimetypeExt(targetMimetype, sourceMimetype) + ' ' +
|
||||||
|
@@ -74,19 +74,19 @@ public class TransformCache
|
|||||||
return transforms;
|
return transforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cache(final String transformerName, final String sourceMimetype,
|
public void cache(final String renditionName, final String sourceMimetype,
|
||||||
final List<SupportedTransform> transformListBySize)
|
final List<SupportedTransform> transformListBySize)
|
||||||
{
|
{
|
||||||
cachedSupportedTransformList
|
cachedSupportedTransformList
|
||||||
.get(transformerName)
|
.get(renditionName)
|
||||||
.put(sourceMimetype, transformListBySize);
|
.put(sourceMimetype, transformListBySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SupportedTransform> retrieveCached(final String transformerName,
|
public List<SupportedTransform> retrieveCached(final String renditionName,
|
||||||
final String sourceMimetype)
|
final String sourceMimetype)
|
||||||
{
|
{
|
||||||
return cachedSupportedTransformList
|
return cachedSupportedTransformList
|
||||||
.computeIfAbsent(transformerName, k -> new ConcurrentHashMap<>())
|
.computeIfAbsent(renditionName, k -> new ConcurrentHashMap<>())
|
||||||
.get(sourceMimetype);
|
.get(sourceMimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -75,20 +75,20 @@ class TransformRegistryHelper
|
|||||||
// been discarded.
|
// been discarded.
|
||||||
static List<SupportedTransform> retrieveTransformListBySize(final TransformCache data,
|
static List<SupportedTransform> retrieveTransformListBySize(final TransformCache data,
|
||||||
final String sourceMimetype, final String targetMimetype,
|
final String sourceMimetype, final String targetMimetype,
|
||||||
Map<String, String> actualOptions, String transformerName)
|
Map<String, String> actualOptions, String renditionName)
|
||||||
{
|
{
|
||||||
if (actualOptions == null)
|
if (actualOptions == null)
|
||||||
{
|
{
|
||||||
actualOptions = emptyMap();
|
actualOptions = emptyMap();
|
||||||
}
|
}
|
||||||
if (transformerName != null && transformerName.trim().isEmpty())
|
if (renditionName != null && renditionName.trim().isEmpty())
|
||||||
{
|
{
|
||||||
transformerName = null;
|
renditionName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<SupportedTransform> cachedTransformList =
|
final List<SupportedTransform> cachedTransformList =
|
||||||
transformerName == null ? null :
|
renditionName == null ? null :
|
||||||
data.retrieveCached(transformerName, sourceMimetype);
|
data.retrieveCached(renditionName, sourceMimetype);
|
||||||
if (cachedTransformList != null)
|
if (cachedTransformList != null)
|
||||||
{
|
{
|
||||||
return cachedTransformList;
|
return cachedTransformList;
|
||||||
@@ -99,9 +99,9 @@ class TransformRegistryHelper
|
|||||||
targetMimetype,
|
targetMimetype,
|
||||||
filterTimeout(actualOptions));
|
filterTimeout(actualOptions));
|
||||||
|
|
||||||
if (transformerName != null)
|
if (renditionName != null)
|
||||||
{
|
{
|
||||||
data.cache(transformerName, sourceMimetype, builtTransformList);
|
data.cache(renditionName, sourceMimetype, builtTransformList);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builtTransformList;
|
return builtTransformList;
|
||||||
@@ -111,7 +111,6 @@ class TransformRegistryHelper
|
|||||||
final TransformCache data, final String sourceMimetype, final String targetMimetype,
|
final TransformCache data, final String sourceMimetype, final String targetMimetype,
|
||||||
final Map<String, String> actualOptions)
|
final Map<String, String> actualOptions)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (sourceMimetype == null)
|
if (sourceMimetype == null)
|
||||||
{
|
{
|
||||||
throw new TransformException(400, "Null value provided for sourceMimetype, please provide a value");
|
throw new TransformException(400, "Null value provided for sourceMimetype, please provide a value");
|
||||||
|
Reference in New Issue
Block a user