// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program 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 General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.base; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.Enumeration; import java.util.Vector; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; import com.netscape.cmsutil.util.Utils; /** * FileConfigStore: * Extends HashConfigStore with methods to load/save from/to file for * persistent storage. This is a configuration store agent who * reads data from a file. *

* Note that a LdapConfigStore can be implemented so that it reads * the configuration stores from the Ldap directory. *

* * @version $Revision$, $Date$ * @see PropConfigStore */ public class FileConfigStore extends PropConfigStore implements IConfigStore { private File mFile = null; /** * Constructs a file configuration store. *

* * @param fileName file name * @exception EBaseException failed to create file configuration */ public FileConfigStore(String fileName) throws EBaseException { super(null); // top-level store without a name mFile = new File(fileName); if (!mFile.exists()) { throw new EBaseException(CMS.getUserMessage("CMS_BASE_NO_CONFIG_FILE", mFile.getPath())); } load(fileName); } /** * Loads property file into memory. *

* * @param fileName file name * @exception EBaseException failed to load configuration */ public void load(String fileName) throws EBaseException { try { FileInputStream fi = new FileInputStream(fileName); BufferedInputStream bis = new BufferedInputStream(fi); super.load(bis); } catch (IOException e) { throw new EBaseException("input stream error " + fileName, e); } } /** * The original config file is copied to * .. * Commits the current properties to the configuration file. *

* * @param backup */ public void commit(boolean createBackup) throws EBaseException { if (createBackup) { File newName = new File(mFile.getPath() + "." + Long.toString(System.currentTimeMillis())); try { if( Utils.isNT() ) { // NT is very picky on the path Utils.exec( "copy " + mFile.getAbsolutePath().replace( '/', '\\' ) + " " + newName.getAbsolutePath().replace( '/', '\\' ) ); } else { // Create a copy of the original file which // preserves the original file permissions. Utils.exec( "cp -p " + mFile.getAbsolutePath() + " " + newName.getAbsolutePath() ); } // Proceed only if the backup copy was successful. if( !newName.exists() ) { throw new EBaseException( "backup copy failed" ); } else { // Make certain that the backup file has // the correct permissions. if( !Utils.isNT() ) { Utils.exec( "chmod 00660 " + newName.getAbsolutePath() ); } } } catch( EBaseException e ) { throw new EBaseException( "backup copy failed" ); } } // Overwrite the contents of the original file // to preserve the original file permissions. save( mFile.getPath() ); try { // Make certain that the original file retains // the correct permissions. if( !Utils.isNT() ) { Utils.exec( "chmod 00660 " + mFile.getCanonicalPath() ); } } catch( Exception e ) { } } /** * Saves in-memory properties to a specified file. *

* Note that the superclass's save is synchronized. It * means no properties can be altered (inserted) at * the saving time. *

* * @param fileName filename * @exception EBaseException failed to save configuration */ public void save(String fileName) throws EBaseException { try { FileOutputStream fo = new FileOutputStream(fileName); PrintWriter writer = new PrintWriter(new OutputStreamWriter(fo)); printSubStore(writer, this, ""); writer.close(); fo.close(); } catch (IOException e) { throw new EBaseException("output stream error " + fileName, e); } } private void printSubStore(PrintWriter writer, IConfigStore store, String name) throws EBaseException, IOException { // print keys Enumeration e0 = store.getPropertyNames(); Vector v = new Vector(); while (e0.hasMoreElements()) { v.addElement(e0.nextElement()); } // sorting them lexicographically while (v.size() > 0) { String pname = (String) v.firstElement(); int j = 0; for (int i = 1; i < v.size(); i++) { String s = (String) v.elementAt(i); if (pname.compareTo(s) > 0) { j = i; pname = (String) v.elementAt(i); } } v.removeElementAt(j); writer.println(name + pname + "=" + store.getString(pname)); } // print substores Enumeration e1 = store.getSubStoreNames(); while (e1.hasMoreElements()) { v.addElement(e1.nextElement()); } while (v.size() > 0) { String pname = (String) v.firstElement(); int j = 0; for (int i = 1; i < v.size(); i++) { String s = (String) v.elementAt(i); if (pname.compareTo(s) > 0) { j = i; pname = (String) v.elementAt(i); } } v.removeElementAt(j); printSubStore(writer, store.getSubStore(pname), name + pname + "."); } } }