Package com.google.caja.lexer

Source Code of com.google.caja.lexer.FetchedData$BinaryFetchedData

// Copyright (C) 2009 Google Inc.
//
// Licensed 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 com.google.caja.lexer;

import com.google.caja.SomethingWidgyHappenedError;
import com.google.caja.util.Charsets;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;

import javax.annotation.WillClose;
import javax.mail.internet.ContentType;
import javax.mail.internet.ParseException;

/**
* Encapsulates a unit of content fetched from some remote location, including
* some basic metadata about the content.
*
* @author jasvir@gmail.com (Jasvir Nagra)
*/
public abstract class FetchedData {
  protected final String contentType;
  protected final String charSet;

  protected FetchedData(String contentType, String charSet) {
    this.contentType = contentType;
    this.charSet = charSet != null ? charSet : "";
  }

  private static class BinaryFetchedData extends FetchedData {
    private final byte[] content;
    private final InputSource src;

    BinaryFetchedData(
        byte[] content, String contentType, String charSet, InputSource src) {
      super(contentType, charSet);
      this.content = content;
      this.src = src;
    }

    @Override
    public CharProducer getTextualContent()
        throws UnsupportedEncodingException {
      return CharProducer.Factory.fromString(
          new String(content, "".equals(charSet)
              ? Charsets.UTF_8.name() : charSet), src);
    }

    @Override
    public InputStream getBinaryContent() {
      return new ByteArrayInputStream(content);
    }

    @Override
    public byte[] getByteContent() { return content.clone(); }
  }

  private static class TextualFetchedData extends FetchedData {
    private final CharProducer cp;

    public TextualFetchedData(
        CharProducer cp, String contentType, String charSet) {
      super(contentType, charSet);
      this.cp = cp;
    }

    @Override
    public CharProducer getTextualContent() {
      return cp.clone();
    }

    @Override
    public InputStream getBinaryContent() throws UnsupportedEncodingException {
      return new ByteArrayInputStream(getByteContent());
    }

    @Override
    public byte[] getByteContent() throws UnsupportedEncodingException {
      return cp.toString().getBytes(charSet);
    }
  }

  public static FetchedData fromBytes(
      byte[] content, String contentType, String charSet, InputSource src) {
    return new BinaryFetchedData(content, contentType, charSet, src);
  }

  public static FetchedData fromStream(
      @WillClose InputStream is, String contentType, String charSet,
      InputSource src)
      throws IOException {
    return fromBytes(readStream(is), contentType, charSet, src);
  }

  public static FetchedData fromConnection(URLConnection connection)
      throws IOException {
    connection.connect();
    URI uri;
    try {
      uri = connection.getURL().toURI();
    } catch (URISyntaxException ex) {
      throw new SomethingWidgyHappenedError(ex);
    }
    return fromBytes(
        readStream(connection.getInputStream()),
        connection.getContentType(),
        getCharSet(connection),
        new InputSource(uri));
  }

  public static FetchedData fromCharProducer(
      CharProducer cp, String contentType, String charSet) {
    return new TextualFetchedData(cp, contentType, charSet);
  }

  public static FetchedData fromReader(
      Reader in, InputSource is, String contentType, String charSet)
      throws IOException {
    return fromCharProducer(
        CharProducer.Factory.create(in, is), contentType, charSet);
  }

  public static FetchedData fromReader(
      Reader in, FilePosition pos, String contentType, String charSet)
      throws IOException {
    return fromCharProducer(
        CharProducer.Factory.create(in, pos), contentType, charSet);
  }

  public abstract CharProducer getTextualContent()
      throws UnsupportedEncodingException;

  public abstract InputStream getBinaryContent()
      throws UnsupportedEncodingException;

  public abstract byte[] getByteContent()
      throws UnsupportedEncodingException;

  /**
   * @return the MIME type of the content.
   */
  public String getContentType() { return contentType; }

  /**
   * @return the character set of the content. This is only meaningful if the
   * MIME type of the content is textual and if the character set is provided
   * by the source. If neither case is true, the return value of this method
   * will be an empty string.
   */
  public String getCharSet() { return charSet; }

  private static int MAX_RESPONSE_SIZE_BYTES = 1 << 24// 16MB
  protected static byte[] readStream(@WillClose InputStream is)
      throws IOException {
    try {
      ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      byte[] barr = new byte[4096];
      int totalLen = 0;
      for (int n; (n = is.read(barr)) > 0;) {
        if ((totalLen += n) > MAX_RESPONSE_SIZE_BYTES) {
          throw new IOException("Response too large");
        }
        buffer.write(barr, 0, n);
      }
      return buffer.toByteArray();
    } finally {
      is.close();
    }
  }

  private static String getCharSet(URLConnection conn) {
    try {
      String contentType = conn.getContentType();
      if (contentType == null) { return ""; }
      String charset = new ContentType(contentType).getParameter("charset");
      return (charset == null) ? "" : charset;
    } catch (ParseException e) {
      return "";
    }
  }
}
TOP

Related Classes of com.google.caja.lexer.FetchedData$BinaryFetchedData

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.
y>