About FirstSpirit-UploadHooks (Developer-API)

andre
I'm new here
3 6 1,635

1. UploadHooks in general

...here we go ...brief.....

* ... processed on new media creation or changing a picture/file of a FirstSpirit medium

  (yes, FirstSpirit-5 does support setting preview thumbnails for media of type FirstSpirit.File)

* ... process before and/or after an upload to the FirstSpirit-Server was triggered by the user or a FirstSpirit-API-Call

  @see implementation interface: http://www.e-spirit.com/odfs50/dev/?de/espirit/firstspirit/service/mediamanagement/UploadHook.html

  or an upload has been aborted by an UploadHook throwing an UploadRejectedException in this case the Hooks uploadAborted method will be called

  to give the Hook a chance of cleaning something.

some use cases out of many...

* call any thirdparty- or custom FirstSpirit-Module-Component -service e.g scan for virus before uploading a medium to the FirstSpirit-Server

* generate custom thumbnails e.g. for PDF Files

* extract meta data information (e.g. image exif data) and assign/write them to the meta data of a FirstSpirit media.

  for this case FirstSpirit provides a deffault ExifUploadHook implementation sprinkled with a small exif-developer-api

  for exif data processing and formatting able to extract any simple

  (e.g. image orientation '...extract image exif orientation information and rotate the image auto-magically' , timestamps ...) exif types

  as well complex type like Geolocation information.

  Dev-API:

  @see http://www.e-spirit.com/odfs50/dev/de/espirit/firstspirit/server/mediamanagement/exif/package-frame....

  in addition to the default ExifUploadHook-Implementation it is possible to register custom additional ExifHook(s)

  @see http://www.e-spirit.com/odfs50/dev/?de/espirit/firstspirit/service/mediamanagement/ExifUploadHook.ht...

  @see Release notes chapter 7.7 for some FirstSpirit exif documentation - usages in templates and basic concepts

      http://www.e-spirit.com/odfs50/en/weiterfuehrende_themen/exif_daten/exif_daten_1.html?community

* reject uploads to the FirstSpirit-Server for any desired cases throwing an UploadRejectedException (this needs to be done in the pre*-Method of the Hook)

2. ... some details - an example PDF-Thumbnail-Hook implementation (use PDFRenderer library - Source License: LGPL-2.1)

* registering the hook as FirstSpirit-Module (module descriptor)

-------Module descriptor ------------------------------------------------------------------------------------------

<module>

    <name>FirstSpirit PDF Preview-Image UploadHook Example</name>

    <version>@VERSION@</version>

    <description>FirstSpirit PDF Preview-Image UploadHook example implementation.</description>

    <vendor>e-Spirit AG</vendor>

    <components>

        <public>

            <name>PDF_THUMBNAIL_UPLOADHOOK</name>

            <description>FirstSpirit PDF Preview-Image UploadHook example implementation.</description>

            <class>de.espirit.firstspirit.opt.example.PdfThumbnailHookExample</class>

            <resources>

                <resource scope="server">lib/fs-example_pdfthumbnailhook.jar</resource>

                <resource scope="server">lib/PDFRenderer-0.9.0.jar</resource>

            </resources>

        </public>

    </components>

</module>

-----------------------------------------------------------------------------------------------------------------

...at least some java

---------------PdfThumbnailHookExample.java ---------------------------------------------------------------------

public class PdfThumbnailHookExample implements UploadHook {

    public void preProcess(@NotNull final BaseContext baseContext, @NotNull final Media media, @NotNull final File file, @NotNull final InputStream inputStream, final long length) throws UploadRejectedException, IOException {

        //nothing to do

    }

    public void preProcess(@NotNull final BaseContext baseContext, @NotNull final Media media, @NotNull final Picture picture, final Resolution resolution, @NotNull final InputStream inputStream, final long length) throws UploadRejectedException, IOException {

        //nothing to do

    }

    public void postProcess(@NotNull final BaseContext baseContext, @NotNull final Media media, @NotNull final File file, final long length) {

        final MimeType mimeType = file.getMimeType();

        if (mimeType == null) {

            return;

        }

        final String extension = file.getExtension();

        if (extension != null && !"pdf".equals(extension.toLowerCase(Locale.ENGLISH))) {

            return;

        }

        InputStream inputStream = null;

        try {

            inputStream = file.getInputStream();

            final Image image = createImage(baseContext, inputStream, (int) file.getSize());

            if (image == null) {

                baseContext.logWarning("PDF image generation failed.");

            }

            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

            ImageIO.write((RenderedImage) image, "png", byteArrayOutputStream);

            final byte[] bytes = byteArrayOutputStream.toByteArray();

            if (bytes.length > 0) {

                file.setPreviewImage(bytes);

            }

        } catch (IOException e) {

            baseContext.logError("PDF image generation failed.", e);

        } finally {

            if (inputStream != null) {

                try {

                    inputStream.close();

                } catch (IOException ignore) {

                }

            }

        }

    }

    public void postProcess(@NotNull final BaseContext baseContext, @NotNull final Media media, @NotNull final Picture picture, final long length) {

        //nothing to do

    }

    public void uploadAborted(@NotNull final BaseContext baseContext, @NotNull final Media media, @NotNull final MediaElement mediaElement) {

        //nothing to do

    }

    @Nullable

    private static Image createImage(final BaseContext baseContext, final InputStream stream, final int size) throws IOException {

        final byte[] bytes = readFromStream(stream, size);

        final ByteBuffer buffer = ByteBuffer.allocateDirect(size);

        buffer.put(bytes);

        final PDFFile pdfFile = new PDFFile(buffer);

        final int pages = pdfFile.getNumPages();

        if (pages < 1) {

            baseContext.logWarning("Minimum of one pdf page is required to render an image.");

            return null;

        }

        final PDFPage page = pdfFile.getPage(0);

        return page.getImage((int) page.getWidth(), (int) page.getHeight(), page.getBBox(), null, true, true);

    }

    private static byte[] readFromStream(final InputStream in, final int size) throws IOException {

        final byte[] bytes = new byte[size];

        try {

            int offset = 0;

            do {

                final int len = in.read(bytes, offset, bytes.length - offset);

                if (len == -1) {

                    throw new IllegalStateException("buffer underflow");

                }

                offset += len;

            } while (offset < bytes.length);

        } finally {

            in.close();

        }

        return bytes;

    }

}

not much ...isn't it?

----------------------------------------------------------------------------------------------------

The PdfThumbnailHookExample.java captures always the first page of the pdf,

may be providing some settings (...which pdf page to render) through the media meta data could be useful.

feel free to ask your e-Spirit contact to get the full example hook implementation.

There's also an exif_example_project.tar.gz which you could ask our help desk for.

NOTE: keep in mind an UploadHook may run in the FirstSpirit JavaClient and FirstSpirit WebEdit.

6 Comments