Package ch.entwine.weblounge.common.impl.content.image

Source Code of ch.entwine.weblounge.common.impl.content.image.ImageContentReader$UnclosableInputStream

/*
*  Weblounge: Web Content Management System
*  Copyright (c) 2003 - 2011 The Weblounge Team
*  http://entwinemedia.com/weblounge
*
*  This program 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 2
*  of the License, or (at your option) any later version.
*
*  This program 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 this program; if not, write to the Free Software Foundation
*  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package ch.entwine.weblounge.common.impl.content.image;

import ch.entwine.weblounge.common.content.image.ImageContent;
import ch.entwine.weblounge.common.impl.content.ResourceContentReaderImpl;
import ch.entwine.weblounge.common.impl.util.WebloungeDateFormat;
import ch.entwine.weblounge.common.language.Language;
import ch.entwine.weblounge.common.security.User;

import com.sun.media.jai.codec.MemoryCacheSeekableStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.text.ParseException;
import java.util.Date;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;

/**
* Utility class used to parse <code>Content</code> data for simple files.
*/
public class ImageContentReader extends ResourceContentReaderImpl<ImageContent> {

  /** Logging facility */
  protected static final Logger logger = LoggerFactory.getLogger(ImageContentReader.class);

  /**
   * Creates a new file content reader that will parse serialized XML version of
   * the file content and store it in the
   * {@link ch.entwine.weblounge.common.content.ResourceContent} that is
   * returned by the {@link #read} method.
   *
   * @throws ParserConfigurationException
   *           if the SAX parser setup failed
   * @throws SAXException
   *           if an error occurs while parsing
   *
   * @see #createFromXml(InputStream)
   */
  public ImageContentReader() throws ParserConfigurationException, SAXException {
    parserRef = new WeakReference<SAXParser>(parserFactory.newSAXParser());
  }

  /**
   * This method is called to parse the serialized XML of a
   * {@link ch.entwine.weblounge.common.content.ResourceContent}.
   *
   * @param is
   *          the content data
   * @throws ParserConfigurationException
   *           if the SAX parser setup failed
   * @throws IOException
   *           if reading the input stream fails
   * @throws SAXException
   *           if an error occurs while parsing
   */
  public ImageContent createFromXml(InputStream is) throws SAXException,
      IOException, ParserConfigurationException {

    SAXParser parser = parserRef.get();
    if (parser == null) {
      parser = parserFactory.newSAXParser();
      parserRef = new WeakReference<SAXParser>(parser);
    }
    parser.parse(is, this);
    return content;
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.content.ResourceContentReader#createFromContent(java.io.InputStream,
   *      ch.entwine.weblounge.common.language.Language, long, java.lang.String)
   */
  public ImageContent createFromContent(InputStream is, User user,
      Language language, long size, String fileName, String mimeType)
      throws IOException {

    ImageContent content = new ImageContentImpl(fileName, language, mimeType);

    // Use the logged in user as the author
    content.setCreator(user);

    // Set the creation date
    content.setCreationDate(new Date());

    MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream(is);
    UnclosableInputStream bis = new UnclosableInputStream(mcss);

    // Read the Exif metadata (if available)
    try {
      readExifMetadata(content, bis);
    } catch (Throwable t) {
      logger.warn("Error extracting Exif metadata from {}: {}", fileName, t.getMessage());
    }

    // Read the JAI metadata
    if (content.getWidth() <= 0 || content.getHeight() <= 0) {
      try {
        mcss.seek(0);
        readJAIMetadata(content, mcss);
      } catch (Throwable t) {
        logger.warn("Error extracting metadata using java advanced imaging (jai) from {}: {}", fileName, t.getMessage());
        throw new IOException(t);
      } finally {
        IOUtils.closeQuietly(is);
      }
    }

    // Close the input stream
    IOUtils.closeQuietly(mcss);
    bis = null;

    return content;
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.ResourceContentReaderImpl#createContent()
   */
  @Override
  protected ImageContent createContent() {
    return new ImageContentImpl();
  }

  /**
   * Resets the pagelet parser.
   */
  public void reset() {
    super.reset();
    content = null;
  }

  /**
   * {@inheritDoc}
   *
   * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
   *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
   */
  public void startElement(String uri, String local, String raw,
      Attributes attrs) throws SAXException {

    // start of a new content element
    if ("content".equals(raw)) {
      logger.debug("Started reading image content {}", content);
    }

    // gps position
    else if ("gps".equals(raw)) {
      double gpsLat = Double.parseDouble(attrs.getValue("lat"));
      double gpsLong = Double.parseDouble(attrs.getValue("lng"));
      content.setGpsPosition(gpsLat, gpsLong);
      logger.trace("Image's gps lat is '{}'", content.getGpsLat());
      logger.trace("Image's gps long is '{}'", content.getGpsLong());
    }

    super.startElement(uri, local, raw, attrs);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.common.impl.content.WebloungeContentReader#endElement(java.lang.String,
   *      java.lang.String, java.lang.String)
   */
  public void endElement(String uri, String local, String raw)
      throws SAXException {

    // mime type
    if ("mimetype".equals(raw)) {
      content.setMimetype(getCharacters());
      logger.trace("Images's content mimetype is '{}'", content.getMimetype());
    }

    // size
    else if ("size".equals(raw)) {
      content.setSize(Long.parseLong(getCharacters()));
      logger.trace("Image's content filesize is '{}'", content.getSize());
    }

    // height
    else if ("height".equals(raw)) {
      content.setHeight(Integer.parseInt(getCharacters()));
      logger.trace("Image's height is '{}'", content.getHeight());
    }

    // width
    else if ("width".equals(raw)) {
      content.setWidth(Integer.parseInt(getCharacters()));
      logger.trace("Image's width is '{}'", content.getWidth());
    }

    // date taken
    else if ("datetaken".equals(raw)) {
      try {
        content.setDateTaken(WebloungeDateFormat.parseStatic(getCharacters()));
      } catch (ParseException e) {
        throw new IllegalStateException("The date taken '" + getCharacters() + "' cannot be parsed", e);
      }
      logger.trace("Image's date taken is '{}'", content.getDateTaken());
    }

    // location
    else if ("location".equals(raw)) {
      content.setLocation(getCharacters());
      logger.trace("Image's location is '{}'", content.getLocation());
    }

    // filmspeed
    else if ("filmspeed".endsWith(raw)) {
      content.setFilmspeed(Integer.parseInt(getCharacters()));
      logger.trace("Image's filmspeed is '{}'", content.getFilmspeed());
    }

    // fnumber
    else if ("fnumber".equals(raw)) {
      content.setFNumber(Float.parseFloat(getCharacters()));
      logger.trace("Image's fnumber is '{}'", content.getFNumber());
    }

    // focal width
    else if ("focalwidth".equals(raw)) {
      content.setFocalWidth(Integer.parseInt(getCharacters()));
      logger.trace("Image's focalwidth is '{}'", content.getFocalWidth());
    }

    // exposure time
    else if ("exposuretime".equals(raw)) {
      content.setExposureTime(Float.parseFloat(getCharacters()));
      logger.trace("Image's exposuretime is '{}'", content.getExposureTime());
    }

    else {
      super.endElement(uri, local, raw);
    }
  }

  /**
   * Extracts the Exif metadata from the image.
   *
   * @param content
   *          the resource content
   * @param is
   *          the input stream
   * @return the Exif metadata
   */
  protected ImageMetadata readExifMetadata(ImageContent content, InputStream is) {
    BufferedInputStream bis = new BufferedInputStream(is);
    ImageMetadata exifMetadata = ImageMetadataUtils.extractMetadata(bis);

    if (exifMetadata == null)
      return null;

    if (exifMetadata.getDateTaken() != null) {
      content.setDateTaken(exifMetadata.getDateTaken());
    }

    if (!StringUtils.isBlank(exifMetadata.getPhotographer())) {
      content.setAuthor(exifMetadata.getPhotographer());
    }

    if (!StringUtils.isBlank(exifMetadata.getLocation())) {
      content.setLocation(exifMetadata.getLocation());
    }

    if (exifMetadata.getGpsLat() != 0 && exifMetadata.getGpsLong() != 0) {
      content.setGpsPosition(exifMetadata.getGpsLat(), exifMetadata.getGpsLong());
    }

    if (exifMetadata.getFilmspeed() != 0) {
      content.setFilmspeed(exifMetadata.getFilmspeed());
    }

    if (exifMetadata.getFNumber() != 0) {
      content.setFNumber(exifMetadata.getFNumber());
    }

    if (exifMetadata.getFocalWidth() != 0) {
      content.setFocalWidth(exifMetadata.getFocalWidth());
    }

    if (exifMetadata.getExposureTime() != 0) {
      content.setExposureTime(exifMetadata.getExposureTime());
    }

    return exifMetadata;
  }

  /**
   * Extracts image metadata from the image using Java Advanced Imaging (JAI).
   *
   * @param content
   *          the resource content
   * @param is
   *          the input stream
   * @return the image metadata
   */
  protected RenderedOp readJAIMetadata(ImageContent content, InputStream is) {
    MemoryCacheSeekableStream imageInputStream = new MemoryCacheSeekableStream(is);
    RenderedOp jaiMetadata = JAI.create("stream", imageInputStream);

    if (jaiMetadata == null)
      return null;

    content.setWidth(jaiMetadata.getWidth());
    content.setHeight(jaiMetadata.getHeight());

    return jaiMetadata;
  }

  /**
   * Implementation of an input stream that ignores calls to
   * {@link java.io.InputStream#close()}.
   */
  private static class UnclosableInputStream extends BufferedInputStream {

    /**
     * Creates a new input stream which will be fully consumed before being
     * closed.
     *
     * @param is
     *          the input stream to be consumed from
     */
    public UnclosableInputStream(InputStream is) {
      super(is);
    }

    /**
     * {@inheritDoc}
     *
     * @see java.io.BufferedInputStream#close()
     */
    @Override
    public void close() throws IOException {
      // Don't do anything, we still need this input stream
    }

  }

}
TOP

Related Classes of ch.entwine.weblounge.common.impl.content.image.ImageContentReader$UnclosableInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.