Merged V4.1-BUG-FIX to HEAD

38065: ALF-13725: yui-genXXX appears in the warning message while changing file name 
   38113: Merged BRANCHES/DEV/CLOUD1 to BRANCHES/DEV/V4.1-BUG-FIX
      35857: Merged BRANCHES/DEV/THOR1 to BRANCHES/DEV/CLOUD1
         33050: THOR-427: Decrease log level of 'Login Failed'
   38117: Merged V4.1 to V4.1-BUG-FIX
      38087: ALF-14725: Merged V3.4-BUG-FIX to V4.1
         38086: ALF-14724: Upgrade to Java 1.6 u33
   38118: Missing semicolons
   38128: Merged V3.4-BUG-FIX to V4.1-BUG-FIX
      37821: Fix for ALF-13658 - Direct access (SSO) to share user dashboard with external authentication fails and user is prompted to log on when browsing
      37829: ALF-14340 CLONE: Alfresco crashes when viewing doclib / previewing - PDF with CMap
         This first part is general code (does not fix the specific issue) that could be merged to any branch.
         - TransformerDebug changes made to support investigation
         - Addition of 'supported mimetype transformations' to spring configuration (this is generally what people have thought EXPLICIT transformations were).
         - Tidy up of OpenOffice and JOD converters so that they don't say they can convert a mimetype to itself. There is a binary transformer that can just copy them.
           This also simplifies the Transformer debug output. 
      37831: ALF-14340 CLONE: Alfresco crashes when viewing doclib / previewing - PDF with CMap
         - missing file from last commit.
      37832: ALF-14340 CLONE: Alfresco crashes when viewing doclib / previewing - PDF with CMap
         This second part that fixes the specific issue with reconfiguration of the transformers used.
         - Configuration of transformers changed to use ImageMagick with Ghostscript rather than PDFBox and PDFRenderer.
           The same transformations should be possible after this change. No combinations have been removed or added.
         - ImageMagick with Ghostscript now replaces both PDFBox and PDFRenderer for PDF to PNG.
         - A single or double ImageMagick with Ghostscript transformation (fails over to double when not possible with a
           single transformation) is now used by transformer.complex.PDF.Image
         - ImageMagick with Ghostscript rather than transformer.complex.PDF.Image now declares itself as having an EXPLICIT
           transformation for PDF to PNG. So normally there is no need to even look at the more complicated
           transformer.complex.PDF.Image unless it is included as a component of another transformer (there are 3).
         - PDFRenderer and 3rd party libs were only being used for PDF to PNG, so could be removed.
           NOT REMOVED AT THIS STAGE TO ALLOW CUSTOMISATION USE AND WORKAROUNDS OF ANY ISSUED THAT MIGHT BE FOUND.
         - PDFBox is still required for text to PDF, PDF to Text and metadata extraction.
         - Tidy up transformer.PdfBox.TextToPdf so that it does not declare csv to pdf and xml to pdf as EXPLICIT as
           this is the only transformer that can do it.
      37834: ALF-10518 - Improvements to tagQuery.get.js for the Repository use case to remove the need to add //* PATH for CompanyHome query.
      37835: Fix for ALF-14429 - Recently Modified dashlet takes up to 30 seconds to load after upgrade to Alfresco 3.4.6.23
      37858: Merged V3.4 to V3.4-BUG-FIX (RECORD ONLY)
         37592: Merged V3.4-BUG-FIX to V3.4 (3.4.10)
            35103: Merged DEV to V3.4-BUG-FIX
         37789: Merged V3.4-BUG-FIX to V3.4
            37788: Second part of fix from Alex Mukha for ALF-11714
         37841: ALF-14524: Merged PATCHES/V3.4.9 to V3.4
            37840: ALF-14589: ALF-9861 breaks the JSON based error reporting for document library actions (by custom actions and code) 
               - Fix by Mr Roast
      37865: Merged DEV to V3.4-BUG-FIX (with corrections)
         37845: ALF-13929: Error during processing of the 'show audit' template after upgrade
            New patch that updates show_audit.ftl to the newest version during upgrade
      37877: Correction to corrections:
      37865: Merged DEV to V3.4-BUG-FIX (with corrections)
         37845: ALF-13929: Error during processing of the 'show audit' template after upgrade
            New patch that updates show_audit.ftl to the newest version during upgrade
      37918: Merged DEV to V3.4-BUG-FIX
         37548: ALF-11124: English language bundle properties have _en_US suffix
            Updated ant scripts to create properties files without _US suffix.
      38090: ALF-14699: Merged DEV to V3.4-BUGFIX
         38070: Search in Alfresco Explorer does not work
      38124: Merged V3.4 to V3.4-BUG-FIX (RECORD ONLY)
         38092: Merged V3.4-BUG-FIX to V3.4
            38090: : Merged DEV to V3.4-BUGFIX
               38070: ALF-14699: Search in Alfresco Explorer does not work


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@38135 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2012-06-21 16:58:32 +00:00
parent efea3399ee
commit 3ba7ffcca0
18 changed files with 446 additions and 524 deletions

View File

@@ -318,24 +318,6 @@
</property> </property>
</bean> </bean>
<!-- These transformers are not used alone but only as part of a failover sequence -->
<!-- For this reason they do not extend the baseContentTransformer bean and so will not be registered. -->
<bean id="failover.transformer.PdfRenderer.PdfToImage"
class="org.alfresco.repo.content.transform.PdfToImageContentTransformer"
parent="unregisteredBaseContentTransformer" />
<bean id="failover.transformer.PdfBox.PdfToImage"
class="org.alfresco.repo.content.transform.PdfBoxPdfToImageContentTransformer"
parent="unregisteredBaseContentTransformer" />
<bean id="failover.transformer.ImageMagick"
class="org.alfresco.repo.content.transform.ProxyContentTransformer"
parent="unregisteredBaseContentTransformer" >
<property name="worker">
<ref bean="transformer.worker.ImageMagick" />
</property>
</bean>
<!-- Content Transformations --> <!-- Content Transformations -->
<bean id="transformer.StringExtracter" <bean id="transformer.StringExtracter"
class="org.alfresco.repo.content.transform.StringExtractingContentTransformer" class="org.alfresco.repo.content.transform.StringExtractingContentTransformer"
@@ -397,48 +379,128 @@
</property> </property>
</bean> </bean>
<bean id="transformer.PdfToImage" <!-- Supports the same transformations as the previous version by using either a single
class="org.alfresco.repo.content.transform.FailoverPdfToImageContentTransformer" ImageMagick transformation to png or two ImageMagick transformation via png. -->
parent="baseContentTransformer" >
<property name="transformers">
<list>
<ref bean="failover.transformer.PdfRenderer.PdfToImage"/>
<ref bean="failover.transformer.ImageMagick"/>
<ref bean="failover.transformer.PdfBox.PdfToImage"/>
</list>
</property>
</bean>
<bean id="transformer.complex.PDF.Image" <bean id="transformer.complex.PDF.Image"
class="org.alfresco.repo.content.transform.ComplexContentTransformer" class="org.alfresco.repo.content.transform.FailoverContentTransformer"
parent="baseComplexContentTransformer" > parent="baseContentTransformer" >
<property name="supportedTransformations">
<list>
<!-- Requires a single ImageMagick transformation.
Not used unless called as part of another transformer as
the ImageMagick transformation declares this as EXPLICIT
so take priority. -->
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/png</value></property>
</bean>
<!-- Requires a double ImageMagick transformation via png -->
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>application/eps</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/jp2</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/cgm</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/gif</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/ief</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/bmp</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/jpeg</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-portable-bitmap</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-portable-graymap</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-portable-anymap</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-portable-pixmap</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-cmu-raster</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/tiff</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-xbitmap</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-xpixmap</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-xwindowdump</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-dwg</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.SupportedTransformation" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/x-dwt</value></property>
</bean>
</list>
</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" >
<property name="sourceMimetype"><value>application/pdf</value></property> <property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/jpeg</value></property> <property name="targetMimetype"><value>image/jpeg</value></property>
</bean> </bean>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/png</value></property>
</bean>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" > <bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<property name="sourceMimetype"><value>application/pdf</value></property> <property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/gif</value></property> <property name="targetMimetype"><value>image/gif</value></property>
</bean> </bean>
</list> </list>
</property> </property>
<property name="transformers"> <property name="transformers">
<list> <list>
<ref bean="transformer.PdfToImage" /> <ref bean="transformer.ImageMagick"/>
<ref bean="transformer.ImageMagick" />
</list> <bean class="org.alfresco.repo.content.transform.ComplexContentTransformer"
</property> parent="unregisteredBaseContentTransformer" >
<property name="intermediateMimetypes"> <property name="transformers">
<list> <list>
<value>image/png</value> <ref bean="transformer.ImageMagick" />
</list> <ref bean="transformer.ImageMagick" />
</property> </list>
</property>
<property name="intermediateMimetypes">
<list>
<value>image/png</value>
</list>
</property>
</bean>
</list>
</property>
</bean> </bean>
<!-- Recent Adobe Illustrator files are, in fact, PDF files --> <!-- Recent Adobe Illustrator files are, in fact, PDF files -->
@@ -550,14 +612,6 @@
<constructor-arg><value>text/plain</value></constructor-arg> <constructor-arg><value>text/plain</value></constructor-arg>
<constructor-arg><value>application/pdf</value></constructor-arg> <constructor-arg><value>application/pdf</value></constructor-arg>
</bean> </bean>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<constructor-arg><value>text/csv</value></constructor-arg>
<constructor-arg><value>application/pdf</value></constructor-arg>
</bean>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<constructor-arg><value>text/xml</value></constructor-arg>
<constructor-arg><value>application/pdf</value></constructor-arg>
</bean>
</list> </list>
</property> </property>
<property name="maxSourceSizeKBytes"><value>${content.transformer.PdfBox.TextToPdf.maxSourceSizeKBytes}</value></property> <property name="maxSourceSizeKBytes"><value>${content.transformer.PdfBox.TextToPdf.maxSourceSizeKBytes}</value></property>
@@ -819,6 +873,14 @@
<property name="worker"> <property name="worker">
<ref bean="transformer.worker.ImageMagick" /> <ref bean="transformer.worker.ImageMagick" />
</property> </property>
<property name="explicitTransformations">
<list>
<bean class="org.alfresco.repo.content.transform.ExplictTransformationDetails" >
<property name="sourceMimetype"><value>application/pdf</value></property>
<property name="targetMimetype"><value>image/png</value></property>
</bean>
</list>
</property>
</bean> </bean>
<!-- This transformer allows for the indexing and therefore searching of zip files. --> <!-- This transformer allows for the indexing and therefore searching of zip files. -->

View File

@@ -478,4 +478,6 @@ patch.swsdpPatch.success=Successfully patched the Sample: Web Site Design Projec
patch.swsdpPatch.skipped=Skipped, not required. patch.swsdpPatch.skipped=Skipped, not required.
patch.swsdpPatch.missingSurfConfig=surf-config folder is not present in Sample: Web Site Design Project. patch.swsdpPatch.missingSurfConfig=surf-config folder is not present in Sample: Web Site Design Project.
patch.redeployParallelActivitiWorkflows.description=Patch that redeploys both parallel activiti workflows, completion-condition now takes into account if minimum approval percentage can still be achived. patch.redeployParallelActivitiWorkflows.description=Patch that redeploys both parallel activiti workflows, completion-condition now takes into account if minimum approval percentage can still be achived.
patch.show.audit.success=show_audit.ftl was updated successfully

View File

@@ -3233,4 +3233,25 @@
</property> </property>
</bean> </bean>
<bean id="patch.show.audit" class="org.alfresco.repo.admin.patch.impl.UpdateAuditTemplatePatch" parent="basePatch" >
<property name="id"><value>patch.show.audit</value></property>
<property name="description"><value>patch.show.audit.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>6011</value></property>
<property name="targetSchema"><value>6012</value></property>
<!-- bootstrap view -->
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="contentService">
<ref bean="ContentService" />
</property>
<property name="copyPath">
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname}/cm:show_audit.ftl</value>
</property>
<property name="fileName">
<value>alfresco/templates/content/examples/show_audit.ftl</value>
</property>
</bean>
</beans> </beans>

View File

@@ -19,4 +19,4 @@ version.build=@build-number@
# Schema number # Schema number
version.schema=6011 version.schema=6012

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.InputStream;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Updates show_audit.ftl file for upgrade from v3.3.5 to v3.4.x (ALF-13929)
* @author alex.malinovsky
*
*/
public class UpdateAuditTemplatePatch extends AbstractPatch
{
private static final String ERR_MULTIPLE_FOUND = "Multiple files for replacement were found";
public static final String TEXT_CONTENT_MIMETYPE = "text/plain";
private static final String MSG_CREATED = "patch.show.audit.success";
private ImporterBootstrap importerBootstrap;
private ContentService contentService;
private String copyPath;
private String fileName;
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
public void setCopyPath(String copyPath)
{
this.copyPath = copyPath;
}
public void setFileName(String fileName)
{
this.fileName = fileName;
}
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
@Override
protected String applyInternal() throws Exception
{
StoreRef storeRef = importerBootstrap.getStoreRef();
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
List<NodeRef> results = searchService.selectNodes(rootNodeRef, copyPath, null, namespaceService, true);
if (results.size() > 1)
{
throw new PatchException(ERR_MULTIPLE_FOUND, copyPath);
}
else if (results.size() == 1)
{
makeCopy(results.get(0));
return I18NUtil.getMessage(MSG_CREATED);
}
return null;
}
private void makeCopy(NodeRef nodeRef)
{
InputStream resource = getClass().getClassLoader().getResourceAsStream(fileName);
if (resource != null)
{
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
writer.setEncoding("UTF-8");
writer.setMimetype(TEXT_CONTENT_MIMETYPE);
writer.putContent(resource);
}
else throw new PatchException("Resource '"+fileName+"' not found");
}
}

View File

@@ -776,14 +776,16 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
MimetypeMap.MIMETYPE_IMAGE_PNG.equals(targetMimetype) && MimetypeMap.MIMETYPE_IMAGE_PNG.equals(targetMimetype) &&
"debugTransformers.txt".equals(transformerDebug.getFileName(transformOptions, true, 0))) "debugTransformers.txt".equals(transformerDebug.getFileName(transformOptions, true, 0)))
{ {
debugActiveTransformers(); Map<String, Set<String>> explicitTransforms = debugExplicitTransforms();
debugActiveTransformersByTransformer(explicitTransforms);
debugActiveTransformersByMimetypes(explicitTransforms);
} }
} }
/** /**
* Creates TransformerDebug that lists all the supported mimetype transformation for each transformer. * Creates TransformerDebug that lists all the supported mimetype transformation for each transformer.
*/ */
private void debugActiveTransformers() private void debugActiveTransformersByTransformer(Map<String, Set<String>> explicitTransforms)
{ {
try try
{ {
@@ -791,8 +793,6 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
transformerDebug.debug("Active and inactive transformers"); transformerDebug.debug("Active and inactive transformers");
TransformationOptions options = new TransformationOptions(); TransformationOptions options = new TransformationOptions();
Map<String, Set<String>> explicitTransforms = debugExplicitTransforms();
for (ContentTransformer transformer: transformerRegistry.getTransformers()) for (ContentTransformer transformer: transformerRegistry.getTransformers())
{ {
try try
@@ -843,6 +843,62 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
} }
} }
/**
* Creates TransformerDebug that lists all available transformers for each mimetype combination.
*/
private void debugActiveTransformersByMimetypes(Map<String, Set<String>> explicitTransforms)
{
try
{
transformerDebug.pushMisc();
transformerDebug.debug("Transformers for each mimetype combination");
TransformationOptions options = new TransformationOptions();
for (String sourceMimetype : mimetypeService.getMimetypes())
{
for (String targetMimetype : mimetypeService.getMimetypes())
{
try
{
transformerDebug.pushMisc();
int transformerCount = 0;
for (ContentTransformer transformer: transformerRegistry.getTransformers())
{
if (transformer.isTransformable(sourceMimetype, -1, targetMimetype, options))
{
long maxSourceSizeKBytes = transformer.getMaxSourceSizeKBytes(
sourceMimetype, targetMimetype, options);
// Is this an explicit transform, ignored because there are explicit transforms
// or does not have explicit transforms.
Boolean explicit = transformer.isExplicitTransformation(sourceMimetype,
targetMimetype, options);
if (!explicit)
{
Set<String> targetMimetypes = explicitTransforms.get(sourceMimetype);
explicit = (targetMimetypes == null || !targetMimetypes.contains(targetMimetype))
? null
: Boolean.FALSE;
}
transformerDebug.activeTransformer(sourceMimetype, targetMimetype,
transformerCount, transformer, maxSourceSizeKBytes, explicit,
transformerCount++ == 0);
}
}
}
finally
{
transformerDebug.popMisc();
}
}
}
}
finally
{
transformerDebug.popMisc();
}
}
/** /**
* Returns the explicit mimetype transformations. Key is the source mimetype * Returns the explicit mimetype transformations. Key is the source mimetype
* and the value is a set of target mimetypes that are explicit. * and the value is a set of target mimetypes that are explicit.

View File

@@ -103,6 +103,7 @@ public abstract class AbstractContentTransformerLimits extends ContentTransforme
// though they cannot transform the source to the target mimetype. // though they cannot transform the source to the target mimetype.
return return
isSupportedTransformation(sourceMimetype, targetMimetype, options) &&
isTransformableMimetype(sourceMimetype, targetMimetype, options) && isTransformableMimetype(sourceMimetype, targetMimetype, options) &&
isTransformableSize(sourceMimetype, sourceSize, targetMimetype, options); isTransformableSize(sourceMimetype, sourceSize, targetMimetype, options);
} }
@@ -112,7 +113,6 @@ public abstract class AbstractContentTransformerLimits extends ContentTransforme
* to the target mimetype. * to the target mimetype.
*/ */
@Override @Override
@SuppressWarnings("deprecation")
public boolean isTransformableMimetype(String sourceMimetype, String targetMimetype, TransformationOptions options) public boolean isTransformableMimetype(String sourceMimetype, String targetMimetype, TransformationOptions options)
{ {
return isTransformable(sourceMimetype, targetMimetype, options); return isTransformable(sourceMimetype, targetMimetype, options);

View File

@@ -174,6 +174,11 @@ public class ComplexContentTransformer extends AbstractContentTransformer2 imple
public boolean isTransformable(String sourceMimetype, long sourceSize, String targetMimetype, public boolean isTransformable(String sourceMimetype, long sourceSize, String targetMimetype,
TransformationOptions options) TransformationOptions options)
{ {
if (!isSupportedTransformation(sourceMimetype, targetMimetype, options))
{
return false;
}
// Don't allow transformer to be its own child. // Don't allow transformer to be its own child.
if (parentTransformers.get().contains(this)) if (parentTransformers.get().contains(this))
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2012 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -37,6 +37,7 @@ public class ContentTransformerHelper
private MimetypeService mimetypeService; private MimetypeService mimetypeService;
private List<ExplictTransformationDetails> explicitTransformations; private List<ExplictTransformationDetails> explicitTransformations;
private List<SupportedTransformation> supportedTransformations;
/** /**
* *
@@ -44,6 +45,7 @@ public class ContentTransformerHelper
public ContentTransformerHelper() public ContentTransformerHelper()
{ {
setExplicitTransformations(Collections.<ExplictTransformationDetails> emptyList()); setExplicitTransformations(Collections.<ExplictTransformationDetails> emptyList());
setSupportedTransformations(null);
} }
/** /**
@@ -64,11 +66,28 @@ public class ContentTransformerHelper
return mimetypeService; return mimetypeService;
} }
/**
* Specifies transformations that are considered to be 'exceptional' so
* should be used in preference to other transformers that can perform
* the same transformation.
*/
public void setExplicitTransformations(List<ExplictTransformationDetails> explicitTransformations) public void setExplicitTransformations(List<ExplictTransformationDetails> explicitTransformations)
{ {
this.explicitTransformations = explicitTransformations; this.explicitTransformations = explicitTransformations;
} }
/**
* Restricts the transformations that may be performed even though the transformer
* may perform other transformations. An null value applies no additional restrictions.
* Even if a list is specified, the
* {@link ContentTransformer#isTransformableMimetype(String, String, TransformationOptions)}
* method will still be called.
*/
public void setSupportedTransformations(List<SupportedTransformation> supportedTransformations)
{
this.supportedTransformations = supportedTransformations;
}
/** /**
* Convenience to fetch and check the mimetype for the given content * Convenience to fetch and check the mimetype for the given content
* *
@@ -110,4 +129,22 @@ public class ContentTransformerHelper
return result; return result;
} }
public boolean isSupportedTransformation(String sourceMimetype, String targetMimetype, TransformationOptions options)
{
boolean result = true;
if (supportedTransformations != null)
{
result = false;
for (SupportedTransformation suportedTransformation : supportedTransformations)
{
if (sourceMimetype.equals(suportedTransformation.getSourceMimetype()) == true
&& targetMimetype.equals(suportedTransformation.getTargetMimetype()) == true)
{
result = true;
break;
}
}
}
return result;
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2012 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -18,38 +18,20 @@
*/ */
package org.alfresco.repo.content.transform; package org.alfresco.repo.content.transform;
public class ExplictTransformationDetails /**
* Specifies transformations that are considered to be 'exceptional' so
* should be used in preference to other transformers that can perform
* the same transformation.
*/
public class ExplictTransformationDetails extends SupportedTransformation
{ {
private String sourceMimetype;
private String targetMimetype;
public ExplictTransformationDetails() public ExplictTransformationDetails()
{ {
super();
} }
public ExplictTransformationDetails(String sourceMimetype, String targetMimetype) public ExplictTransformationDetails(String sourceMimetype, String targetMimetype)
{ {
this.sourceMimetype = sourceMimetype; super(sourceMimetype, targetMimetype);
this.targetMimetype = targetMimetype;
}
public void setSourceMimetype(String sourceMimetype)
{
this.sourceMimetype = sourceMimetype;
}
public String getSourceMimetype()
{
return sourceMimetype;
}
public void setTargetMimetype(String targetMimetype)
{
this.targetMimetype = targetMimetype;
}
public String getTargetMimetype()
{
return targetMimetype;
} }
} }

View File

@@ -88,9 +88,11 @@ public class FailoverContentTransformer extends AbstractContentTransformer2 impl
@Override @Override
public boolean isTransformable(String sourceMimetype, long sourceSize, String targetMimetype, TransformationOptions options) public boolean isTransformable(String sourceMimetype, long sourceSize, String targetMimetype, TransformationOptions options)
{ {
return // isTransformableSize must check the mimetype anyway return
((sourceSize >= 0) && isTransformableSize(sourceMimetype, sourceSize, targetMimetype, options)) || isSupportedTransformation(sourceMimetype, targetMimetype, options) &&
((sourceSize < 0) && isTransformableMimetype(sourceMimetype,targetMimetype, options)); // isTransformableSize must check the mimetype anyway
(((sourceSize >= 0) && isTransformableSize(sourceMimetype, sourceSize, targetMimetype, options)) ||
((sourceSize < 0) && isTransformableMimetype(sourceMimetype,targetMimetype, options)));
} }
@Override @Override

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.content.transform;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.TransformationOptions;
/**
* ALF-14303 Only support PDF to PNG rather than all the possible transformations from transformer.worker.ImageMagick
*/
public class FailoverPdfToImageContentTransformer extends FailoverContentTransformer
{
@Override
public boolean isTransformableMimetype(String sourceMimetype, String targetMimetype, TransformationOptions options)
{
return MimetypeMap.MIMETYPE_PDF.equals(sourceMimetype) &&
MimetypeMap.MIMETYPE_IMAGE_PNG.equals(targetMimetype);
}
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2012 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -136,6 +136,12 @@ public class OpenOfficeContentTransformerWorker extends OOoContentTransformerHel
*/ */
public boolean isTransformable(String sourceMimetype, String targetMimetype, TransformationOptions options) public boolean isTransformable(String sourceMimetype, String targetMimetype, TransformationOptions options)
{ {
// Use BinaryPassThroughContentTransformer if mimetypes are the same.
if (sourceMimetype.equals(targetMimetype))
{
return false;
}
if (!isAvailable()) if (!isAvailable())
{ {
// The connection management is must take care of this // The connection management is must take care of this

View File

@@ -1,127 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.content.transform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
/**
* Makes use of the {@link http://www.pdfbox.org/ PDFBox} library to
* perform conversions from PDF files to images.
*
* @author Neil McErlean
*/
public class PdfBoxPdfToImageContentTransformer extends AbstractContentTransformer2
{
/**
* The PDF spec allows for a default user password of the empty string.
* See PDF Specification section 3.5 "Password Algorithms", specifically algorithms 3.6
*/
private static final String PDF_DEFAULT_PASSWORD = "";
private static Log logger = LogFactory.getLog(PdfBoxPdfToImageContentTransformer.class);
@Override
public boolean isTransformableMimetype(String sourceMimetype, String targetMimetype, TransformationOptions options)
{
// only support PDF -> PNG OR Adobe Illustrator -> PNG.
// Recent .ai file format is a .pdf file.
return ( (MimetypeMap.MIMETYPE_PDF.equals(sourceMimetype) ||
MimetypeMap.MIMETYPE_APPLICATION_ILLUSTRATOR.equals(sourceMimetype))
&& MimetypeMap.MIMETYPE_IMAGE_PNG.equals(targetMimetype));
}
@SuppressWarnings("unchecked")
protected void transformInternal(
ContentReader reader,
ContentWriter writer,
TransformationOptions options) throws Exception
{
PDDocument document = null;
try
{
File file = TempFileProvider.createTempFile("pdfToImage", ".pdf");
reader.getContent(file);
document = PDDocument.load(file);
if (document.isEncrypted())
{
// Encrypted means password-protected, but PDF allows for two passwords: "owner" and "user".
// A "user" of a document should be able to read (but not modify) the content.
//
// We'll attempt to open the document using the common PDF default password.
document.openProtection(new StandardDecryptionMaterial(PDF_DEFAULT_PASSWORD));
}
boolean canExtractContent = document.getCurrentAccessPermission().canExtractContent();
if (!canExtractContent)
{
String msg = "PDF document's intrinsic permissions forbid content extraction.";
if (logger.isDebugEnabled())
{
logger.debug(msg);
}
throw new AlfrescoRuntimeException(msg);
}
final int resolution = 16; // A rather arbitrary number for resolution (DPI) here.
List pages = document.getDocumentCatalog().getAllPages();
PDPage page = (PDPage)pages.get(0);
BufferedImage img = page.convertToImage(BufferedImage.TYPE_INT_ARGB, resolution);
File outputFile = TempFileProvider.createTempFile(this.getClass().getSimpleName(), ".png");
ImageIO.write(img, "png", outputFile);
writer.putContent(outputFile);
}
catch (FileNotFoundException e1)
{
throw new AlfrescoRuntimeException("Unable to create image from pdf file.", e1);
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Unable to create image from pdf file.", e);
}
finally
{
if( document != null )
{
document.close();
}
}
}
}

View File

@@ -1,119 +0,0 @@
/*
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.content.transform;
import java.io.File;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.repo.content.filestore.FileContentWriter;
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;
/**
* Tests for {@link PdfBoxPdfToImageContentTransformer}.
*
* @author Neil Mc Erlean
* @since 3.4.2.
*/
public class PdfBoxPdfToImageContentTransformerTest extends AbstractContentTransformerTest
{
private PdfBoxPdfToImageContentTransformer transformer;
@Override
public void setUp() throws Exception
{
super.setUp();
transformer = new PdfBoxPdfToImageContentTransformer();
transformer.setMimetypeService(mimetypeService);
transformer.setTransformerDebug(transformerDebug);
}
/**
* @return Returns the same transformer regardless - it is allowed
*/
protected ContentTransformer getTransformer(String sourceMimetype, String targetMimetype)
{
return transformer;
}
public void testIsTransformable() throws Exception
{
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_PDF, -1, MimetypeMap.MIMETYPE_IMAGE_PNG, new TransformationOptions()));
}
/**
* This test method checks that the PDFBox-based transformer is able to extract image content from a secured PDF file.
* See ALF-6650.
*
* @since 3.4.2
*/
public void testExtractContentFromSecuredPdf() throws Exception
{
File securePdfFile = loadNamedQuickTestFile("quick-secured.pdf");
assertNotNull("test file was null.", securePdfFile);
ContentReader reader = new FileContentReader(securePdfFile);
reader.setMimetype(MimetypeMap.MIMETYPE_PDF);
reader.setEncoding("UTF-8");
ContentWriter writer = new FileContentWriter(TempFileProvider.createTempFile(this.getClass().getSimpleName() + System.currentTimeMillis(), "txt"));
writer.setMimetype(MimetypeMap.MIMETYPE_IMAGE_PNG);
writer.setEncoding("UTF-8");
transformer.transform(reader, writer);
// get a reader onto the transformed content and check - although the real test here is that exceptions weren't thrown during transformation.
ContentReader checkReader = writer.getReader();
checkReader.setMimetype(MimetypeMap.MIMETYPE_IMAGE_PNG);
assertTrue("PNG output was empty", checkReader.getContentData().getSize() != 0l);
}
/**
* This test method checks that the PDFBox-based transformer is able to transform an Adobe Illustrator file to image.
* Adobe Illustrator files (.ai) have been PostScript files in the past, but are now just pdf files.
*
* @since 3.5.0
*/
public void testTransformAdobeIllustrator() throws Exception
{
for (String quickFile : new String[]{"quickCS3.ai", "quickCS5.ai"})
{
File aiFile = loadNamedQuickTestFile(quickFile);
assertNotNull("test file was null.", aiFile);
ContentReader reader = new FileContentReader(aiFile);
reader.setMimetype(MimetypeMap.MIMETYPE_APPLICATION_ILLUSTRATOR);
reader.setEncoding("UTF-8");
ContentWriter writer = new FileContentWriter(TempFileProvider
.createTempFile(this.getClass().getSimpleName()
+ System.currentTimeMillis(), "txt"));
writer.setMimetype(MimetypeMap.MIMETYPE_IMAGE_PNG);
writer.setEncoding("UTF-8");
transformer.transform(reader, writer);
// get a reader onto the transformed content and check - although the real test here is that exceptions weren't thrown during transformation.
ContentReader checkReader = writer.getReader();
checkReader.setMimetype(MimetypeMap.MIMETYPE_IMAGE_PNG);
assertTrue("PNG output was empty", checkReader.getContentData()
.getSize() != 0l);
}
}
}

View File

@@ -1,149 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.content.transform;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import javax.imageio.ImageIO;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.MimetypeMap;
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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
/**
* Makes use of the {@link https://pdf-renderer.dev.java.net/ PDFRenderer} library to
* perform conversions from PDF files to images.
*
* @author Roy Wetherall
*/
public class PdfToImageContentTransformer extends AbstractContentTransformer2
{
private static final Log logger = LogFactory.getLog(PdfToImageContentTransformer.class);
/**
* Currently the only transformation performed is that of text extraction from PDF documents.
*/
@Override
public boolean isTransformableMimetype(String sourceMimetype, String targetMimetype, TransformationOptions options)
{
// only support PDF -> PNG OR Adobe Illustrator -> PNG.
// .ai is really just a .pdf file anyway
return ( (MimetypeMap.MIMETYPE_PDF.equals(sourceMimetype) ||
MimetypeMap.MIMETYPE_APPLICATION_ILLUSTRATOR.equals(sourceMimetype))
&& MimetypeMap.MIMETYPE_IMAGE_PNG.equals(targetMimetype));
}
protected void transformInternal(
ContentReader reader,
ContentWriter writer,
TransformationOptions options) throws Exception
{
RandomAccessFile raf = null;
try
{
File file = TempFileProvider.createTempFile("pdfToImage", ".pdf");
reader.getContent(file);
raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new PDFFile(buf);
// Log the PDF version of the file being transformed.
if (logger.isInfoEnabled())
{
int pdfMajorVersion = pdffile.getMajorVersion();
int pdfMinorVersion = pdffile.getMinorVersion();
StringBuilder msg = new StringBuilder();
msg.append("File being transformed is of pdf version ")
.append(pdfMajorVersion).append(".").append(pdfMinorVersion);
logger.info(msg.toString());
}
PDFPage page = pdffile.getPage(0, true);
if (page == null)
{
throw new AlfrescoRuntimeException("Unable to create image from pdf file."+
"A PDFRender error took place which should have been sent to stdout.");
}
//get the width and height for the doc at the default zoom
int width=(int)page.getBBox().getWidth();
int height=(int)page.getBBox().getHeight();
Rectangle rect = new Rectangle(0,0,width,height);
int rotation=page.getRotation();
Rectangle rect1=rect;
if (rotation==90 || rotation==270)
rect1=new Rectangle(0,0,rect.height,rect.width);
//generate the image
BufferedImage img = (BufferedImage)page.getImage(
rect.width, rect.height, //width & height
rect1, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true // block until drawing is done
);
File outputFile = TempFileProvider.createTempFile("pdfToImageOutput", ".png");
ImageIO.write(img, "png", outputFile);
writer.putContent(outputFile);
}
catch (FileNotFoundException e1)
{
throw new AlfrescoRuntimeException("Unable to create image from pdf file.", e1);
}
catch (Exception e)
{
throw new AlfrescoRuntimeException("Unable to create image from pdf file. "+e.getMessage(), e);
}
finally
{
if (raf != null)
{
try
{
raf.close();
}
catch (IOException ignored)
{
// Intentionally empty
}
}
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.content.transform;
/**
* Represents a supported transformation. Normally used in a spring bean that limits
* the number of supported configures.
*/
public class SupportedTransformation
{
private String sourceMimetype;
private String targetMimetype;
public SupportedTransformation()
{
}
public SupportedTransformation(String sourceMimetype, String targetMimetype)
{
this.sourceMimetype = sourceMimetype;
this.targetMimetype = targetMimetype;
}
public void setSourceMimetype(String sourceMimetype)
{
this.sourceMimetype = sourceMimetype;
}
public String getSourceMimetype()
{
return sourceMimetype;
}
public void setTargetMimetype(String targetMimetype)
{
this.targetMimetype = targetMimetype;
}
public String getTargetMimetype()
{
return targetMimetype;
}
}

View File

@@ -356,6 +356,21 @@ public class TransformerDebug
(explicit == null ? "" : explicit ? " EXPLICIT" : " not explicit")); (explicit == null ? "" : explicit ? " EXPLICIT" : " not explicit"));
} }
public void activeTransformer(String sourceMimetype, String targetMimetype,
int transformerCount, ContentTransformer transformer, long maxSourceSizeKBytes,
Boolean explicit, boolean firstTransformer)
{
String mimetypes = firstTransformer
? getMimetypeExt(sourceMimetype)+getMimetypeExt(targetMimetype)
: spaces(10);
char c = (char)('a'+transformerCount);
log(mimetypes+
" "+c+") "+getName(transformer)+' '+ms(transformer.getTransformationTime())+
' '+fileSize((maxSourceSizeKBytes > 0) ? maxSourceSizeKBytes*1024 : maxSourceSizeKBytes)+
(maxSourceSizeKBytes == 0 || (explicit != null && !explicit) ? " disabled" : "")+
(explicit == null ? "" : explicit ? " EXPLICIT" : " not explicit"));
}
private int getLongestTransformerNameLength(List<ContentTransformer> transformers, private int getLongestTransformerNameLength(List<ContentTransformer> transformers,
Frame frame) Frame frame)
{ {