mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
MNT-14316 2013/2014 iWork Transformation Failure
* Support the creation of thumbnails for 2008/9 and 2013/14 iWorks file types. * Support the preview of 2008/9 and 2013/14 iWorks file types. It should be noted that the embedded PDF files from 2008/9 no longer are used for the preview, so the quality is not as good as it was in the past. It is however using the embedded JPEG and quality is reasonable. * AppleIWorksContentTransformer no longer supports PDF as an target mimetype, as the newer iWoks 2013/14 formats no longer includes an embedded PDF file. Having PDF supported by the transformer resulted in Share always trying PDF which was one of the reasons that the newer formats did not preview. The other reason was that the embedded JPEG filename also changed. * Added 'quick' files for testing. * Also modified the exception message thrown when the iWorks file did not contain an embedded preview file, which is optional. An example would is "The source numbers file did not contain a jpg preview", rather than "Unable to transform numbers file to jpg". This should reduce the number of issues raised with support. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@135869 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
BIN
config/quick/quick.key
Normal file
BIN
config/quick/quick.key
Normal file
Binary file not shown.
BIN
config/quick/quick.numbers
Normal file
BIN
config/quick/quick.numbers
Normal file
Binary file not shown.
BIN
config/quick/quick.pages
Normal file
BIN
config/quick/quick.pages
Normal file
Binary file not shown.
BIN
config/quick/quick2009.pages
Normal file
BIN
config/quick/quick2009.pages
Normal file
Binary file not shown.
@@ -1,35 +1,30 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
@@ -40,10 +35,16 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Converts Apple iWorks files to PDFs or JPEGs for thumbnailing & previewing.
|
||||
* The transformer will only work for iWorks 09 files and later as previous versions of those files
|
||||
* were actually saved as directories.
|
||||
* Converts Apple iWorks files to JPEGs for thumbnailing & previewing.
|
||||
* The transformer will only work for iWorks 2013/14 files. Support for iWorks 2008/9 has been dropped as we cannot
|
||||
* support both, because the newer format does not contain a PDF. If we say this transformer supports PDF, Share will
|
||||
* assume incorrectly that we can convert to PDF and we would only get a preview for the older format and never the
|
||||
* newer one. Both formats have the same mimetype.
|
||||
*
|
||||
* @author Neil Mc Erlean
|
||||
* @since 4.0
|
||||
@@ -51,23 +52,29 @@ import org.apache.commons.logging.LogFactory;
|
||||
public class AppleIWorksContentTransformer extends AbstractContentTransformer2
|
||||
{
|
||||
private static final Log log = LogFactory.getLog(AppleIWorksContentTransformer.class);
|
||||
|
||||
// Apple's zip entry names for the front-page and all-doc previews in iWorks.
|
||||
// We don't attempt to parse the XML 'manifest' (index.xml) within the iWorks file.
|
||||
private static final String QUICK_LOOK_PREVIEW_PDF = "QuickLook/Preview.pdf";
|
||||
private static final String QUICK_LOOK_THUMBNAIL_JPG = "QuickLook/Thumbnail.jpg";
|
||||
|
||||
private static final List<String> IWORKS_MIMETYPES = Arrays.asList(new String[]{MimetypeMap.MIMETYPE_IWORK_KEYNOTE,
|
||||
MimetypeMap.MIMETYPE_IWORK_NUMBERS,
|
||||
MimetypeMap.MIMETYPE_IWORK_PAGES});
|
||||
private static final List<String> TARGET_MIMETYPES = Arrays.asList(new String[]{MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
MimetypeMap.MIMETYPE_PDF});
|
||||
|
||||
|
||||
// Apple's zip entry names for previews in iWorks have changed over time.
|
||||
private static final List<String> PDF_PATHS = Arrays.asList(
|
||||
"QuickLook/Preview.pdf"); // iWorks 2008/9
|
||||
private static final List<String> JPG_PATHS = Arrays.asList(
|
||||
"QuickLook/Thumbnail.jpg", // iWorks 2008/9
|
||||
"preview.jpg"); // iWorks 2013/14 (720 x 552) We use the best quality image. Others are:
|
||||
// (225 x 173) preview-web.jpg
|
||||
// (53 x 41) preview-micro.jpg
|
||||
|
||||
private static final List<String> IWORKS_MIMETYPES = Arrays.asList(MimetypeMap.MIMETYPE_IWORK_KEYNOTE,
|
||||
MimetypeMap.MIMETYPE_IWORK_NUMBERS,
|
||||
MimetypeMap.MIMETYPE_IWORK_PAGES);
|
||||
private static final List<String> TARGET_MIMETYPES = Arrays.asList(MimetypeMap.MIMETYPE_IMAGE_JPEG
|
||||
// Commented out rather than removed, in case we can get SHARE to fall back to using JPEG when a PDF is not available
|
||||
// ,MimetypeMap.MIMETYPE_PDF
|
||||
);
|
||||
|
||||
@Override
|
||||
public boolean isTransformable(String sourceMimetype, String targetMimetype, TransformationOptions options)
|
||||
{
|
||||
// only support [iWorks] -> JPEG | PDF
|
||||
// This is because iWorks 09+ files are zip files containing embedded jpeg/pdf previews.
|
||||
// only support [iWorks] -> JPEG but only if these are embedded in the file.
|
||||
// This is because iWorks 13+ files are zip files containing embedded jpeg previews.
|
||||
return TARGET_MIMETYPES.contains(targetMimetype) && IWORKS_MIMETYPES.contains(sourceMimetype);
|
||||
}
|
||||
|
||||
@@ -85,8 +92,8 @@ public class AppleIWorksContentTransformer extends AbstractContentTransformer2
|
||||
final String sourceMimetype = reader.getMimetype();
|
||||
final String sourceExtension = getMimetypeService().getExtension(sourceMimetype);
|
||||
final String targetMimetype = writer.getMimetype();
|
||||
|
||||
|
||||
final String targetExtension = getMimetypeService().getExtension(targetMimetype);
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
StringBuilder msg = new StringBuilder();
|
||||
@@ -94,45 +101,37 @@ public class AppleIWorksContentTransformer extends AbstractContentTransformer2
|
||||
.append(" to ").append(targetMimetype);
|
||||
log.debug(msg.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZipArchiveInputStream iWorksZip = null;
|
||||
try
|
||||
try
|
||||
{
|
||||
// iWorks files are zip files (at least in recent versions, iWork 09).
|
||||
// iWorks files are zip (or package) files.
|
||||
// If it's not a zip file, the resultant ZipException will be caught as an IOException below.
|
||||
iWorksZip = new ZipArchiveInputStream(reader.getContentInputStream());
|
||||
|
||||
ZipArchiveEntry entry = null;
|
||||
|
||||
// Look through the zip file entries for the preview/thumbnail.
|
||||
List<String> paths = MimetypeMap.MIMETYPE_IMAGE_JPEG.equals(targetMimetype) ? JPG_PATHS : PDF_PATHS;
|
||||
ZipArchiveEntry entry;
|
||||
boolean found = false;
|
||||
while ( !found && (entry = iWorksZip.getNextZipEntry()) != null )
|
||||
while ((entry=iWorksZip.getNextZipEntry()) != null)
|
||||
{
|
||||
if (MimetypeMap.MIMETYPE_IMAGE_JPEG.equals(targetMimetype) &&
|
||||
entry.getName().equals(QUICK_LOOK_THUMBNAIL_JPG))
|
||||
{
|
||||
writer.putContent( iWorksZip );
|
||||
found = true;
|
||||
}
|
||||
else if (MimetypeMap.MIMETYPE_PDF.equals(targetMimetype) &&
|
||||
entry.getName().equals(QUICK_LOOK_PREVIEW_PDF))
|
||||
String name = entry.getName();
|
||||
if (paths.contains(name))
|
||||
{
|
||||
writer.putContent( iWorksZip );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to transform " + sourceExtension + " file to " + targetMimetype);
|
||||
throw new AlfrescoRuntimeException("The source " + sourceExtension + " file did not contain a " + targetExtension + " preview");
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e1)
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to transform " + sourceExtension + " file.", e1);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to transform " + sourceExtension + " file.", e);
|
||||
throw new AlfrescoRuntimeException("Unable to transform " + sourceExtension + " file. It should have been a zip format file.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import java.io.File;
|
||||
@@ -256,11 +256,15 @@ public abstract class AbstractContentTransformerTest extends TestCase
|
||||
// attempt to convert to every other mimetype
|
||||
for (String targetMimetype : mimetypes)
|
||||
{
|
||||
if (sourceMimetype.equals(targetMimetype))
|
||||
{
|
||||
// Don't test like-to-like transformations
|
||||
continue;
|
||||
}
|
||||
if (sourceMimetype.equals(targetMimetype))
|
||||
{
|
||||
// Don't test like-to-like transformations
|
||||
continue;
|
||||
}
|
||||
if (!doTestTransformation(quickFile, sourceMimetype, targetMimetype))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ContentWriter targetWriter = null;
|
||||
// construct a reader onto the source file
|
||||
String targetExtension = mimetypeService.getExtension(targetMimetype);
|
||||
@@ -373,7 +377,19 @@ public abstract class AbstractContentTransformerTest extends TestCase
|
||||
outputWriter.setEncoding("UTF8");
|
||||
outputWriter.putContent(sb.toString());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allows a subclass to skip selected transformations.
|
||||
* @param quickFile name
|
||||
* @param sourceMimetype of the quickFile
|
||||
* @param targetMimetype of the transformation
|
||||
* @return false to skip the transformation.
|
||||
*/
|
||||
protected boolean doTestTransformation(String quickFile, String sourceMimetype, String targetMimetype)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows implementations to do some extra checks on the
|
||||
* results of the content as found by
|
||||
|
@@ -1,33 +1,36 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test case for {@link AppleIWorksContentTransformer} content transformer.
|
||||
*
|
||||
@@ -36,7 +39,7 @@ import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
*/
|
||||
public class AppleIWorksContentTransformerTest extends AbstractContentTransformerTest
|
||||
{
|
||||
private ContentTransformer transformer;
|
||||
private AppleIWorksContentTransformer transformer;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
@@ -45,9 +48,9 @@ public class AppleIWorksContentTransformerTest extends AbstractContentTransforme
|
||||
|
||||
transformer = new AppleIWorksContentTransformer();
|
||||
|
||||
// Ugly cast just to set the MimetypeService
|
||||
((ContentTransformerHelper)transformer).setMimetypeService(mimetypeService);
|
||||
((ContentTransformerHelper)transformer).setTransformerConfig(transformerConfig);
|
||||
transformer.setMimetypeService(mimetypeService);
|
||||
transformer.setTransformerDebug(transformerDebug);
|
||||
transformer.setTransformerConfig(transformerConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,17 +58,38 @@ public class AppleIWorksContentTransformerTest extends AbstractContentTransforme
|
||||
{
|
||||
return transformer;
|
||||
}
|
||||
|
||||
|
||||
// Commented out rather than removed, in case we can get SHARE to fall back to using JPEG when a PDF is not available
|
||||
// @Override
|
||||
// protected String[] getQuickFilenames(String sourceMimetype)
|
||||
// {
|
||||
// List<String> filenames = Arrays.asList(super.getQuickFilenames(sourceMimetype));
|
||||
// filenames.add("quick2009.pages");
|
||||
// return (String[])filenames.toArray();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected boolean doTestTransformation(String quickFile, String sourceMimetype, String targetMimetype)
|
||||
// {
|
||||
// // This transformer can only do transforms to PDF when a iWorks 2008/9 file (rather than 2013/14) file is used.
|
||||
// return !MimetypeMap.MIMETYPE_PDF.equals(targetMimetype) || !"quick2009.pages".endsWith(quickFile);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected boolean isTransformationExcluded(String sourceExtension, String targetExtension)
|
||||
// {
|
||||
// return "pdf".equals(targetExtension); // Our quick files are 2013/14 format so don't include a pdf, only jpgs.
|
||||
// }
|
||||
|
||||
public void testIsTransformable() throws Exception
|
||||
{
|
||||
// thumbnails
|
||||
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_KEYNOTE, MimetypeMap.MIMETYPE_IMAGE_JPEG, new TransformationOptions()));
|
||||
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_NUMBERS, MimetypeMap.MIMETYPE_IMAGE_JPEG, new TransformationOptions()));
|
||||
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_PAGES, MimetypeMap.MIMETYPE_IMAGE_JPEG, new TransformationOptions()));
|
||||
|
||||
// previews
|
||||
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_KEYNOTE, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()));
|
||||
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_NUMBERS, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()));
|
||||
assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_PAGES, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()));
|
||||
|
||||
// Commented out rather than removed, in case we can get SHARE to fall back to using JPEG when a PDF is not available
|
||||
// assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_KEYNOTE, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()));
|
||||
// assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_NUMBERS, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()));
|
||||
// assertTrue(transformer.isTransformable(MimetypeMap.MIMETYPE_IWORK_PAGES, MimetypeMap.MIMETYPE_PDF, new TransformationOptions()));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user