diff --git a/deprecated/alfresco-transformer-base/src/main/java/org/alfresco/transform/TransformEngine.java b/deprecated/alfresco-transformer-base/src/main/java/org/alfresco/transform/TransformEngine.java deleted file mode 100644 index 1802714c..00000000 --- a/deprecated/alfresco-transformer-base/src/main/java/org/alfresco/transform/TransformEngine.java +++ /dev/null @@ -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 . - * #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 getTransformers(); - - /** - * @return a ProbeTestTransform (will do a quick transform) for k8 liveness and readiness probes. - */ - ProbeTestTransform getLivenessAndReadinessProbeTestTransform(); -} diff --git a/engines/base/src/main/java/org/alfresco/transform/base/CustomTransformer.java b/engines/base/src/main/java/org/alfresco/transform/base/CustomTransformer.java index 3b16b024..30983a4f 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/CustomTransformer.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/CustomTransformer.java @@ -36,12 +36,14 @@ import java.util.Map; * 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 * 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 { String getTransformerName(); - void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception; + void transform(String sourceMimetype, InputStream inputStream, + String targetMimetype, OutputStream outputStream, + Map transformOptions, TransformManager transformManager) throws Exception; } diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java index 818fa486..dd729e46 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java @@ -26,7 +26,9 @@ */ package org.alfresco.transform.base; +import org.alfresco.transform.base.fs.FileManager; import org.alfresco.transform.base.probes.ProbeTestTransform; +import org.alfresco.transform.base.util.OutputStreamLengthRecorder; import org.alfresco.transform.common.TransformerDebug; import org.alfresco.transform.client.model.InternalContext; 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.logging.LogEntry; import org.alfresco.transform.base.model.FileRefResponse; -import org.codehaus.plexus.util.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.client.HttpClientErrorException; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; -import java.net.URL; +import java.io.InputStream; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; @@ -82,6 +86,8 @@ import java.util.concurrent.atomic.AtomicInteger; import static java.text.MessageFormat.format; 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.common.RequestParamMap.DIRECT_ACCESS_URL; 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_CONFIG; 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.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.getDirectAccessUrlInputStream; 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.save; @@ -280,7 +282,7 @@ public class TransformController } @PostMapping(value = ENDPOINT_TRANSFORM, consumes = MULTIPART_FORM_DATA_VALUE) - public ResponseEntity transform(HttpServletRequest request, + public StreamingResponseBody transform(HttpServletRequest request, @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, @RequestParam(value = SOURCE_MIMETYPE, required = false) String sourceMimetype, @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: '{}', " + "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(); - 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 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(); - transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceFile, transformName); + transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformName); transformerDebug.logOptions(reference, requestParameters); - try - { - transformImpl(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile); - final ResponseEntity body = createAttachment(targetFilename, targetFile); - LogEntry.setTargetSize(targetFile.length()); - long time = LogEntry.setStatusCodeAndMessage(OK.value(), "Success"); - probeTestTransform.recordTransformTime(time); - transformerDebug.popTransform(reference, time); - return body; - } - catch (Throwable t) - { - transformerDebug.logFailure(reference, t.getMessage()); - throw t; - } + return os -> { + OutputStreamLengthRecorder outputStream = new OutputStreamLengthRecorder(os); + try + { + TransformManagerImpl transformManager = TransformManagerImpl.builder() + .withRequest(request) + .withSourceMimetype(sourceMimetype) + .withTargetMimetype(targetMimetype) + .withInputStream(inputStream) + .withOutputStream(outputStream) + .build(); + + customTransformer.transform(sourceMimetype, inputStream, + targetMimetype, outputStream, transformOptions, transformManager); + + transformManager.ifUsedCopyTargetFileToOutputStream(); + + LogEntry.setTargetSize(outputStream.getLength()); + long time = LogEntry.setStatusCodeAndMessage(OK.value(), "Success"); + + transformManager.deleteSourceFileIfExists(); + transformManager.deleteTargetFileIfExists(); + + probeTestTransform.recordTransformTime(time); + transformerDebug.popTransform(reference, time); + } + catch (Exception e) + { + transformerDebug.logFailure(reference, e.getMessage()); + throw new RuntimeException(e); + } + }; } /** @@ -353,89 +359,68 @@ public class TransformController public ResponseEntity transform(@RequestBody TransformRequest request, @RequestParam(value = "timeout", required = false) Long timeout) { + long start = System.currentTimeMillis(); logger.trace("Received {}, timeout {} ms", request, timeout); + probeTestTransform.incrementTransformerCount(); + TransformReply reply = createBasicTransformReply(request); - final TransformReply reply = new TransformReply(); - 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()) + if (isTransformRequestValid(request, reply) == false) { - 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())); } + + InputStream inputStream = getInputStream(request, reply); + if (inputStream == null) + { + return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); + } + + String targetMimetype = request.getTargetMediaType(); + String sourceMimetype = request.getSourceMediaType(); + File targetFile = createTargetFile(null, sourceMimetype, targetMimetype); 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)); + OutputStreamLengthRecorder outputStream = + new OutputStreamLengthRecorder(new BufferedOutputStream(new FileOutputStream(targetFile))); - 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())); - } - - // Create local temp target file in order to run the transformation - final String targetFilename = createTargetFileName(sourceFile.getName(), request.getTargetMediaType(), request.getSourceMediaType()); - final File targetFile = buildFile(targetFilename); - - // Run the transformation - try - { - String targetMimetype = request.getTargetMediaType(); - String sourceMimetype = request.getSourceMediaType(); + long sourceSizeInBytes = request.getSourceSize(); Map transformOptions = getTransformOptions(request.getTransformRequestOptions()); + String sourceEncoding = transformOptions.get(SOURCE_ENCODING); + String targetEncoding = transformOptions.get(TARGET_ENCODING); // TODO not normally set transformerDebug.logOptions(request); - String transformName = getTransformerName(sourceFile, sourceMimetype, targetMimetype, transformOptions); - transformImpl(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile); - reply.getInternalContext().setCurrentSourceSize(targetFile.length()); + String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions); + CustomTransformer customTransformer = getCustomTransformer(transformName); + + 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) { @@ -455,65 +440,38 @@ public class TransformController logger.trace("Failed to perform transform (Exception), sending " + reply, e); return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); } + } - // Write the target file - FileRefResponse targetRef; - try + private boolean isTransformRequestValid(TransformRequest request, TransformReply reply) + { + final Errors errors = validateTransformRequest(request); + validateInternalContext(request, errors); + reply.setInternalContext(request.getInternalContext()); + if (!errors.getAllErrors().isEmpty()) { - targetRef = alfrescoSharedFileStoreClient.saveFile(targetFile); - } - catch (TransformException e) - { - reply.setStatus(e.getStatusCode()); - reply.setErrorDetails(messageWithCause("Failed at writing the transformed file", e)); + reply.setStatus(BAD_REQUEST.value()); + reply.setErrorDetails(errors + .getAllErrors() + .stream() + .map(Object::toString) + .collect(joining(", "))); transformerDebug.logFailure(reply); - logger.trace("Failed to save target file (TransformException), sending " + reply, e); - return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); + logger.trace("Invalid request, sending {}", reply); + return false; } - catch (HttpClientErrorException e) - { - reply.setStatus(e.getStatusCode().value()); - reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e)); + return true; + } - 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 - { - deleteFile(targetFile); - } - catch (Exception e) - { - logger.error("Failed to delete local temp target file '{}'. Error will be ignored ", - targetFile, e); - } - 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 TransformReply createBasicTransformReply(TransformRequest request) + { + TransformReply reply = new TransformReply(); + reply.setRequestId(request.getRequestId()); + reply.setSourceReference(request.getSourceReference()); + reply.setSchema(request.getSchema()); + reply.setClientData(request.getClientData()); + reply.setInternalContext(request.getInternalContext()); + return reply; } private Errors validateTransformRequest(final TransformRequest transformRequest) @@ -530,6 +488,7 @@ public class TransformController { errors.rejectValue("internalContext", null, errorMessage); } + initialiseContext(request); } private void initialiseContext(TransformRequest request) @@ -538,25 +497,6 @@ public class TransformController 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 getTransformOptions(Map requestParameters) { Map transformOptions = new HashMap<>(requestParameters); @@ -565,6 +505,108 @@ public class TransformController return transformOptions; } + private InputStream getSharedFileStoreInputStream(String sourceReference) + { + ResponseEntity 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 * @@ -574,9 +616,7 @@ public class TransformController */ private File loadSourceFile(final String sourceReference, final String sourceExtension) { - ResponseEntity responseEntity = alfrescoSharedFileStoreClient - .retrieveFile(sourceReference); - probeTestTransform.incrementTransformerCount(); + ResponseEntity responseEntity = alfrescoSharedFileStoreClient.retrieveFile(sourceReference); HttpHeaders headers = responseEntity.getHeaders(); String filename = getFilenameFromContentDisposition(headers); @@ -621,7 +661,7 @@ public class TransformController 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 transformOptions) { // 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); try { - final long sourceSizeInBytes = sourceFile.length(); final String transformerName = transformRegistry.findTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, transformOptions, 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, Map transformOptions, File sourceFile, File targetFile) { diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java index 34f57e97..34e84f3d 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformEngine.java @@ -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. * 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 { diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformInterceptor.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformInterceptor.java index 16f5d3f2..330430d9 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformInterceptor.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformInterceptor.java @@ -55,7 +55,6 @@ public class TransformInterceptor extends HandlerInterceptorAdapter public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { - // TargetFile cannot be deleted until completion, otherwise 0 bytes are sent. deleteFile(request, SOURCE_FILE); deleteFile(request, TARGET_FILE); diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformManager.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformManager.java new file mode 100644 index 00000000..66560209 --- /dev/null +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformManager.java @@ -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 . + * #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); +} diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java new file mode 100644 index 00000000..e70ba2bf --- /dev/null +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java @@ -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 . + * #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; + } + } +} diff --git a/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java b/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java index 270d423b..c3d5aed0 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java @@ -26,6 +26,8 @@ */ 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.HttpStatus.BAD_REQUEST; 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.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; @@ -58,11 +62,43 @@ public class FileManager public static final String TARGET_FILE = "targetFile"; 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); - request.setAttribute(TARGET_FILE, file); - return file; + try + { + 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; + } + 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) @@ -97,8 +133,7 @@ public class FileManager { try { - Files.copy(multipartFile.getInputStream(), file.toPath(), - StandardCopyOption.REPLACE_EXISTING); + Files.copy(multipartFile.getInputStream(), file.toPath(), REPLACE_EXISTING); } catch (IOException e) { @@ -111,7 +146,7 @@ public class FileManager { try { - Files.copy(body.getInputStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(body.getInputStream(), file.toPath(), REPLACE_EXISTING); } catch (IOException e) { @@ -176,16 +211,46 @@ public class FileManager 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(); - long size = multipartFile.getSize(); - filename = checkFilename(true, filename); - File file = TempFileProvider.createTempFile("source_", "_" + filename); - request.setAttribute(SOURCE_FILE, file); - save(multipartFile, file); - LogEntry.setSource(filename, size); - return file; + InputStream inputStream; + if (sourceMultipartFile == null) + { + throw new TransformException(BAD_REQUEST.value(), "Required request part 'file' is not present"); + } + try + { + 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") diff --git a/engines/base/src/main/java/org/alfresco/transform/base/metadataExtractors/AbstractMetadataExtractor.java b/engines/base/src/main/java/org/alfresco/transform/base/metadataExtractors/AbstractMetadataExtractor.java index c1d6fc37..9ed892bc 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/metadataExtractors/AbstractMetadataExtractor.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/metadataExtractors/AbstractMetadataExtractor.java @@ -30,7 +30,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.alfresco.transform.base.CustomTransformer; -import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.base.TransformManager; import org.slf4j.Logger; import java.io.File; @@ -51,7 +51,7 @@ import java.util.Set; import java.util.StringTokenizer; 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. @@ -151,16 +151,30 @@ public abstract class AbstractMetadataExtractor implements CustomTransformer return getClass().getSimpleName(); } - public abstract Map extractMetadata(String sourceMimetype, Map transformOptions, - File sourceFile) throws Exception; - - public void embedMetadata(String sourceMimetype, Map transformOptions, - String sourceEncoding, InputStream inputStream, - String targetEncoding, OutputStream outputStream) throws Exception + @Override + public void transform(String sourceMimetype, InputStream inputStream, + String targetMimetype, OutputStream outputStream, + Map transformOptions, TransformManager transformManager) throws Exception { - // TODO - throw new TransformException(500, "TODO embedMetadata"); + if (type == EMBEDDER) + { + 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 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 transformOptions, File sourceFile, File targetFile) throws Exception { @@ -493,27 +507,13 @@ public abstract class AbstractMetadataExtractor implements CustomTransformer return true; } - @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception + public void extractMetadata(String sourceMimetype, InputStream inputStream, + String targetMimetype, OutputStream outputStream, + Map transformOptions, TransformManager transformManager) throws Exception { - if (type == EXTRACTOR) - { - extractMetadata(sourceMimetype, transformOptions, sourceEncoding, inputStream, targetEncoding, outputStream); - } - else - { - embedMetadata(sourceMimetype, transformOptions, sourceEncoding, inputStream, targetEncoding, outputStream); - } - } - - public void extractMetadata(String sourceMimetype, Map transformOptions, - String sourceEncoding, InputStream inputStream, - String targetEncoding, OutputStream outputStream) throws Exception - { - // TODO - throw new TransformException(500, "TODO extractMetadata"); + File sourceFile = transformManager.createSourceFile(); + File targetFile = transformManager.createTargetFile(); + extractMetadata(sourceMimetype, transformOptions, sourceFile, targetFile); } /** @@ -539,6 +539,9 @@ public abstract class AbstractMetadataExtractor implements CustomTransformer } } + public abstract Map extractMetadata(String sourceMimetype, Map transformOptions, + File sourceFile) throws Exception; + private Map> getExtractMappingFromOptions(Map transformOptions, Map> defaultExtractMapping) { diff --git a/engines/base/src/main/java/org/alfresco/transform/base/util/CustomTransformerFileAdaptor.java b/engines/base/src/main/java/org/alfresco/transform/base/util/CustomTransformerFileAdaptor.java new file mode 100644 index 00000000..c2a4c805 --- /dev/null +++ b/engines/base/src/main/java/org/alfresco/transform/base/util/CustomTransformerFileAdaptor.java @@ -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 . + * #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 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 transformOptions, + File sourceFile, File targetFile) throws Exception; +} \ No newline at end of file diff --git a/deprecated/alfresco-transformer-base/src/main/java/org/alfresco/transform/CustomTransformer.java b/engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java similarity index 63% rename from deprecated/alfresco-transformer-base/src/main/java/org/alfresco/transform/CustomTransformer.java rename to engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java index 1a47cff7..ab644519 100644 --- a/deprecated/alfresco-transformer-base/src/main/java/org/alfresco/transform/CustomTransformer.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java @@ -24,15 +24,35 @@ * along with Alfresco. If not, see . * #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.util.Map; -public interface CustomTransformer +public class OutputStreamLengthRecorder extends FilterOutputStream { - void transform(String transformerName, String sourceMimetype, String targetMimetype, - Map transformOptions, - InputStream inputStream, OutputStream outputStream) throws Exception; -} + private long byteCount; + + 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; + } +} \ No newline at end of file diff --git a/engines/base/src/main/java/org/alfresco/transform/base/util/Util.java b/engines/base/src/main/java/org/alfresco/transform/base/util/Util.java index ba5a8c8e..eb8baf81 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/util/Util.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/util/Util.java @@ -26,6 +26,9 @@ */ package org.alfresco.transform.base.util; +import java.io.File; +import java.io.InputStream; + public class Util { /** diff --git a/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/transformers/ImageMagickTransformer.java b/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/transformers/ImageMagickTransformer.java index 9a2acd0b..1dcd4a33 100644 --- a/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/transformers/ImageMagickTransformer.java +++ b/engines/imagemagick/src/main/java/org/alfresco/transform/imagemagick/transformers/ImageMagickTransformer.java @@ -26,11 +26,12 @@ */ 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.RuntimeExec; -import org.alfresco.transform.imagemagick.ImageMagickOptionsBuilder; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.imagemagick.ImageMagickOptionsBuilder; import org.springframework.beans.factory.annotation.Value; 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; @Component -public class ImageMagickTransformer extends AbstractCommandExecutor implements CustomTransformer +public class ImageMagickTransformer extends AbstractCommandExecutor implements CustomTransformerFileAdaptor { @Value("${transform.core.imagemagick.exe}") private String exe; @@ -150,14 +151,7 @@ public class ImageMagickTransformer extends AbstractCommandExecutor implements C } @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO ImageMagick transform"); - } - public void transform(String transformName, String sourceMimetype, String targetMimetype, - Map transformOptions, + public void transform(String sourceMimetype, String targetMimetype, Map transformOptions, File sourceFile, File targetFile) throws TransformException { final String options = ImageMagickOptionsBuilder diff --git a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java index 621c6f1a..9fe973c9 100644 --- a/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java +++ b/engines/libreoffice/src/main/java/org/alfresco/transform/libreoffice/transformers/LibreOfficeTransformer.java @@ -28,7 +28,8 @@ package org.alfresco.transform.libreoffice.transformers; import com.fasterxml.jackson.databind.ObjectMapper; 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.apache.commons.lang3.StringUtils; 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). */ @Component -public class LibreOfficeTransformer implements CustomTransformer +public class LibreOfficeTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger(LibreOfficeTransformer.class); @@ -130,20 +131,8 @@ public class LibreOfficeTransformer implements CustomTransformer } @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO LibreOffice transform"); - } - - public void transform(String transformName, String sourceMimetype, String targetMimetype, Map transformOptions, + public void transform(String sourceMimetype, String targetMimetype, Map transformOptions, File sourceFile, File targetFile) - { - call(sourceFile, targetFile); - } - - public void call(File sourceFile, File targetFile, String... args) { try { diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/HtmlMetadataExtractor.java b/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/HtmlMetadataExtractor.java index 095b7928..075216d2 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/HtmlMetadataExtractor.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/HtmlMetadataExtractor.java @@ -27,6 +27,7 @@ package org.alfresco.transform.misc.metadataExtractors; import org.alfresco.transform.base.CustomTransformer; +import org.alfresco.transform.base.TransformManager; import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor; import org.alfresco.transform.common.TransformException; import org.slf4j.Logger; @@ -85,19 +86,6 @@ public class HtmlMetadataExtractor extends AbstractMetadataExtractor implements return getClass().getSimpleName(); } - @Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO HtmlMetadataExtractor transform"); - } - - public void extractMetadata(String sourceMimetype, String targetMimetype, Map transformOptions, - File sourceFile, File targetFile) throws Exception - { - extractMetadata(sourceMimetype, transformOptions, sourceFile, targetFile); - } - @Override public Map extractMetadata(String sourceMimetype, Map transformOptions, File sourceFile) throws Exception diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java b/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java index cbbc1cb2..3930dd85 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java @@ -27,6 +27,7 @@ package org.alfresco.transform.misc.metadataExtractors; import org.alfresco.transform.base.CustomTransformer; +import org.alfresco.transform.base.TransformManager; import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor; import org.alfresco.transform.common.TransformException; import org.slf4j.Logger; @@ -87,19 +88,6 @@ public class RFC822MetadataExtractor extends AbstractMetadataExtractor implement super(EXTRACTOR, logger); } - @Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO RFC822MetadataExtractor transform"); - } - - public void extractMetadata(String sourceMimetype, String targetMimetype, Map transformOptions, - File sourceFile, File targetFile) throws Exception - { - extractMetadata(sourceMimetype, transformOptions, sourceFile, targetFile); - } - @Override public Map extractMetadata(String sourceMimetype, Map transformOptions, File sourceFile) throws Exception diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/AppleIWorksContentTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/AppleIWorksContentTransformer.java index 2f5448c0..81e80c96 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/AppleIWorksContentTransformer.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/AppleIWorksContentTransformer.java @@ -27,8 +27,8 @@ package org.alfresco.transform.misc.transformers; import com.google.common.collect.ImmutableList; -import org.alfresco.transform.base.CustomTransformer; -import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.base.TransformManager; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.slf4j.Logger; @@ -64,7 +64,7 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_JPEG; * @since 4.0 */ @Component -public class AppleIWorksContentTransformer implements CustomTransformer +public class AppleIWorksContentTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger( AppleIWorksContentTransformer.class); @@ -84,15 +84,9 @@ public class AppleIWorksContentTransformer implements CustomTransformer return "appleIWorks"; } - @Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO appleIWorks transform"); - } - - public void transform(final String sourceMimetype, final String targetMimetype, final Map parameters, - final File sourceFile, final File targetFile) + @Override + public void transform(String sourceMimetype, String targetMimetype, Map transformOptions, + File sourceFile, File targetFile) { logger.debug("Performing IWorks to jpeg transform with sourceMimetype={} targetMimetype={}", sourceMimetype, targetMimetype); diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/EMLTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/EMLTransformer.java index 68076b08..5ec68656 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/EMLTransformer.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/EMLTransformer.java @@ -26,9 +26,9 @@ */ 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.common.TransformException; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -69,7 +69,7 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN; *

*/ @Component -public class EMLTransformer implements CustomTransformer +public class EMLTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger(EMLTransformer.class); @@ -82,15 +82,9 @@ public class EMLTransformer implements CustomTransformer return "rfc822"; } - @Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO rfc822 transform"); - } - - public void transform(final String sourceMimetype, final String targetMimetype, final Map parameters, - final File sourceFile, final File targetFile) throws Exception + @Override + public void transform(String sourceMimetype, String targetMimetype, Map transformOptions, + File sourceFile, File targetFile) throws Exception { logger.debug("Performing RFC822 to text transform."); // Use try with resource diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/HtmlParserContentTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/HtmlParserContentTransformer.java index 4b678f9e..3f625308 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/HtmlParserContentTransformer.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/HtmlParserContentTransformer.java @@ -26,8 +26,7 @@ */ package org.alfresco.transform.misc.transformers; -import org.alfresco.transform.base.CustomTransformer; -import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.htmlparser.Parser; import org.htmlparser.beans.StringBean; import org.htmlparser.util.ParserException; @@ -38,8 +37,6 @@ import org.springframework.stereotype.Component; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URLConnection; @@ -77,7 +74,7 @@ import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING; * @see HTML Parser */ @Component -public class HtmlParserContentTransformer implements CustomTransformer +public class HtmlParserContentTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger( HtmlParserContentTransformer.class); @@ -89,17 +86,11 @@ public class HtmlParserContentTransformer implements CustomTransformer } @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO html transform"); - } - - public void transform(final String sourceMimetype, final String targetMimetype, final Map parameters, + public void transform(final String sourceMimetype, final String targetMimetype, + final Map transformOptions, final File sourceFile, final File targetFile) throws Exception { - String sourceEncoding = parameters.get(SOURCE_ENCODING); + String sourceEncoding = transformOptions.get(SOURCE_ENCODING); checkEncodingParameter(sourceEncoding, SOURCE_ENCODING); if (logger.isDebugEnabled()) diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/OOXMLThumbnailContentTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/OOXMLThumbnailContentTransformer.java index fe4ea888..31022f85 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/OOXMLThumbnailContentTransformer.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/OOXMLThumbnailContentTransformer.java @@ -26,8 +26,8 @@ */ package org.alfresco.transform.misc.transformers; -import org.alfresco.transform.base.CustomTransformer; -import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.base.TransformManager; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; @@ -58,7 +58,7 @@ import java.util.Map; * @author eknizat */ @Component -public class OOXMLThumbnailContentTransformer implements CustomTransformer +public class OOXMLThumbnailContentTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger( OOXMLThumbnailContentTransformer.class); @@ -69,13 +69,6 @@ public class OOXMLThumbnailContentTransformer implements CustomTransformer } @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO ooXmlThumbnail transform"); - } - public void transform(final String sourceMimetype, final String targetMimetype, final Map parameters, final File sourceFile, final File targetFile) throws Exception { diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/StringExtractingContentTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/StringExtractingContentTransformer.java index 9468aa00..a466558f 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/StringExtractingContentTransformer.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/StringExtractingContentTransformer.java @@ -26,8 +26,7 @@ */ package org.alfresco.transform.misc.transformers; -import org.alfresco.transform.base.CustomTransformer; -import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -37,9 +36,7 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; @@ -64,7 +61,7 @@ import static org.alfresco.transform.common.RequestParamMap.TARGET_ENCODING; * @author eknizat */ @Component -public class StringExtractingContentTransformer implements CustomTransformer +public class StringExtractingContentTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger(StringExtractingContentTransformer.class); @@ -82,18 +79,11 @@ public class StringExtractingContentTransformer implements CustomTransformer * be unformatted but valid. */ @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO string transform"); - } - - public void transform(final String sourceMimetype, final String targetMimetype, final Map parameters, + public void transform(final String sourceMimetype, final String targetMimetype, final Map transformOptions, final File sourceFile, final File targetFile) throws Exception { - String sourceEncoding = parameters.get(SOURCE_ENCODING); - String targetEncoding = parameters.get(TARGET_ENCODING); + String sourceEncoding = transformOptions.get(SOURCE_ENCODING); + String targetEncoding = transformOptions.get(TARGET_ENCODING); if (logger.isDebugEnabled()) { diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/TextToPdfContentTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/TextToPdfContentTransformer.java index b71e7e3d..2a4a96a5 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/TextToPdfContentTransformer.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/TextToPdfContentTransformer.java @@ -26,8 +26,8 @@ */ package org.alfresco.transform.misc.transformers; -import org.alfresco.transform.base.CustomTransformer; -import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.base.TransformManager; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; @@ -66,7 +66,7 @@ import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING; * @author eknizat */ @Component -public class TextToPdfContentTransformer implements CustomTransformer +public class TextToPdfContentTransformer implements CustomTransformerFileAdaptor { private static final Logger logger = LoggerFactory.getLogger(TextToPdfContentTransformer.class); @@ -113,17 +113,13 @@ public class TextToPdfContentTransformer implements CustomTransformer return "textToPdf"; } - @Override public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO textToPdf transform"); - } - public void transform(final String sourceMimetype, final String targetMimetype, final Map parameters, + @Override + public void transform(final String sourceMimetype, final String targetMimetype, final Map transformOptions, final File sourceFile, final File targetFile) throws Exception { - String sourceEncoding = parameters.get(SOURCE_ENCODING); - String stringPageLimit = parameters.get(PAGE_LIMIT); + String sourceEncoding = transformOptions.get(SOURCE_ENCODING); + String stringPageLimit = transformOptions.get(PAGE_LIMIT); int pageLimit = -1; if (stringPageLimit != null) { diff --git a/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/transformers/PdfRendererTransformer.java b/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/transformers/PdfRendererTransformer.java index b64270fb..cba5d71e 100644 --- a/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/transformers/PdfRendererTransformer.java +++ b/engines/pdfrenderer/src/main/java/org/alfresco/transform/pdfrenderer/transformers/PdfRendererTransformer.java @@ -26,9 +26,10 @@ */ 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.RuntimeExec; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; import org.alfresco.transform.common.TransformException; import org.alfresco.transform.pdfrenderer.PdfRendererOptionsBuilder; 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. */ @Component -public class PdfRendererTransformer extends AbstractCommandExecutor implements CustomTransformer +public class PdfRendererTransformer extends AbstractCommandExecutor implements CustomTransformerFileAdaptor { @Value("${transform.core.pdfrenderer.exe}") private String exe; @@ -103,14 +104,7 @@ public class PdfRendererTransformer extends AbstractCommandExecutor implements C } @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - throw new TransformException(500, "TODO PdfRenderer transform"); - } - public void transform(String transformName, String sourceMimetype, String targetMimetype, - Map transformOptions, + public void transform(String sourceMimetype, String targetMimetype, Map transformOptions, File sourceFile, File targetFile) throws TransformException { final String options = PdfRendererOptionsBuilder diff --git a/engines/tika/src/main/java/org/alfresco/transform/tika/metadataExtractors/AbstractTikaMetadataExtractor.java b/engines/tika/src/main/java/org/alfresco/transform/tika/metadataExtractors/AbstractTikaMetadataExtractor.java index b8cf8b01..ef293cac 100644 --- a/engines/tika/src/main/java/org/alfresco/transform/tika/metadataExtractors/AbstractTikaMetadataExtractor.java +++ b/engines/tika/src/main/java/org/alfresco/transform/tika/metadataExtractors/AbstractTikaMetadataExtractor.java @@ -26,9 +26,8 @@ */ 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.common.TransformException; import org.apache.tika.embedder.Embedder; import org.apache.tika.extractor.DocumentSelector; import org.apache.tika.metadata.DublinCore; @@ -54,7 +53,6 @@ import org.xml.sax.Locator; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; @@ -84,7 +82,7 @@ import java.util.stream.Stream; * @author Nick Burch * @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_TITLE = "title"; @@ -310,22 +308,15 @@ public abstract class AbstractTikaMetadataExtractor extends AbstractMetadataExtr return rawProperties; } - public void embedMetadata(String sourceMimetype, Map 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. * 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. */ @Override - public void embedMetadata(String sourceMimetype, String targetMimetype, Map transformOptions, - File sourceFile, File targetFile) throws Exception + public void embedMetadata(String sourceMimetype, InputStream inputStream, + String targetMimetype, OutputStream outputStream, + Map transformOptions, TransformManager transformManager) throws Exception { Embedder embedder = getEmbedder(); if (embedder == null) @@ -334,12 +325,7 @@ public abstract class AbstractTikaMetadataExtractor extends AbstractMetadataExtr } 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 transformOptions) diff --git a/engines/tika/src/main/java/org/alfresco/transform/tika/transformers/GenericTikaTransformer.java b/engines/tika/src/main/java/org/alfresco/transform/tika/transformers/GenericTikaTransformer.java index 7a47dec2..56a2bc2e 100644 --- a/engines/tika/src/main/java/org/alfresco/transform/tika/transformers/GenericTikaTransformer.java +++ b/engines/tika/src/main/java/org/alfresco/transform/tika/transformers/GenericTikaTransformer.java @@ -26,10 +26,9 @@ */ package org.alfresco.transform.tika.transformers; -import org.alfresco.transform.base.CustomTransformer; 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.TransformException; import org.apache.tika.extractor.DocumentSelector; import org.apache.tika.parser.Parser; import org.slf4j.Logger; @@ -38,21 +37,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; import java.util.ArrayList; import java.util.Map; import java.util.StringJoiner; 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); @Value("${transform.core.tika.pdfBox.notExtractBookmarksTextDefault:false}") boolean notExtractBookmarksTextDefault; - @Autowired protected Tika tika; @@ -71,15 +67,7 @@ public abstract class GenericTikaTransformer implements CustomTransformer } @Override - public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream, - String targetMimetype, String targetEncoding, OutputStream outputStream, - Map transformOptions) throws Exception - { - // TODO - throw new TransformException(500, "TODO GenericTikaTransformer transform with InputStreams"); - } - - public void transform(String transformName, String sourceMimetype, String targetMimetype, + public void transform(String sourceMimetype, String targetMimetype, Map transformOptions, File sourceFile, File targetFile) throws Exception { @@ -92,7 +80,8 @@ public abstract class GenericTikaTransformer implements CustomTransformer { 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, notExtractBookmarksText ? Tika.NOT_EXTRACT_BOOKMARKS_TEXT : null, Tika.TARGET_MIMETYPE + targetMimetype, Tika.TARGET_ENCODING + targetEncoding); diff --git a/engines/tika/src/test/java/org/alfresco/transform/tika/transformers/GenericTikaTransformerTest.java b/engines/tika/src/test/java/org/alfresco/transform/tika/transformers/GenericTikaTransformerTest.java index 4774321b..e56cfbe7 100644 --- a/engines/tika/src/test/java/org/alfresco/transform/tika/transformers/GenericTikaTransformerTest.java +++ b/engines/tika/src/test/java/org/alfresco/transform/tika/transformers/GenericTikaTransformerTest.java @@ -49,7 +49,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) public class GenericTikaTransformerTest { - private class TikaTestTransformer extends GenericTikaTransformer + private static class TikaTestTransformer extends GenericTikaTransformer { @Override protected Parser getParser() @@ -61,7 +61,7 @@ public class GenericTikaTransformerTest { this.notExtractBookmarksTextDefault = notExtractBookmarksTextDefault; } - }; + } @Test public void testNotExtractBookmarkTextDefault() throws Exception @@ -83,9 +83,9 @@ public class GenericTikaTransformerTest Map transformOptions = new HashMap<>(); // use empty transformOptions to test defaults - executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions, + executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); - executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions, + executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); // 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 clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse); transformOptions.put("notExtractBookmarksText", "true"); - executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions, + executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); - executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions, + executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); // both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT @@ -114,8 +114,8 @@ public class GenericTikaTransformerTest // use transforms with notExtractBookmarksText set to false clearInvocations(executorSpyDefaultTrue, executorSpyDefaultFalse); transformOptions.replace("notExtractBookmarksText", "true", "false"); - executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); - executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); + executorSpyDefaultTrue.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); + executorSpyDefaultFalse.transform(sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); // both call methods should have NOT_EXTRACT_BOOKMARKS_TEXT 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, 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); transformOptions.put("targetEncoding", "anyEncoding"); - executorSpyDefaultTrue.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); - executorSpyDefaultFalse.transform(transformName, sourceMimetype, targetMimetype, transformOptions, mockSourceFile, mockTargetFile); + executorSpyDefaultTrue.transform(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 verify(executorSpyDefaultTrue, times(1)).call(mockSourceFile, mockTargetFile, transformName, null, null, diff --git a/model/src/main/java/org/alfresco/transform/common/TransformerDebug.java b/model/src/main/java/org/alfresco/transform/common/TransformerDebug.java index 324b4b31..7c2eb96f 100644 --- a/model/src/main/java/org/alfresco/transform/common/TransformerDebug.java +++ b/model/src/main/java/org/alfresco/transform/common/TransformerDebug.java @@ -79,10 +79,15 @@ public class TransformerDebug } 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()) { - final long sourceSizeInBytes = sourceFile.length(); String message = getPaddedReference(reference) + getMimetypeExt(sourceMimetype) + getTargetMimetypeExt(targetMimetype, sourceMimetype) + ' ' + diff --git a/model/src/main/java/org/alfresco/transform/registry/TransformCache.java b/model/src/main/java/org/alfresco/transform/registry/TransformCache.java index 55da8aa0..8a8ec55c 100644 --- a/model/src/main/java/org/alfresco/transform/registry/TransformCache.java +++ b/model/src/main/java/org/alfresco/transform/registry/TransformCache.java @@ -74,19 +74,19 @@ public class TransformCache return transforms; } - public void cache(final String transformerName, final String sourceMimetype, + public void cache(final String renditionName, final String sourceMimetype, final List transformListBySize) { cachedSupportedTransformList - .get(transformerName) + .get(renditionName) .put(sourceMimetype, transformListBySize); } - public List retrieveCached(final String transformerName, + public List retrieveCached(final String renditionName, final String sourceMimetype) { return cachedSupportedTransformList - .computeIfAbsent(transformerName, k -> new ConcurrentHashMap<>()) + .computeIfAbsent(renditionName, k -> new ConcurrentHashMap<>()) .get(sourceMimetype); } diff --git a/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java b/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java index 98ebe47e..c92f656c 100644 --- a/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java +++ b/model/src/main/java/org/alfresco/transform/registry/TransformRegistryHelper.java @@ -75,20 +75,20 @@ class TransformRegistryHelper // been discarded. static List retrieveTransformListBySize(final TransformCache data, final String sourceMimetype, final String targetMimetype, - Map actualOptions, String transformerName) + Map actualOptions, String renditionName) { if (actualOptions == null) { actualOptions = emptyMap(); } - if (transformerName != null && transformerName.trim().isEmpty()) + if (renditionName != null && renditionName.trim().isEmpty()) { - transformerName = null; + renditionName = null; } final List cachedTransformList = - transformerName == null ? null : - data.retrieveCached(transformerName, sourceMimetype); + renditionName == null ? null : + data.retrieveCached(renditionName, sourceMimetype); if (cachedTransformList != null) { return cachedTransformList; @@ -99,9 +99,9 @@ class TransformRegistryHelper targetMimetype, filterTimeout(actualOptions)); - if (transformerName != null) + if (renditionName != null) { - data.cache(transformerName, sourceMimetype, builtTransformList); + data.cache(renditionName, sourceMimetype, builtTransformList); } return builtTransformList; @@ -111,13 +111,12 @@ class TransformRegistryHelper final TransformCache data, final String sourceMimetype, final String targetMimetype, final Map actualOptions) { - - if(sourceMimetype == null) + if (sourceMimetype == null) { throw new TransformException(400, "Null value provided for sourceMimetype, please provide a value"); } - if(targetMimetype == null) + if (targetMimetype == null) { throw new TransformException(400, "Null value provided for tragetMimetype, please provide a value"); }