Android Open Source - tape File Object Queue






From Project

Back to project page tape.

License

The source code is released under:

Apache License

If you think the Android project tape listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

// Copyright 2012 Square, Inc.
package com.squareup.tape;
//from  ww w.ja  va2 s .c o  m
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import static java.util.Collections.unmodifiableList;

/**
 * Base queue class, implements common functionality for a QueueFile-backed
 * queue manager.  This class is not thread safe; instances should be kept
 * thread-confined.
 * <p>
 * The {@link #add( Object )}, {@link #peek()}, {@link #remove()}, and
 * {@link #setListener(ObjectQueue.Listener)} methods may throw a
 * {@link FileException} if the underlying {@link QueueFile} experiences an
 * {@link java.io.IOException}.
 *
 * @param <T> The type of elements in the queue.
 */
public class FileObjectQueue<T> implements ObjectQueue<T> {
  /** Backing storage implementation. */
  private final QueueFile queueFile;
  /** Reusable byte output buffer. */
  private final DirectByteArrayOutputStream bytes = new DirectByteArrayOutputStream();
  /** Keep file around for error reporting. */
  private final File file;
  private final Converter<T> converter;
  private Listener<T> listener;

  public FileObjectQueue(File file, Converter<T> converter) throws IOException {
    this.file = file;
    this.converter = converter;
    this.queueFile = new QueueFile(file);
  }

  @Override public int size() {
    return queueFile.size();
  }

  @Override public final void add(T entry) {
    try {
      bytes.reset();
      converter.toStream(entry, bytes);
      queueFile.add(bytes.getArray(), 0, bytes.size());
      if (listener != null) listener.onAdd(this, entry);
    } catch (IOException e) {
      throw new FileException("Failed to add entry.", e, file);
    }
  }

  @Override public T peek() {
    try {
      byte[] bytes = queueFile.peek();
      if (bytes == null) return null;
      return converter.from(bytes);
    } catch (IOException e) {
      throw new FileException("Failed to peek.", e, file);
    }
  }

  /**
   * Reads up to {@code max} entries from the head of the queue without removing the entries.
   * If the queue's {@link #size()} is less than {@code max} then only {@link #size()} entries
   * are read.
   */
  public List<T> peek(final int max) {
    try {
      final List<T> entries = new ArrayList<T>(max);
      queueFile.forEach(new QueueFile.ElementVisitor() {
        int count;
        @Override public boolean read(InputStream in, int length) throws IOException {
          byte[] data = new byte[length];
          in.read(data, 0, length);

          entries.add(converter.from(data));
          return ++count < max;
        }
      });
      return unmodifiableList(entries);

    } catch (IOException e) {
      throw new FileException("Failed to peek.", e, file);
    }
  }

  public List<T> asList() {
    return peek(size());
  }

  @Override public final void remove() {
    try {
      queueFile.remove();
      if (listener != null) listener.onRemove(this);
    } catch (IOException e) {
      throw new FileException("Failed to remove.", e, file);
    }
  }

  public final void close() {
    try {
      queueFile.close();
    } catch (IOException e) {
      throw new FileException("Failed to close.", e, file);
    }
  }

  @Override public void setListener(final Listener<T> listener) {
    if (listener != null) {
      try {
        queueFile.forEach(new QueueFile.ElementVisitor() {
          @Override public boolean read(InputStream in, int length) throws IOException {
            byte[] data = new byte[length];
            in.read(data, 0, length);

            listener.onAdd(FileObjectQueue.this, converter.from(data));
            return true;
          }
        });
      } catch (IOException e) {
        throw new FileException("Unable to iterate over QueueFile contents.", e, file);
      }
    }
    this.listener = listener;
  }

  /**
   * Convert a byte stream to and from a concrete type.
   *
   * @param <T> Object type.
   */
  public interface Converter<T> {
    /** Converts bytes to an object. */
    T from(byte[] bytes) throws IOException;

    /** Converts o to bytes written to the specified stream. */
    void toStream(T o, OutputStream bytes) throws IOException;
  }

  /** Enables direct access to the internal array. Avoids unnecessary copying. */
  private static class DirectByteArrayOutputStream extends ByteArrayOutputStream {
    public DirectByteArrayOutputStream() {
      super();
    }

    /**
     * Gets a reference to the internal byte array.  The {@link #size()} method indicates how many
     * bytes contain actual data added since the last {@link #reset()} call.
     */
    public byte[] getArray() {
      return buf;
    }
  }
}




Java Source Code List

com.squareup.tape.FileException.java
com.squareup.tape.FileObjectQueue.java
com.squareup.tape.InMemoryObjectQueue.java
com.squareup.tape.ObjectQueue.java
com.squareup.tape.QueueFile.java
com.squareup.tape.SerializedConverter.java
com.squareup.tape.TaskInjector.java
com.squareup.tape.TaskQueue.java
com.squareup.tape.Task.java
com.squareup.tape.sample.GsonConverter.java
com.squareup.tape.sample.ImageUploadQueueSizeEvent.java
com.squareup.tape.sample.ImageUploadSuccessEvent.java
com.squareup.tape.sample.ImageUploadTaskQueue.java
com.squareup.tape.sample.ImageUploadTaskService.java
com.squareup.tape.sample.ImageUploadTask.java
com.squareup.tape.sample.SampleActivity.java
com.squareup.tape.sample.SampleApplication.java