Package wyfs.util

Source Code of wyfs.util.VirtualRoot$Entry

package wyfs.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;

import wyfs.lang.Content;
import wyfs.lang.Path;
import wyfs.lang.Path.ID;
import wyfs.util.DirectoryRoot.Folder;

/**
* <p>
* Provides an implementation of <code>Path.Root</code> which stores files in
* memory, rather than on disk or within e.g. a Jar file. Initially, a virtual
* root is completely empty since there is nothing backing it. Virtual roots are
* used to hold temporary files that are generated during compilation and which
* one does not want stored on e.g. the file system.
* </p>
*
* <p>
* As an example, intermediate Wyil files are often stored in virtual root. The
* build task will typically use a virtual root as the default (meaning wyil
* files are not written to disk during compilation), but the user can then
* override this in order to examine them (e.g. for debugging).
* </p>
*
* @author David J. Pearce
*
*/
public class VirtualRoot extends AbstractRoot<VirtualRoot.Folder> {

  /**
   * Construct a virtual root out of nothing.
   *
   * @param contentTypes
   *            --- registry of known content types and their "suffixes"
   * @throws IOException
   */
  public VirtualRoot(Content.Registry contentTypes) {
    super(contentTypes);
  }

  @Override
  protected Folder root() {
    return new Folder(Trie.ROOT);
  }

  /**
   * An entry is a file on the file system which represents a Whiley module. The
   * file may be encoded in a range of different formats. For example, it may be a
   * source file and/or a binary wyil file.
   *
   * @author David J. Pearce
   *
   */
  public static final class Entry<T> extends AbstractEntry<T> implements Path.Entry<T> {

    /**
     * The following is use to determine the appropriate "suffix" of an
     * entry.
     */
    private final Content.Registry contentTypes;

    /**
     * The raw data representing the contents of this file. Initially, this
     * is empty as one would expect.
     */
    private byte[] data;

    /**
     * The last modified date. This is a time stamp used to determine when
     * the file was last modified in order to calculate which dependents
     * need recompilation.
     */
    private long lastModified;

    public Entry(Path.ID id, Content.Registry contentTypes) {
      super(id);
      this.data = new byte[0];
      this.contentTypes = contentTypes;
    }

    public String location() {
      return "~:" + id.toString();
    }

    public String suffix() {
      return contentTypes.suffix(contentType);
    }

    public long lastModified() {
      return lastModified;
    }

    public InputStream inputStream() {
      return new ByteArrayInputStream(data);
    }

    public OutputStream outputStream() {
      lastModified = System.currentTimeMillis();
      data = new byte[0];
      // create an output stream which will automatically resize the given
      // array.
      return new OutputStream() {
        private int pos = 0;

        public void write(int b) {
          if (pos >= data.length) {
            data = Arrays.copyOf(data, (data.length + 1) * 2);
          }
          data[pos++] = (byte) b;
        }
      };
    }

    public String toString() {
      return location();
    }
  }

  /**
   * Represents a directory in the virtual file system.
   *
   * @author David J. Pearce
   *
   */
  public final class Folder extends AbstractFolder {
    public Folder(Path.ID id) {
      super(id);
    }

    @Override
    protected Path.Item[] contents() throws IOException {
      // Initially, a virtual folder is always empty.
      return new Path.Item[0];
    }

    @Override
    public <T> Path.Entry<T> create(ID nid, Content.Type<T> ct) throws IOException {
      if (nid.size() == 1) {
        // attempting to create an entry in this folder
        Path.Entry<T> e = super.get(nid.subpath(0, 1), ct);
        if (e == null) {
          // Entry doesn't already exist, so create it
          nid = id.append(nid.get(0));
          e = new Entry(nid, contentTypes);
          e.associate(ct, null);
          super.insert(e);
        }
        return e;
      } else {
        // attempting to create entry in subfolder.
        Path.Folder folder = getFolder(nid.get(0));
        if (folder == null) {
          // Folder doesn't already exist, so create it.
          folder = new Folder(id.append(nid.get(0)));
          super.insert(folder);
        }
        return folder.create(nid.subpath(1, nid.size()), ct);
      }
    }

    public String toString() {
      return "~:" + id;
    }
  }
}
TOP

Related Classes of wyfs.util.VirtualRoot$Entry

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.