diff --git a/config/quick/quick.key b/config/quick/quick.key new file mode 100644 index 0000000000..372c688cdd Binary files /dev/null and b/config/quick/quick.key differ diff --git a/config/quick/quick.numbers b/config/quick/quick.numbers new file mode 100644 index 0000000000..7e58c11f18 Binary files /dev/null and b/config/quick/quick.numbers differ diff --git a/config/quick/quick.pages b/config/quick/quick.pages new file mode 100644 index 0000000000..33ccef34a7 Binary files /dev/null and b/config/quick/quick.pages differ diff --git a/config/quick/quick2009.pages b/config/quick/quick2009.pages new file mode 100644 index 0000000000..70c6193382 Binary files /dev/null and b/config/quick/quick2009.pages differ diff --git a/source/java/org/alfresco/repo/content/transform/AppleIWorksContentTransformer.java b/source/java/org/alfresco/repo/content/transform/AppleIWorksContentTransformer.java index 1fb73c7579..e5d00ca4f2 100644 --- a/source/java/org/alfresco/repo/content/transform/AppleIWorksContentTransformer.java +++ b/source/java/org/alfresco/repo/content/transform/AppleIWorksContentTransformer.java @@ -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 . - * #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 . + * #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 IWORKS_MIMETYPES = Arrays.asList(new String[]{MimetypeMap.MIMETYPE_IWORK_KEYNOTE, - MimetypeMap.MIMETYPE_IWORK_NUMBERS, - MimetypeMap.MIMETYPE_IWORK_PAGES}); - private static final List 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 PDF_PATHS = Arrays.asList( + "QuickLook/Preview.pdf"); // iWorks 2008/9 + private static final List 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 IWORKS_MIMETYPES = Arrays.asList(MimetypeMap.MIMETYPE_IWORK_KEYNOTE, + MimetypeMap.MIMETYPE_IWORK_NUMBERS, + MimetypeMap.MIMETYPE_IWORK_PAGES); + private static final List 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 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 { diff --git a/source/test-java/org/alfresco/repo/content/transform/AbstractContentTransformerTest.java b/source/test-java/org/alfresco/repo/content/transform/AbstractContentTransformerTest.java index b0d29d1e7d..06bebad3e1 100644 --- a/source/test-java/org/alfresco/repo/content/transform/AbstractContentTransformerTest.java +++ b/source/test-java/org/alfresco/repo/content/transform/AbstractContentTransformerTest.java @@ -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 . - * #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 . + * #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 diff --git a/source/test-java/org/alfresco/repo/content/transform/AppleIWorksContentTransformerTest.java b/source/test-java/org/alfresco/repo/content/transform/AppleIWorksContentTransformerTest.java index ab44341b33..72f6ffbb54 100644 --- a/source/test-java/org/alfresco/repo/content/transform/AppleIWorksContentTransformerTest.java +++ b/source/test-java/org/alfresco/repo/content/transform/AppleIWorksContentTransformerTest.java @@ -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 . - * #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 . + * #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 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())); } }