Package org.waveprotocol.box.server.attachment

Source Code of org.waveprotocol.box.server.attachment.AttachmentService

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.waveprotocol.box.server.attachment;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.waveprotocol.box.attachment.AttachmentMetadata;
import org.waveprotocol.box.attachment.ImageMetadata;
import org.waveprotocol.box.attachment.impl.AttachmentMetadataImpl;
import org.waveprotocol.box.attachment.impl.ImageMetadataImpl;
import org.waveprotocol.box.server.persistence.AttachmentStore;
import org.waveprotocol.box.server.persistence.AttachmentStore.AttachmentData;
import org.waveprotocol.box.server.rpc.AttachmentServlet;
import org.waveprotocol.wave.media.model.AttachmentId;
import org.waveprotocol.wave.model.id.WaveletName;
import org.waveprotocol.wave.model.wave.ParticipantId;
import org.waveprotocol.wave.model.waveref.WaveRef;
import org.waveprotocol.wave.util.escapers.jvm.JavaWaverefEncoder;

/**
* Serves storing and getting of attachments.
*
* @author akaplanov@gmail.com (A. Kaplanov)
*/
public class AttachmentService {
  private static final Logger LOG = Logger.getLogger(AttachmentService.class.getName());

  public static final String THUMBNAIL_MIME_TYPE = "image/jpeg";
  public static final String THUMBNAIL_FORMAT_NAME = "jpeg";

  public static final int THUMBNAIL_PATTERN_WIDTH = 95;
  public static final int THUMBNAIL_PATTERN_HEIGHT = 60;

  private static final int MAX_THUMBNAIL_WIDTH = 200;
  private static final int MAX_THUMBNAIL_HEIGHT = 200;

  private final AttachmentStore store;

  @Inject
  private AttachmentService(AttachmentStore store) {
    this.store = store;
  }

  public AttachmentMetadata getMetadata(AttachmentId attachmentId) throws IOException {
    return store.getMetadata(attachmentId);
  }

  public AttachmentData getAttachment(AttachmentId attachmentId) throws IOException {
    return store.getAttachment(attachmentId);
  }

  public AttachmentData getThumbnail(AttachmentId attachmentId) throws IOException {
    return store.getThumbnail(attachmentId);
  }

  public void storeAttachment(AttachmentId attachmentId, InputStream in, WaveletName waveletName,
      String fileName, ParticipantId creator) throws IOException {
    store.storeAttachment(attachmentId, in);
    buildAndStoreMetadataWithThumbnail(attachmentId, waveletName, fileName, creator);
  }

  public AttachmentMetadata buildAndStoreMetadataWithThumbnail(AttachmentId attachmentId,
      WaveletName waveletName, String fileName, ParticipantId creator) throws IOException {
    AttachmentData data = store.getAttachment(attachmentId);
    if (data == null) {
      throw new IOException("No such atachment " + attachmentId.serialise());
    }
    AttachmentMetadata metadata = new AttachmentMetadataImpl();
    metadata.setAttachmentId(attachmentId.serialise());
    metadata.setAttachmentUrl(AttachmentServlet.ATTACHMENT_URL + "/" + attachmentId.serialise());
    metadata.setThumbnailUrl(AttachmentServlet.THUMBNAIL_URL + "/" + attachmentId.serialise());
    metadata.setWaveRef(waveletName2WaveRef(waveletName));
    metadata.setFileName(fileName);
    String contentType = getMimeType(fileName);
    metadata.setMimeType(contentType);
    metadata.setSize(data.getSize());
    metadata.setCreator((creator != null) ? creator.getAddress() : "");
    BufferedImage image = null;
    try {
      image = ImageIO.read(data.getInputStream());
    } catch (IOException ex) {
      LOG.log(Level.SEVERE, "Identifying attachment", ex);
    }
    if (image != null) {
      ImageMetadata imageMetadata = new ImageMetadataImpl();
      imageMetadata.setWidth(image.getWidth());
      imageMetadata.setHeight(image.getHeight());
      metadata.setImageMetadata(imageMetadata);
      try {
        BufferedImage thumbnail = makeThumbnail(image);
        storeThumbnail(attachmentId, thumbnail);
        ImageMetadata thumbnailMetadata = new ImageMetadataImpl();
        thumbnailMetadata.setWidth(thumbnail.getWidth());
        thumbnailMetadata.setHeight(thumbnail.getHeight());
        metadata.setThumbnailMetadata(thumbnailMetadata);
      } catch (IOException ex) {
        LOG.log(Level.SEVERE, "Building attachment thumbnail", ex);
      }
    } else {
      ImageMetadata thumbnailMetadata = new ImageMetadataImpl();
      thumbnailMetadata.setWidth(THUMBNAIL_PATTERN_WIDTH);
      thumbnailMetadata.setHeight(THUMBNAIL_PATTERN_HEIGHT);
      metadata.setThumbnailMetadata(thumbnailMetadata);
    }
    store.storeMetadata(attachmentId, metadata);
    return metadata;
  }

  private static BufferedImage makeThumbnail(BufferedImage image) {
    int imageWidth = image.getWidth();
    int imageHeight = image.getHeight();
    Preconditions.checkState(imageHeight != 0);
    Preconditions.checkState(imageWidth != 0);
    int thumbnailWidth = imageWidth < MAX_THUMBNAIL_WIDTH ? imageWidth : MAX_THUMBNAIL_WIDTH;
    int thumbnailHeight = imageHeight < MAX_THUMBNAIL_HEIGHT ? imageHeight : MAX_THUMBNAIL_HEIGHT;
    if (imageWidth * thumbnailHeight < imageHeight * thumbnailWidth) {
      thumbnailWidth = imageWidth * thumbnailHeight / imageHeight;
    } else {
      thumbnailHeight = imageHeight * thumbnailWidth / imageWidth;
    }
    BufferedImage thumbnail = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = thumbnail.createGraphics();
    try {
      g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
          RenderingHints.VALUE_INTERPOLATION_BICUBIC);
      g.setBackground(Color.BLACK);
      g.clearRect(0, 0, thumbnailWidth, thumbnailHeight);
      g.drawImage(image, 0, 0, thumbnailWidth, thumbnailHeight, null);
    } finally {
      g.dispose();
    }
    return thumbnail;
  }

  private void storeThumbnail(AttachmentId attachemntId, BufferedImage thumbnail) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ImageIO.write(thumbnail, THUMBNAIL_FORMAT_NAME, out);
    store.storeThumbnail(attachemntId, new ByteArrayInputStream(out.toByteArray()));
  }

  private static String waveletName2WaveRef(WaveletName waveletName) {
    WaveRef waveRef = WaveRef.of(waveletName.waveId, waveletName.waveletId);
    return JavaWaverefEncoder.encodeToUriPathSegment(waveRef);
  }

  private static String getMimeType(String fileName) {
    String mimeType = URLConnection.getFileNameMap().getContentTypeFor(fileName);
    if (mimeType == null) {
      return "application/octet-stream";
    }
    return mimeType;
  }
}
TOP

Related Classes of org.waveprotocol.box.server.attachment.AttachmentService

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.