Fixed ALFCOM-2285: swf2pdf command is hard-coded

- Added toMap() method to TransformationOptions
 - toMap() of SWFTransformationOptions adds 'flashVersion' property
 - RuntimeExecutableContentTransformer uses toMap() to override default properties
 - Changed 'transformer.Pdf2swf' bean to use RuntimeExecutableContentTransformer
 - Removed PDFToSWFContentTransformer


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12623 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-01-08 12:55:20 +00:00
parent 857aff414c
commit c16bdad03f
10 changed files with 99 additions and 338 deletions

View File

@@ -3,7 +3,40 @@
<beans> <beans>
<bean id="transformer.Pdf2swf" class="org.alfresco.repo.content.transform.swf.PDFToSWFContentTransformer" parent="baseContentTransformer"> <bean id="transformer.Pdf2swf" class="org.alfresco.repo.content.transform.RuntimeExecutableContentTransformer" parent="baseContentTransformer">
<property name="checkCommand">
<bean class="org.alfresco.util.exec.RuntimeExec">
<property name="commandMap">
<map>
<entry key=".*">
<value>pdf2swf -V</value>
</entry>
</map>
</property>
<property name="errorCodes">
<value>1</value>
</property>
</bean>
</property>
<property name="transformCommand">
<bean class="org.alfresco.util.exec.RuntimeExec">
<property name="commandMap">
<map>
<entry key=".*">
<value>pdf2swf -T ${flashVersion} ${source} -o ${target}</value>
</entry>
</map>
</property>
<property name="defaultProperties">
<map>
<entry key="flashVersion" value="9" />
</map>
</property>
<property name="errorCodes">
<value>1</value>
</property>
</bean>
</property>
<property name="explicitTransformations"> <property name="explicitTransformations">
<list> <list>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" > <bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
@@ -12,7 +45,6 @@
</bean> </bean>
</list> </list>
</property> </property>
</bean> </bean>
<bean id="transformer.complex.OpenOffice.Pdf2swf" <bean id="transformer.complex.OpenOffice.Pdf2swf"

View File

@@ -32,7 +32,6 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
@@ -165,10 +164,6 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
return; return;
} }
// Get the source mimetype
ContentData contentData = (ContentData)this.nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_CONTENT);
String sourceMimeType = contentData.getMimetype();
// Get the mime type // Get the mime type
String mimeType = (String)ruleAction.getParameterValue(PARAM_MIME_TYPE); String mimeType = (String)ruleAction.getParameterValue(PARAM_MIME_TYPE);
@@ -288,7 +283,8 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
{ {
// Transformation options // Transformation options
TransformationOptions options = new TransformationOptions(sourceNodeRef, ContentModel.PROP_NAME, destinationNodeRef, ContentModel.PROP_NAME); TransformationOptions options = new TransformationOptions(
sourceNodeRef, ContentModel.PROP_NAME, destinationNodeRef, ContentModel.PROP_NAME);
// try to pre-empt the lack of a transformer // try to pre-empt the lack of a transformer
if (this.contentService.isTransformable(contentReader, contentWriter, options) == false) if (this.contentService.isTransformable(contentReader, contentWriter, options) == false)

View File

@@ -222,15 +222,12 @@ public class RuntimeExecutableContentTransformer extends AbstractContentTransfor
Map<String, String> properties = new HashMap<String, String>(5); Map<String, String> properties = new HashMap<String, String>(5);
// copy options over // copy options over
if (options instanceof RuntimeExecutableContentTransformerOptions) Map<String, Object> optionsMap = options.toMap();
for (Map.Entry<String, Object> entry : optionsMap.entrySet())
{ {
RuntimeExecutableContentTransformerOptions runtimeOptions = (RuntimeExecutableContentTransformerOptions)options; String key = entry.getKey();
for (Map.Entry<String, Object> entry : runtimeOptions.getPropertyValues().entrySet()) Object value = entry.getValue();
{ properties.put(key, (value == null ? null : value.toString()));
String key = entry.getKey();
Object value = entry.getValue();
properties.put(key, (value == null ? null : value.toString()));
}
} }
// add the source and target properties // add the source and target properties
properties.put(VAR_SOURCE, sourceFile.getAbsolutePath()); properties.put(VAR_SOURCE, sourceFile.getAbsolutePath());

View File

@@ -40,25 +40,27 @@ import org.alfresco.service.cmr.repository.TransformationOptions;
public class RuntimeExecutableContentTransformerOptions extends TransformationOptions public class RuntimeExecutableContentTransformerOptions extends TransformationOptions
{ {
/** Map of property values */ /** Map of property values */
private Map<String, Object> propertyValues = new HashMap<String, Object>(1); private Map<String, String> propertyValues = new HashMap<String, String>(11);
/** /**
* Sets the map of property values that are used when executing the transformer * Sets the map of property values that are used when executing the transformer
* *
* @param propertyValues property value * @param propertyValues property value
*/ */
public void setPropertyValues(Map<String, Object> propertyValues) public void setPropertyValues(Map<String, String> propertyValues)
{ {
this.propertyValues = propertyValues; this.propertyValues = propertyValues;
} }
/** /**
* Gets the map of property values that are used when executing the transformer * Overrides the base class implementation to add all values set in {@link #setPropertyValues(Map)}
*
* @return Map<String, Object> property values
*/ */
public Map<String, Object> getPropertyValues() @Override
public Map<String, Object> toMap()
{ {
return propertyValues; Map<String, Object> baseProps = super.toMap();
Map<String, Object> props = new HashMap<String, Object>(baseProps);
props.putAll(propertyValues);
return props;
} }
} }

View File

@@ -70,9 +70,11 @@ public class ImageMagickContentTransformerTest extends AbstractContentTransforme
{ {
return; return;
} }
boolean reliability = transformer.isTransformable(MimetypeMap.MIMETYPE_IMAGE_GIF, MimetypeMap.MIMETYPE_TEXT_PLAIN, new TransformationOptions()); boolean reliability = transformer.isTransformable(
MimetypeMap.MIMETYPE_IMAGE_GIF, MimetypeMap.MIMETYPE_TEXT_PLAIN, new TransformationOptions());
assertEquals("Mimetype should not be supported", false, reliability); assertEquals("Mimetype should not be supported", false, reliability);
reliability = transformer.isTransformable(MimetypeMap.MIMETYPE_IMAGE_GIF, MimetypeMap.MIMETYPE_IMAGE_JPEG, new TransformationOptions()); reliability = transformer.isTransformable(
MimetypeMap.MIMETYPE_IMAGE_GIF, MimetypeMap.MIMETYPE_IMAGE_JPEG, new TransformationOptions());
assertEquals("Mimetype should be supported", true, reliability); assertEquals("Mimetype should be supported", true, reliability);
} }
} }

View File

@@ -1,273 +0,0 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.content.transform.swf;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.AbstractContentTransformer2;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.exec.RuntimeExec;
import org.alfresco.util.exec.RuntimeExec.ExecutionResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* PDF to SWF content transformer
*
* @author Roy Wetherall
*/
public class PDFToSWFContentTransformer extends AbstractContentTransformer2
{
/** Logger */
private static final Log logger = LogFactory.getLog(PDFToSWFContentTransformer.class);
/** Used to indicate whether the transformaer in available or not */
private boolean available = false;
/** Stores the output from the check command */
private String versionString;
/** Check and transform command */
private RuntimeExec checkCommand;
private RuntimeExec transformCommand;
/** Default flash version to convert to */
private static final String DEFAULT_FLASH_VERSION = "9";
/** Check command string */
private static final String PDF2SWF_CHECK = "pdf2swf -V";
/** Transformation command string */
private static final String PDF2SWF_COMMAND = "pdf2swf -t ${flashVersion} ${source} -o ${target}";
private static final String VAR_SOURCE = "source";
private static final String VAR_TARGET = "target";
private static final String VAR_FLASH_VERSION = "flashVersion";
/**
* Get the check command for the PDF2SWF tool
*
* @return RuntimeExec check command
*/
private RuntimeExec getCheckCommand()
{
if (this.checkCommand == null)
{
this.checkCommand = createCommand(PDF2SWF_CHECK);
}
return this.checkCommand;
}
/**
* Get the transform command for the PDF2SWF tool
*
* @return RuntimeExec transform command
*/
private RuntimeExec getTransformCommand()
{
if (this.transformCommand == null)
{
this.transformCommand = createCommand(PDF2SWF_COMMAND);
}
return this.transformCommand;
}
/**
* Helper to create a runtime exec object for a given command string
*
* @param commandString command string
* @return RuntimeExec runtime exec command
*/
private RuntimeExec createCommand(String commandString)
{
// Create command
RuntimeExec result = new RuntimeExec();
// Set the command string
Map<String, String> commandsByOS = new HashMap<String, String>(1);
commandsByOS.put(".*", commandString);
result.setCommandMap(commandsByOS);
// Set the error code
result.setErrorCodes("1");
return result;
}
/**
* @see org.alfresco.repo.content.transform.AbstractContentTransformer2#register()
*/
@Override
public void register()
{
ExecutionResult result = getCheckCommand().execute();
// check the return code
if (this.available = result.getSuccess())
{
this.versionString = result.getStdOut().trim();
}
else
{
logger.error("Failed to start SWF2PDF transformer: \n" + result);
}
// call the base class to make sure that it gets registered
super.register();
}
/**
* @see org.alfresco.repo.content.transform.AbstractContentTransformer2#transformInternal(org.alfresco.service.cmr.repository.ContentReader, org.alfresco.service.cmr.repository.ContentWriter, org.alfresco.service.cmr.repository.TransformationOptions)
*/
@Override
protected void transformInternal(ContentReader reader, ContentWriter writer, TransformationOptions options)
throws Exception
{
// get mimetypes
String sourceMimetype = getMimetype(reader);
String targetMimetype = getMimetype(writer);
// get the extensions to use
String sourceExtension = getMimetypeService().getExtension(sourceMimetype);
String targetExtension = getMimetypeService().getExtension(targetMimetype);
if (sourceExtension == null || targetExtension == null)
{
throw new AlfrescoRuntimeException("Unknown extensions for mimetypes: \n" +
" source mimetype: " + sourceMimetype + "\n" +
" source extension: " + sourceExtension + "\n" +
" target mimetype: " + targetMimetype + "\n" +
" target extension: " + targetExtension);
}
// create required temp files
File sourceFile = TempFileProvider.createTempFile(
getClass().getSimpleName() + "_source_",
"." + sourceExtension);
File targetFile = TempFileProvider.createTempFile(
getClass().getSimpleName() + "_target_",
"." + targetExtension);
String flashVersion = DEFAULT_FLASH_VERSION;
Map<String, String> properties = new HashMap<String, String>(5);
if (options instanceof SWFTransformationOptions)
{
SWFTransformationOptions swfOptions = (SWFTransformationOptions)options;
if (swfOptions.getFlashVersion() != null)
{
flashVersion = swfOptions.getFlashVersion();
}
}
properties.put(VAR_FLASH_VERSION, "-T " + flashVersion);
// add the source and target properties
properties.put(VAR_SOURCE, sourceFile.getAbsolutePath());
properties.put(VAR_TARGET, targetFile.getAbsolutePath());
// pull reader file into source temp file
reader.getContent(sourceFile);
// execute the transformation command
ExecutionResult result = null;
try
{
result = getTransformCommand().execute(properties);
}
catch (Throwable e)
{
throw new ContentIOException("Transformation failed during command execution: \n" + transformCommand, e);
}
// check
if (!result.getSuccess())
{
throw new ContentIOException("Transformation failed - status indicates an error: \n" + result);
}
// check that the file was created
if (!targetFile.exists())
{
throw new ContentIOException("Transformation failed - target file doesn't exist: \n" + result);
}
// copy the target file back into the repo
writer.putContent(targetFile);
// done
if (logger.isDebugEnabled())
{
logger.debug("PDF2SWF transformation completed: \n" +
" source: " + reader + "\n" +
" target: " + writer + "\n" +
" options: " + options + "\n" +
" result: \n" + result);
}
}
/**
* @see org.alfresco.repo.content.transform.ContentTransformer#isTransformable(java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.TransformationOptions)
*/
public boolean isTransformable(String sourceMimetype, String targetMimetype, TransformationOptions options)
{
boolean result = false;
if (this.available == true)
{
if (MimetypeMap.MIMETYPE_PDF.equals(sourceMimetype) == true &&
MimetypeMap.MIMETYPE_FLASH.equals(targetMimetype) == true)
{
result = true;
}
}
return result;
}
/**
* Signals whether this transformer is available.
*
* @return true, if is available
*/
public boolean isAvailable()
{
return this.available;
}
/**
* Gets the version string captured from the check command.
*
* @return the version string
*/
public String getVersionString()
{
return this.versionString;
}
}

View File

@@ -24,7 +24,11 @@
*/ */
package org.alfresco.repo.content.transform.swf; package org.alfresco.repo.content.transform.swf;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.repository.TransformationOptions; import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.ParameterCheck;
/** /**
* SFW transformation options * SFW transformation options
@@ -33,11 +37,14 @@ import org.alfresco.service.cmr.repository.TransformationOptions;
*/ */
public class SWFTransformationOptions extends TransformationOptions public class SWFTransformationOptions extends TransformationOptions
{ {
private static final String OPT_FLASH_VERSION = "flashVersion";
/** The version of the flash to convert to */ /** The version of the flash to convert to */
private String flashVersion = "9"; private String flashVersion = "9";
public void setFlashVersion(String flashVersion) public void setFlashVersion(String flashVersion)
{ {
ParameterCheck.mandatory("flashVersion", flashVersion);
this.flashVersion = flashVersion; this.flashVersion = flashVersion;
} }
@@ -45,4 +52,13 @@ public class SWFTransformationOptions extends TransformationOptions
{ {
return flashVersion; return flashVersion;
} }
@Override
public Map<String, Object> toMap()
{
Map<String, Object> baseProps = super.toMap();
Map<String, Object> props = new HashMap<String, Object>(baseProps);
props.put(OPT_FLASH_VERSION, flashVersion);
return props;
}
} }

View File

@@ -30,7 +30,6 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.node.NodeRefPropertyMethodInterceptor;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition;

View File

@@ -37,7 +37,6 @@ import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.content.transform.magick.ImageResizeOptions; import org.alfresco.repo.content.transform.magick.ImageResizeOptions;
import org.alfresco.repo.content.transform.magick.ImageTransformationOptions; import org.alfresco.repo.content.transform.magick.ImageTransformationOptions;
import org.alfresco.repo.jscript.ClasspathScriptLocation; import org.alfresco.repo.jscript.ClasspathScriptLocation;
import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
@@ -94,7 +93,6 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
{ {
} }
/*
public void testCreateThumbnailFromImage() throws Exception public void testCreateThumbnailFromImage() throws Exception
{ {
// Check that the image transformations are available // Check that the image transformations are available
@@ -427,6 +425,4 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js"); ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js");
this.scriptService.executeScript(location, model); this.scriptService.executeScript(location, model);
} }
*/
} }

View File

@@ -30,13 +30,15 @@ import java.util.Map;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
/** /**
* Tansformation options.
* <p>
* Class containing values of options that are passed to content transformers. These options * Class containing values of options that are passed to content transformers. These options
* are used to determine the applicability of a content transformer and also during the * are used to determine the applicability of a content transformer and also during the
* transformation process to provide context or parameter values. * transformation process to provide context or parameter values.
* <p>
* This base class provides some common, optional contextual information about the source and
* target nodes and properties used by the transformation.
* *
* @author Roy Wetherall * @author Roy Wetherall
* @since 3.0.0
*/ */
public class TransformationOptions public class TransformationOptions
{ {
@@ -73,7 +75,8 @@ public class TransformationOptions
* @param targetNodeRef the target node reference * @param targetNodeRef the target node reference
* @param targetContentProperty the target content property * @param targetContentProperty the target content property
*/ */
public TransformationOptions(NodeRef sourceNodeRef, QName sourceContentProperty, NodeRef targetNodeRef, QName targetContentProperty) public TransformationOptions(
NodeRef sourceNodeRef, QName sourceContentProperty, NodeRef targetNodeRef, QName targetContentProperty)
{ {
this.sourceNodeRef = sourceNodeRef; this.sourceNodeRef = sourceNodeRef;
this.sourceContentProperty = sourceContentProperty; this.sourceContentProperty = sourceContentProperty;
@@ -89,7 +92,10 @@ public class TransformationOptions
*/ */
public TransformationOptions(Map<String, Object> optionsMap) public TransformationOptions(Map<String, Object> optionsMap)
{ {
fromMapImpl(optionsMap); this.sourceNodeRef = (NodeRef)optionsMap.get(OPT_SOURCE_NODEREF);
this.sourceContentProperty = (QName)optionsMap.get(OPT_SOURCE_CONTENT_PROPERTY);
this.targetNodeRef = (NodeRef)optionsMap.get(OPT_TARGET_NODEREF);
this.targetContentProperty = (QName)optionsMap.get(OPT_TARGET_CONTENT_PROPERTY);
} }
/** /**
@@ -173,38 +179,26 @@ public class TransformationOptions
} }
/** /**
* Converts the transformation options object into an equivalent map * Convert the transformation options into a map.
* * <p>
* @return * Basic options (optional) are:
* <ul>
* <li>{@link #OPT_SOURCE_NODEREF}</li>
* <li>{@link #OPT_SOURCE_CONTENT_PROPERTY}</li>
* <li>{@link #OPT_TARGET_NODEREF}</li>
* <li>{@link #OPT_TARGET_CONTENT_PROPERTY}</li>
* </ul>
* <p>
* Override this method to append option values to the map. Derived classes should call
* the base class before appending further values and returning the result.
*/ */
public Map<String, Object> toMap() public Map<String, Object> toMap()
{ {
return new HashMap<String, Object>(10); Map<String, Object> optionsMap = new HashMap<String, Object>(7);
} optionsMap.put(OPT_SOURCE_NODEREF, sourceNodeRef);
optionsMap.put(OPT_SOURCE_CONTENT_PROPERTY, sourceContentProperty);
/** optionsMap.put(OPT_TARGET_NODEREF, targetNodeRef);
* Places the values of the transformation options into a Map optionsMap.put(OPT_TARGET_CONTENT_PROPERTY, targetContentProperty);
* return optionsMap;
* @param optionsMap the options map
*/
protected void toMapImpl(Map<String, Object> optionsMap)
{
optionsMap.put(OPT_SOURCE_NODEREF, getSourceNodeRef());
optionsMap.put(OPT_SOURCE_CONTENT_PROPERTY, getSourceContentProperty());
optionsMap.put(OPT_TARGET_NODEREF, getTargetNodeRef());
optionsMap.put(OPT_TARGET_CONTENT_PROPERTY, getTargetContentProperty());
}
/**
* Populates the transformation options from a given Map of value.
*
* @param optionsMap the options map
*/
protected void fromMapImpl(Map<String, Object> optionsMap)
{
this.sourceNodeRef = (NodeRef)optionsMap.get(OPT_SOURCE_NODEREF);
this.sourceContentProperty = (QName)optionsMap.get(OPT_SOURCE_CONTENT_PROPERTY);
this.targetNodeRef = (NodeRef)optionsMap.get(OPT_TARGET_NODEREF);
this.targetContentProperty = (QName)optionsMap.get(OPT_TARGET_CONTENT_PROPERTY);
} }
} }