Package org.xmlvm.proc.out

Source Code of org.xmlvm.proc.out.OutputFile$DelayedDataProvider

/* Copyright (c) 2002-2011 by XMLVM.org
*
* Project Info:  http://www.xmlvm.org
*
* 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.1 of the License, or
* (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*/

package org.xmlvm.proc.out;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.xmlvm.Log;
import org.xmlvm.util.FileUtil;
import org.xmlvm.util.universalfile.UniversalFile;
import org.xmlvm.util.universalfile.UniversalFileCreator;

/**
* This class represents a file and its content, read to be written out to the
* file system.
*/
public class OutputFile
{
  public static final String TAG_LIB_NAME= "lib-name";

  /**
   * Defines a data provider that can be used to de-couple the creation of the
   * OutputFile from the time the data is produced. getData() is only called
   * when the data is actually needed. It is also guaranteed that the method
   * is only called once inside OutputFile.
   */
  public static interface DelayedDataProvider
  {
    public UniversalFile getData();
  }

  private UniversalFile data;
  private DelayedDataProvider provider;
  private String location= "";
  private String fileName= "";
  private String origin= null;
  private Map<String, String> tags= new HashMap<String, String>();

  /**
   * Create an empty output file. It is required to set data later
   */
  public OutputFile()
  {
  }

  public OutputFile(DelayedDataProvider provider)
  {
    this.provider= provider;
  }

  /**
   * Create a new file with the given string content.
   */
  public OutputFile(String data)
  {
    setData(data);
  }

  /**
   * Create a new file with the given string content.
   */
  public OutputFile(byte[] data)
  {
    setData(data, System.currentTimeMillis());
  }

  /**
   * Create a new file with the given string content.
   */
  public OutputFile(byte[] data, long lastModified)
  {
    setData(data, lastModified);
  }

  public OutputFile(UniversalFile file)
  {
    this.data= file;
  }

  /**
   * Returns the contents of this file.
   */
  public UniversalFile getData()
  {
    maybeLoadDelayedData();
    if (data == null)
    {
      return null;
    }
    return data;
  }

  /**
   * Returns the data as a byte array.
   * <p>
   * Same as getData().getFileAsBytes();
   */
  public byte[] getDataAsBytes()
  {
    maybeLoadDelayedData();
    return data.getFileAsBytes();
  }

  /**
   * Returns the data as a string.
   * <p>
   * Same as getData().getFileAsString();
   */
  public String getDataAsString()
  {
    maybeLoadDelayedData();
    return data.getFileAsString();
  }

  /**
   * Sets the content of this file.
   */
  public final void setData(String data)
  {
    setData(data, System.currentTimeMillis());
  }

  /**
   * Sets the content of this file.
   */
  public final void setData(String data, long lastModified)
  {
    if (data == null)
    {
      this.data= null;
    }
    else
    {
      try
      {
        setData(data.getBytes("UTF-8"), lastModified);
      }
      catch (UnsupportedEncodingException ex)
      {
        Log.error(ex.getMessage());
      }
    }
  }

  /**
   * Sets the content of this file.
   */
  public final void setData(byte[] data, long lastModified)
  {
    this.data= UniversalFileCreator.createFile("", data, lastModified);
  }

  /**
   * Sets the content of this file from an Input stream
   *
   * @param stream
   *            The InputStream to use - only UTF-8 streams are supported
   * @return true, if everything was successful
   */
  public boolean setDataFromStream(InputStream stream, long lastModified)
  {
    if (stream == null)
    {
      return false;
    }
    this.data= UniversalFileCreator.createFile("", stream, lastModified);
    return true;
  }

  /**
   * Sets the content of this file from a BufferReader
   *
   * @param in
   *            The BufferReader to use as input
   * @return true, if everything was successful
   */
  public boolean setDataFromReader(BufferedReader in)
  {
    if (in == null)
    {
      return false;
    }
    StringWriter out= new StringWriter();
    if (FileUtil.copyReaders(in, out))
    {
      setData(out.toString());
    }
    return false;
  }

  /**
   * Returns the output location of this file.
   */
  public String getLocation()
  {
    return location;
  }

  /**
   * Sets the output location of this file.
   */
  public void setLocation(String location)
  {
    this.location= (new File(location)).getAbsolutePath();
  }

  /**
   * Returns the name of this file (excluding the path).
   */
  public String getFileName()
  {
    return fileName;
  }

  /**
   * Sets the name of this file (excluding the path).
   */
  public void setFileName(String fileName)
  {
    this.fileName= fileName;
  }

  /**
   * Returns the path from which this resource originated from. Returns
   * <code>null</code>, if no origin can be assigned.
   * <p>
   * The origin is used to cache resources generated from the original
   * resource.
   */
  public String getOrigin()
  {
    return origin;
  }

  /**
   * Sets the origin of this file. This is typically a path to the original
   * file from which this resource has been generated from and is typically
   * used for caching.
   */
  public void setOrigin(String origin)
  {
    this.origin= origin;
  }

  /**
   * Get a list of the files affected by this OutputFile class
   * <p>
   * If this OutputFile only contains a file, it will return itself as the
   * only array element.
   *
   * @return Array of affected files.
   */
  public ArrayList<OutputFile> getAffectedSourceFiles()
  {
    maybeLoadDelayedData();
    ArrayList<OutputFile> result= new ArrayList<OutputFile>();
    if (data == null || data.isFile())
    {
      result.add(this);
    }
    else
    {
      UniversalFile[] files= data.listFilesRecursively();
      int dataPathLength= data.getAbsolutePath().length();
      for (UniversalFile file : files)
      {
        String relativePath= file.getAbsolutePath().substring(dataPathLength + 1);
        OutputFile outputFile= new OutputFile(file);
        String path= getFullPath();
        if (!relativePath.isEmpty())
        {
          path+= relativePath;
        }

        String filelocation= path.substring(0, path.length() - file.getName().length());
        outputFile.setLocation(filelocation);
        outputFile.setFileName(file.getName());

        result.add(outputFile);
      }
    }
    return result;
  }

  /**
   * Get the fill pathname of the output file
   *
   * @return The full pathname as String
   */
  public String getFullPath()
  {
    return location + (location.endsWith(File.separator) ? "" : File.separator) + fileName;
  }

  /**
   * Returns the path of this file relative to the given one.
   * <p>
   * <p>
   * Example:
   * <p>
   * Path of this file: /foo/bar/tar/file.txt
   * <p>
   * Given basePath: /foo/bar
   * <p>
   * Result: tar/file.txt
   *
   * @param basePath
   * @return
   */
  public String getRelativePath(String basePath)
  {
    String fullPath= getFullPath();

    if (!fullPath.startsWith(basePath))
    {
      Log.error("'" + basePath + "' is not a base path of '" + fullPath);
      return null;
    }
    String result= fullPath.substring(basePath.length());
    if (result.startsWith(File.separator))
    {
      result= result.substring(1);
    }
    return result;
  }

  /**
   * Write the given file to disk.
   *
   * @return Whether file was written successfully.
   */
  public boolean write()
  {
    if (location.isEmpty())
    {
      Log.warn("Cannot write OutputFile with no location: " + getFullPath());
      return false;
    }
    maybeLoadDelayedData();
    if (isEmpty())
    {
      Log.warn("Ignoring empty or non-existent file: " + getFullPath());
      return false;
    }
    String pathAndName= getFullPath();
    return data.saveAs(pathAndName);
  }

  /**
   * Returns whether the contents of this file is different from the
   * destination. If the destination doesn't exist, this method returns
   * <code>true</code>.
   */
  public boolean isDifferentFromExisting()
  {
    UniversalFile destination= UniversalFileCreator.createFile(new File(getFullPath()));
    if (!destination.exists() || !destination.isFile())
    {
      return true;
    }

    maybeLoadDelayedData();
    return data.isDifferentFromExisting(getFullPath());
  }

  /**
   * Determines if the file is empty.
   *
   * @return Whether the file empty or not present.
   */
  public boolean isEmpty()
  {
    maybeLoadDelayedData();
    return data == null || data.isEmpty();
  }

  private void maybeLoadDelayedData()
  {
    if (provider != null)
    {
      data= provider.getData();
      provider= null;
    }
  }

  /**
   * Returns the time stamp when the contents of this file have been changed
   * the last time.
   */
  public long getLastModified()
  {
    return data.getLastModified();
  }

  /**
   * Sets a new or overrides an existing tag value.
   *
   * @param tagName
   *            The name of the tag.
   * @param value
   *            The value of the tag.
   */
  public void setTag(String tagName, String value)
  {
    tags.put(tagName, value);
  }

  /**
   * Returns whether the tag with the given name exists on this file.
   */
  public boolean hasTag(String tagName)
  {
    return tags.containsKey(tagName);
  }

  /**
   * Returns the value of the tag with the given name.
   */
  public String getTag(String tagName)
  {
    return tags.get(tagName);
  }
}
TOP

Related Classes of org.xmlvm.proc.out.OutputFile$DelayedDataProvider

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.