/**
   * {@inheritDoc}
   *
   * @see
   *     ch.entwine.weblounge.common.content.PreviewGenerator#createPreview(ch.entwine.weblounge.common.content.Resource,
   *     ch.entwine.weblounge.common.site.Environment,
   *     ch.entwine.weblounge.common.language.Language,
   *     ch.entwine.weblounge.common.content.image.ImageStyle, String, java.io.InputStream,
   *     java.io.OutputStream)
   */
  public void createPreview(
      Resource<?> resource,
      Environment environment,
      Language language,
      ImageStyle style,
      String format,
      InputStream is,
      OutputStream os)
      throws IOException {

    // We don't need the input stream
    IOUtils.closeQuietly(is);

    // Find a suitable image preview generator for scaling
    ImagePreviewGenerator imagePreviewGenerator = null;
    synchronized (previewGenerators) {
      for (ImagePreviewGenerator generator : previewGenerators) {
        if (generator.supports(format)) {
          imagePreviewGenerator = generator;
          break;
        }
      }
      if (imagePreviewGenerator == null) {
        logger.debug("Unable to generate page previews since no image renderer is available");
        return;
      }
    }

    // Find the relevant metadata to start the request
    ResourceURI uri = resource.getURI();
    long version = resource.getVersion();
    Site site = uri.getSite();

    // Create the url
    URL pageURL =
        new URL(
            UrlUtils.concat(
                site.getHostname(environment).toExternalForm(),
                PAGE_HANDLER_PREFIX,
                uri.getIdentifier()));
    if (version == Resource.WORK) {
      pageURL =
          new URL(
              UrlUtils.concat(
                  pageURL.toExternalForm(), "work_" + language.getIdentifier() + ".html"));
    } else {
      pageURL =
          new URL(
              UrlUtils.concat(
                  pageURL.toExternalForm(), "index_" + language.getIdentifier() + ".html"));
    }

    // Create a temporary file
    final File rendererdFile = File.createTempFile("phantomjs-", "." + format, phantomTmpDir);
    final URL finalPageURL = pageURL;
    final AtomicBoolean success = new AtomicBoolean();

    // Call PhantomJS to render the page
    try {
      final PhantomJsProcessExecutor phantomjs =
          new PhantomJsProcessExecutor(
              scriptFile.getAbsolutePath(),
              pageURL.toExternalForm(),
              rendererdFile.getAbsolutePath()) {
            @Override
            protected void onProcessFinished(int exitCode) throws IOException {
              super.onProcessFinished(exitCode);
              switch (exitCode) {
                case 0:
                  if (rendererdFile.length() > 0) {
                    success.set(true);
                    logger.debug(
                        "Page preview of {} created at {}",
                        finalPageURL,
                        rendererdFile.getAbsolutePath());
                  } else {
                    logger.warn("Error creating page preview of {}", finalPageURL);
                    success.set(false);
                    FileUtils.deleteQuietly(rendererdFile);
                  }
                  break;
                default:
                  success.set(false);
                  logger.warn("Error creating page preview of {}", finalPageURL);
                  FileUtils.deleteQuietly(rendererdFile);
              }
            }
          };

      // Finally have PhantomJS create the preview
      logger.debug("Creating preview of {}", finalPageURL);
      phantomjs.execute();

    } catch (ProcessExcecutorException e) {
      logger.warn("Error creating page preview of {}: {}", pageURL, e.getMessage());
      throw new IOException(e);
    } finally {
      // If page preview rendering failed, there is no point in scaling the
      // images
      if (!success.get()) {
        logger.debug("Skipping scaling of failed preview rendering {}", pageURL);
        FileUtils.deleteQuietly(rendererdFile);
        return;
      }
    }

    FileInputStream imageIs = null;

    // Scale the image to the correct size
    try {
      imageIs = new FileInputStream(rendererdFile);
      imagePreviewGenerator.createPreview(
          resource, environment, language, style, PREVIEW_FORMAT, imageIs, os);
    } catch (IOException e) {
      logger.error("Error reading original page preview from " + rendererdFile, e);
      throw e;
    } catch (Throwable t) {
      logger.warn("Error scaling page preview at " + uri + ": " + t.getMessage(), t);
      throw new IOException(t);
    } finally {
      IOUtils.closeQuietly(imageIs);
      FileUtils.deleteQuietly(rendererdFile);
    }
  }
 /**
  * {@inheritDoc}
  *
  * @see ch.entwine.weblounge.common.content.PreviewGenerator#supports(java.lang.String)
  */
 public boolean supports(String format) {
   for (ImagePreviewGenerator generator : previewGenerators) {
     if (generator.supports(PREVIEW_FORMAT) && generator.supports(format)) return true;
   }
   return false;
 }