Package freenet.config

Source Code of freenet.config.FilePersistentConfig

/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.config;

import freenet.support.LogThresholdCallback;
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
import freenet.support.Logger.LogLevel;
import freenet.support.io.Closer;
import freenet.support.io.FileUtil;
import freenet.support.io.LineReadingInputStream;

/**
* Global Config object which persists to a file.
*
* Reads the config file into a SimpleFieldSet when created.
* During init, SubConfig's are registered, and fed the relevant parts of the SFS.
* Once initialization has finished, we check whether there are any options remaining.
* If so, we complain about them.
* And then we write the config file back out.
*/
public class FilePersistentConfig extends PersistentConfig {

  final File filename;
  final File tempFilename;
  final protected String header;
  protected final Object storeSync = new Object();
  protected boolean writeOnFinished;

        private static volatile boolean logMINOR;
  static {
    Logger.registerLogThresholdCallback(new LogThresholdCallback(){
      @Override
      public void shouldUpdate(){
        logMINOR = Logger.shouldLog(LogLevel.MINOR, this);
      }
    });
  }

  public static FilePersistentConfig constructFilePersistentConfig(File f) throws IOException {
    return constructFilePersistentConfig(f, null);
  }

  public static FilePersistentConfig constructFilePersistentConfig(File f, String header) throws IOException {
    File filename = f;
    File tempFilename = new File(f.getPath()+".tmp");
    return new FilePersistentConfig(load(filename, tempFilename), filename, tempFilename, header);
  }

  static SimpleFieldSet load(File filename, File tempFilename) throws IOException {
    boolean filenameExists = filename.exists();
    boolean tempFilenameExists = tempFilename.exists();
    if(filenameExists && !filename.canWrite()) {
      Logger.error(FilePersistentConfig.class, "Warning: Cannot write to config file: "+filename);
      System.err.println("Warning: Cannot write to config file: "+filename);
    }
    if(tempFilenameExists && !tempFilename.canWrite()) {
      Logger.error(FilePersistentConfig.class, "Warning: Cannot write to config tempfile: "+tempFilename);
      System.err.println("Warning: Cannot write to config tempfile: "+tempFilename);
    }
    if(filenameExists) {
      if(filename.canRead() && filename.length() > 0) {
        try {
          return initialLoad(filename);
        } catch (FileNotFoundException e) {
          System.err.println("Cannot open config file "+filename+" : "+e+" - checking for temp file "+tempFilename);
        } catch (EOFException e) {
          System.err.println("Empty config file "+filename+" (end of file)");
        }
        // Other IOE's indicate a more serious problem.
      } else {
        // We probably won't be able to write it either.
        System.err.println("Cannot read config file "+filename);
      }
    }
    if(tempFilename.exists()) {
      if(tempFilename.canRead() && tempFilename.length() > 0) {
        try {
          return initialLoad(tempFilename);
        } catch (FileNotFoundException e) {
          System.err.println("Cannot open temp config file either: "+tempFilename+" : "+e);
        } // Other IOE's indicate a more serious problem.
      } else {
        System.err.println("Cannot read (temp) config file "+tempFilename);
        throw new IOException("Cannot read (temp) config file "+tempFilename);
      }
    }
    System.err.println("No config file found, creating new: "+filename);
    return null;
  }

  protected FilePersistentConfig(SimpleFieldSet origFS, File fnam, File temp) throws IOException {
    this(origFS, fnam, temp, null);
  }

  protected FilePersistentConfig(SimpleFieldSet origFS, File fnam, File temp, String header) throws IOException {
    super(origFS);
    this.filename = fnam;
    this.tempFilename = temp;
    this.header = header;
  }

  /** Load the config file into a SimpleFieldSet.
   * @throws IOException */
  private static SimpleFieldSet initialLoad(File toRead) throws IOException {
    if(toRead == null) return null;
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    LineReadingInputStream lis = null;
    try {
      fis = new FileInputStream(toRead);
      bis = new BufferedInputStream(fis);
      lis = new LineReadingInputStream(bis);
      // Config file is UTF-8 too!
      return new SimpleFieldSet(lis, 1024*1024, 128, true, true, true); // FIXME? advanced users may edit the config file, hence true?
    } finally {
      Closer.close(lis);
      Closer.close(bis);
      Closer.close(fis);
    }
  }

  @Override
  public void register(SubConfig sc) {
    super.register(sc);
  }

  @Override
  public void store() {
    if(!finishedInit) {
      writeOnFinished = true;
      return;
    }
    try {
      synchronized(storeSync) {
        innerStore();
      }
    } catch (IOException e) {
      String err = "Cannot store config: "+e;
      Logger.error(this, err, e);
      System.err.println(err);
      e.printStackTrace();
    }
  }

  /** Don't call without taking storeSync first */
  protected final void innerStore() throws IOException {
    if(!finishedInit)
      throw new IllegalStateException("SHOULD NOT HAPPEN!!");

    SimpleFieldSet fs = exportFieldSet();
    if(logMINOR)
      Logger.minor(this, "fs = " + fs);
    FileOutputStream fos = null;
    try {
      fos = new FileOutputStream(tempFilename);
      synchronized(this) {
        fs.setHeader(header);
        fs.writeToBigBuffer(fos);
      }
      fos.close();
      fos = null;
      FileUtil.renameTo(tempFilename, filename);
    }
    finally {
      Closer.close(fos);
    }
  }
 
  public void finishedInit() {
    super.finishedInit();
    if(writeOnFinished) {
      writeOnFinished = false;
      store();
    }
  }
}
TOP

Related Classes of freenet.config.FilePersistentConfig

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.