mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
JavaScript API enhancements - Document and Image transformation services
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3465 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -66,6 +66,9 @@
|
||||
<property name="policyComponent">
|
||||
<ref bean="policyComponent" />
|
||||
</property>
|
||||
<property name="imageMagickContentTransformer">
|
||||
<ref bean="transformer.ImageMagick" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="mimetypeConfigService" class="org.alfresco.config.xml.XMLConfigService" init-method="init">
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<mime-type>application/pdf</mime-type>
|
||||
<file-extension>pdf</file-extension>
|
||||
<export-filters>
|
||||
<entry><family>Presentation</family><string>impress_pdf_Export</string></entry>
|
||||
<entry><family>Presentation</family><string>impress_pdf_Export</string></entry>
|
||||
<entry><family>Spreadsheet</family><string>calc_pdf_Export</string></entry>
|
||||
<entry><family>Text</family><string>writer_pdf_Export</string></entry>
|
||||
</export-filters>
|
||||
@@ -30,7 +30,7 @@
|
||||
<mime-type>text/html</mime-type>
|
||||
<file-extension>html</file-extension>
|
||||
<export-filters>
|
||||
<entry><family>Presentation</family><string>impress_html_Export</string></entry>
|
||||
<entry><family>Presentation</family><string>impress_html_Export</string></entry>
|
||||
<entry><family>Spreadsheet</family><string>HTML (StarCalc)</string></entry>
|
||||
<entry><family>Text</family><string>HTML (StarWriter)</string></entry>
|
||||
</export-filters>
|
||||
|
@@ -405,6 +405,7 @@
|
||||
org.alfresco.service.cmr.repository.ContentService.getWriter=ACL_NODE.0.sys:base.WriteContent
|
||||
org.alfresco.service.cmr.repository.ContentService.isTransformable=ACL_ALLOW
|
||||
org.alfresco.service.cmr.repository.ContentService.getTransformer=ACL_ALLOW
|
||||
org.alfresco.service.cmr.repository.ContentService.getImageTransformer=ACL_ALLOW
|
||||
org.alfresco.service.cmr.repository.ContentService.transform=ACL_ALLOW
|
||||
org.alfresco.service.cmr.repository.ContentService.getTempWriter=ACL_ALLOW
|
||||
</value>
|
||||
|
@@ -169,7 +169,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
|
||||
// Calculate the destination name
|
||||
String originalName = (String)nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME);
|
||||
String newName = transformName(originalName, mimeType);
|
||||
String newName = transformName(this.mimetypeService, originalName, mimeType);
|
||||
|
||||
// Since we are overwriting we need to figure out whether the destination node exists
|
||||
NodeRef copyNodeRef = null;
|
||||
@@ -225,7 +225,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
String originalTitle = (String)nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_TITLE);
|
||||
if (originalTitle != null && originalTitle.length() > 0)
|
||||
{
|
||||
String newTitle = transformName(originalTitle, mimeType);
|
||||
String newTitle = transformName(this.mimetypeService, originalTitle, mimeType);
|
||||
nodeService.setProperty(copyNodeRef, ContentModel.PROP_TITLE, newTitle);
|
||||
}
|
||||
}
|
||||
@@ -267,11 +267,11 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
* Transform name from original extension to new extension
|
||||
*
|
||||
* @param original
|
||||
* @param originalMimetype
|
||||
* @param newMimetype
|
||||
* @return
|
||||
*
|
||||
* @return name with new extension as appropriate for the mimetype
|
||||
*/
|
||||
private String transformName(String original, String newMimetype)
|
||||
public static String transformName(MimetypeService mimetypeService, String original, String newMimetype)
|
||||
{
|
||||
// get the current extension
|
||||
int dotIndex = original.lastIndexOf('.');
|
||||
|
@@ -28,6 +28,7 @@ import org.alfresco.repo.content.ContentServicePolicies.OnContentUpdatePolicy;
|
||||
import org.alfresco.repo.content.filestore.FileContentStore;
|
||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||
import org.alfresco.repo.content.transform.ContentTransformerRegistry;
|
||||
import org.alfresco.repo.content.transform.magick.ImageMagickContentTransformer;
|
||||
import org.alfresco.repo.policy.ClassPolicyDelegate;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
@@ -72,6 +73,7 @@ public class RoutingContentService implements ContentService
|
||||
private ContentStore store;
|
||||
/** the store for all temporarily created content */
|
||||
private ContentStore tempStore;
|
||||
private ImageMagickContentTransformer imageMagickContentTransformer;
|
||||
|
||||
/**
|
||||
* The policy component
|
||||
@@ -122,6 +124,11 @@ public class RoutingContentService implements ContentService
|
||||
this.policyComponent = policyComponent;
|
||||
}
|
||||
|
||||
public void setImageMagickContentTransformer(ImageMagickContentTransformer imageMagickContentTransformer)
|
||||
{
|
||||
this.imageMagickContentTransformer = imageMagickContentTransformer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Service initialise
|
||||
*/
|
||||
@@ -385,6 +392,14 @@ public class RoutingContentService implements ContentService
|
||||
return transformer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.repository.ContentService#getImageTransformer()
|
||||
*/
|
||||
public ContentTransformer getImageTransformer()
|
||||
{
|
||||
return imageMagickContentTransformer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.content.transform.ContentTransformerRegistry
|
||||
* @see org.alfresco.repo.content.transform.ContentTransformer
|
||||
|
@@ -30,6 +30,8 @@ import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.executer.TransformActionExecuter;
|
||||
import org.alfresco.repo.content.transform.magick.ImageMagickContentTransformer;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
@@ -45,6 +47,7 @@ import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NoTransformerException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
@@ -1420,6 +1423,196 @@ public final class Node implements Serializable, Scopeable
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Transformation and Rendering API
|
||||
|
||||
/**
|
||||
* Transform a document to a new document mimetype format. A copy of the document is made and
|
||||
* the extension changed to match the new mimetype, then the transformation is applied.
|
||||
*
|
||||
* @param mimetype Mimetype destination for the transformation
|
||||
*
|
||||
* @return Node representing the newly transformed document.
|
||||
*/
|
||||
public Node transformDocument(String mimetype)
|
||||
{
|
||||
return transformDocument(mimetype, getPrimaryParentAssoc().getParentRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a document to a new document mimetype format. A copy of the document is made in the
|
||||
* specified destination folder and the extension changed to match the new mimetype, then then
|
||||
* transformation is applied.
|
||||
*
|
||||
* @param mimetype Mimetype destination for the transformation
|
||||
* @param destination Destination folder location
|
||||
*
|
||||
* @return Node representing the newly transformed document.
|
||||
*/
|
||||
public Node transformDocument(String mimetype, Node destination)
|
||||
{
|
||||
return transformDocument(mimetype, destination.getNodeRef());
|
||||
}
|
||||
|
||||
private Node transformDocument(String mimetype, NodeRef destination)
|
||||
{
|
||||
// the delegate definition for transforming a document
|
||||
Transformer transformer = new Transformer()
|
||||
{
|
||||
public Node transform(ContentService contentService, NodeRef nodeRef, ContentReader reader, ContentWriter writer)
|
||||
{
|
||||
Node transformedNode = null;
|
||||
if (contentService.isTransformable(reader, writer))
|
||||
{
|
||||
try
|
||||
{
|
||||
contentService.transform(reader, writer);
|
||||
transformedNode = new Node(nodeRef, services, imageResolver, scope);
|
||||
}
|
||||
catch (NoTransformerException err)
|
||||
{
|
||||
// failed to find a useful transformer - do not return a node instance
|
||||
}
|
||||
}
|
||||
return transformedNode;
|
||||
}
|
||||
};
|
||||
|
||||
return transformNode(transformer, mimetype, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method to transform Node content from one mimetype to another.
|
||||
*
|
||||
* @param transformer The Transformer delegate supplying the transformation logic
|
||||
* @param mimetype Mimetype of the destination content
|
||||
* @param destination Destination folder location for the resulting document
|
||||
*
|
||||
* @return Node representing the transformed content - or null if the transform failed
|
||||
*/
|
||||
private Node transformNode(Transformer transformer, String mimetype, NodeRef destination)
|
||||
{
|
||||
Node transformedNode = null;
|
||||
|
||||
// get the content reader
|
||||
ContentService contentService = this.services.getContentService();
|
||||
ContentReader reader = contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
|
||||
|
||||
// only perform the transformation if some content is available
|
||||
if (reader != null)
|
||||
{
|
||||
// Copy the content node to a new node
|
||||
NodeRef copyNodeRef = this.services.getCopyService().copy(
|
||||
this.nodeRef,
|
||||
destination,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
getPrimaryParentAssoc().getQName(),
|
||||
false);
|
||||
|
||||
// modify the name of the copy to reflect the new mimetype
|
||||
this.nodeService.setProperty(
|
||||
copyNodeRef,
|
||||
ContentModel.PROP_NAME,
|
||||
TransformActionExecuter.transformName(
|
||||
this.services.getMimetypeService(), getName(), mimetype));
|
||||
|
||||
// get the writer and set it up
|
||||
ContentWriter writer = contentService.getWriter(copyNodeRef, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(mimetype); // new mimetype
|
||||
writer.setEncoding(reader.getEncoding()); // original encoding
|
||||
|
||||
// Try and transform the content using the supplied delegate
|
||||
transformedNode = transformer.transform(contentService, copyNodeRef, reader, writer);
|
||||
}
|
||||
|
||||
return transformedNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an image to a new image format. A copy of the image document is made and
|
||||
* the extension changed to match the new mimetype, then the transformation is applied.
|
||||
*
|
||||
* @param mimetype Mimetype destination for the transformation
|
||||
*
|
||||
* @return Node representing the newly transformed image.
|
||||
*/
|
||||
public Node transformImage(String mimetype)
|
||||
{
|
||||
return transformImage(mimetype, null, getPrimaryParentAssoc().getParentRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an image to a new image format. A copy of the image document is made and
|
||||
* the extension changed to match the new mimetype, then the transformation is applied.
|
||||
*
|
||||
* @param mimetype Mimetype destination for the transformation
|
||||
* @param options Image convert command options
|
||||
*
|
||||
* @return Node representing the newly transformed image.
|
||||
*/
|
||||
public Node transformImage(String mimetype, String options)
|
||||
{
|
||||
return transformImage(mimetype, options, getPrimaryParentAssoc().getParentRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an image to a new image mimetype format. A copy of the image document is made in the
|
||||
* specified destination folder and the extension changed to match the new mimetype, then then
|
||||
* transformation is applied.
|
||||
*
|
||||
* @param mimetype Mimetype destination for the transformation
|
||||
* @param destination Destination folder location
|
||||
*
|
||||
* @return Node representing the newly transformed image.
|
||||
*/
|
||||
public Node transformImage(String mimetype, Node destination)
|
||||
{
|
||||
return transformImage(mimetype, null, destination.getNodeRef());
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an image to a new image mimetype format. A copy of the image document is made in the
|
||||
* specified destination folder and the extension changed to match the new mimetype, then then
|
||||
* transformation is applied.
|
||||
*
|
||||
* @param mimetype Mimetype destination for the transformation
|
||||
* @param options Image convert command options
|
||||
* @param destination Destination folder location
|
||||
*
|
||||
* @return Node representing the newly transformed image.
|
||||
*/
|
||||
public Node transformImage(String mimetype, String options, Node destination)
|
||||
{
|
||||
return transformImage(mimetype, options, destination.getNodeRef());
|
||||
}
|
||||
|
||||
private Node transformImage(String mimetype, final String options, NodeRef destination)
|
||||
{
|
||||
// the delegate definition for transforming an image
|
||||
Transformer transformer = new Transformer()
|
||||
{
|
||||
public Node transform(ContentService contentService, NodeRef nodeRef, ContentReader reader, ContentWriter writer)
|
||||
{
|
||||
Node transformedNode = null;
|
||||
try
|
||||
{
|
||||
Map<String, Object> opts = new HashMap<String, Object>(1);
|
||||
opts.put(ImageMagickContentTransformer.KEY_OPTIONS, options != null ? options : "");
|
||||
contentService.getImageTransformer().transform(reader, writer, opts);
|
||||
transformedNode = new Node(nodeRef, services, imageResolver, scope);
|
||||
}
|
||||
catch (NoTransformerException err)
|
||||
{
|
||||
// failed to find a useful transformer - do not return a node instance
|
||||
}
|
||||
return transformedNode;
|
||||
}
|
||||
};
|
||||
|
||||
return transformNode(transformer, mimetype, destination);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
@@ -1647,4 +1840,23 @@ public final class Node implements Serializable, Scopeable
|
||||
private ContentData contentData;
|
||||
private QName property;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interface contract for simple anonymous classes that implement document transformations
|
||||
*/
|
||||
private interface Transformer
|
||||
{
|
||||
/**
|
||||
* Transform the reader to the specified writer
|
||||
*
|
||||
* @param contentService ContentService
|
||||
* @param noderef NodeRef of the destination for the transform
|
||||
* @param reader Source reader
|
||||
* @param writer Destination writer
|
||||
*
|
||||
* @return Node representing the transformed entity
|
||||
*/
|
||||
Node transform(ContentService contentService, NodeRef noderef, ContentReader reader, ContentWriter writer);
|
||||
}
|
||||
}
|
@@ -126,6 +126,14 @@ public interface ContentService
|
||||
@Auditable(parameters = {"sourceMimetype", "targetMimetype"})
|
||||
public ContentTransformer getTransformer(String sourceMimetype, String targetMimetype);
|
||||
|
||||
/**
|
||||
* Fetch the transformer that is capable of transforming image content.
|
||||
*
|
||||
* @return Returns a transformer that can be used, or null if one was not available
|
||||
*/
|
||||
@Auditable
|
||||
public ContentTransformer getImageTransformer();
|
||||
|
||||
/**
|
||||
* Returns whether a transformer exists that can read the content from
|
||||
* the reader and write the content back out to the writer.
|
||||
|
Reference in New Issue
Block a user