Environment.java

/*
 * Created on 2010/07/26
 * Copyright (C) 2010 Koga Laboratory. All rights reserved.
 *
 */
package org.mklab.tool.graph.gnuplot;

import java.io.File;
import java.text.MessageFormat;


/**
 * gnuplotの実行環境を表すクラスです。
 * 
 * @author Yuhi Ishikura
 * @version $Revision$, 2010/07/26
 */
public final class Environment implements Cloneable {

  /** {@link Gnuplot}クラスでデフォルトで利用する共有環境オブジェクトです。 */
  private static Environment sharedEnvironment;

  /** 作業ディレクトリです。 */
  private File workingDirectory = null;
  /** ホームディレクトリです。 */
  private File homeDirectory = null;

  /**
   * gnuplotの実行環境を表す共有オブジェクトを取得します。
   * 
   * @return Gnuplotの実行環境を表す共有オブジェク
   */
  public static synchronized Environment getSharedEnvironment() {
    if (sharedEnvironment == null) {
      sharedEnvironment = new Environment();
    }
    return sharedEnvironment;
  }

  /**
   * 与えられたgnuplot環境をデフォルトの環境にセットアップします。
   * 
   * @param env 設定する環境
   */
  private static void setupDefaultEnvironment(Environment env) {
    final File homeDirectory = EnvironmentLookup.findHomeDirectory();
    if (isValidateHomeDirectory(homeDirectory)) {
      env.homeDirectory = homeDirectory;
    }

    final File workingDirectory = EnvironmentLookup.findWorkingDirectory();
    if (isValidWorkingDirectory(workingDirectory)) {
      env.workingDirectory = workingDirectory;
    }
  }

  /**
   * 新しく生成された{@link Environment}オブジェクトを初期化します。  
   * 
   * インスタンス生成時に環境を調べます。
   * 
   * ユーザーにより設定されたパスに問題があった場合には例外がスローされます。 
   * 
   * 特にパスの設定を行っていない場合には、デフォルト値としてカレントディレクトリが設定されます。
   * 
   * @throws IllegalArgumentException 設定されたGNUPLOT_HOMEが見つからない場合
   */
  public Environment() {
    setupDefaultEnvironment(this);
  }

  /**
   * gnuplotの作業ディレクトリを取得します。
   * 
   * @return 作業ディレクトリ
   */
  public File getWorkingDirectory() {
    return this.workingDirectory;
  }

  /**
   * gnuplotの作業ディレクトリを設定します。
   * 
   * @param workingDirectory gnuplotの作業ディレクトリ
   */
  public void setWorkingDirectory(File workingDirectory) {
    if (isValidWorkingDirectory(workingDirectory)) {
      this.workingDirectory = workingDirectory;
    }
  }

  /**
   * 作業ディレクトリの検証を行います。 
   * 
   * @param dir 検証する作業ディレクトリ
   * @return true if dir is valid
   */
  private static boolean isValidWorkingDirectory(File dir) {
    if (dir == null) {
      return false;
    }
    if (dir.isFile()) {
      return false;
    }
    if (dir.exists() == false) {
      return false;
    }
    if (dir.canWrite() == false) {
      return false;
    }
    
    return true;
  }

  /**
   * gnuplotのホームディレクトリを取得します。
   * 
   * @return gnuplotPath gnuplotのホームディレクトリ
   */
  public File getHomeDirectory() {
    return this.homeDirectory;
  }
  
  /**
   * Returns true if this has home directory.
   * 
   * @return true if this has home directory
   */
  public boolean hasHomeDirectory() {
    return this.homeDirectory != null;
  }
  
  /**
   * Returns true if this has working directory.
   * 
   * @return true if this has working directory
   */
  public boolean hasWorkingDirectory() {
    return this.workingDirectory != null;
  }


  /**
   * gnuplotのホームディレクトリを設定します。
   * 
   * @param home gnuplotのホームディレクトリ
   */
  public void setHomeDirectory(File home) {
    if (isValidateHomeDirectory(home)) {
      this.homeDirectory = home;
    }
  }

  /**
   * gnuplotホームディレクトリの検証を行います。 
   * 
   * @param home 検証するディレクトリ
   * @return true if home is valid
   */
  private static boolean isValidateHomeDirectory(File home) {
    isValidWorkingDirectory(home);

    final File binDir1 = new File(home, "bin"); //$NON-NLS-1$
    final File binDir2 = new File(home, "binary"); //$NON-NLS-1$
    if (binDir1.exists() == false && binDir2.exists() == false) {
      return false;
      //throw new IllegalArgumentException("Not a gnuplot home directory. Not found gnuplot binary. : " + home.getAbsolutePath()); //$NON-NLS-1$
    }
    
    return true;
  }

  /**
   * このオブジェクトのシャローコピーを返します。
   * 
   * @return このオブジェクトのシャローコピー
   */
  @Override
  public Environment clone() {
    try {
      return (Environment)super.clone();
    } catch (CloneNotSupportedException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return MessageFormat.format("Environment [homeDirectory={0}, workingDirectory={1}]", this.homeDirectory, this.workingDirectory); //$NON-NLS-1$
  }

}