001    /**
002     * ========================================
003     * JFreeReport : a free Java report library
004     * ========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/
007     *
008     * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009     *
010     * This library is free software; you can redistribute it and/or modify it under the terms
011     * of the GNU Lesser General Public License as published by the Free Software Foundation;
012     * either version 2.1 of the License, or (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public License along with this
019     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020     * Boston, MA 02111-1307, USA.
021     *
022     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023     * in the United States and other countries.]
024     *
025     * ------------
026     * $Id: FileConfigStorage.java 3525 2007-10-16 11:43:48Z tmorgner $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.modules.preferences.filesystem;
033    
034    import java.io.BufferedInputStream;
035    import java.io.BufferedOutputStream;
036    import java.io.File;
037    import java.io.FileInputStream;
038    import java.io.FileOutputStream;
039    import java.io.InputStream;
040    import java.io.OutputStream;
041    import java.util.Enumeration;
042    import java.util.Iterator;
043    import java.util.Properties;
044    
045    import org.jfree.base.config.HierarchicalConfiguration;
046    import org.jfree.base.config.ModifiableConfiguration;
047    import org.jfree.report.modules.preferences.base.ConfigFactory;
048    import org.jfree.report.modules.preferences.base.ConfigStorage;
049    import org.jfree.report.modules.preferences.base.ConfigStoreException;
050    import org.jfree.util.Configuration;
051    
052    
053    /**
054     * The FileConfigStorage is a storage provider that stores its content on the
055     * local filesystem. The directory used contains the data as plain text property
056     * files.
057     *
058     * @author Thomas Morgner
059     */
060    public class FileConfigStorage implements ConfigStorage
061    {
062      /** The base directory of the storage provider. */
063      private final File baseDirectory;
064      /** The configuration header text that is appended to all property files. */
065      private static final String CONFIGHEADER =
066              "part of the jfreereport filesystem config store";
067    
068      /**
069       * Creates a new file config storage and stores the contents in the given
070       * directory.
071       *
072       * @param baseDirectory the directory that should contain the files.
073       */
074      public FileConfigStorage(final File baseDirectory)
075      {
076        this.baseDirectory = baseDirectory;
077      }
078    
079      /**
080       * Stores the given properties on the defined path.
081       * <p/>
082       * This implementation stores the data as property files.
083       *
084       * @param configPath the configuration path that specifies where to store the
085       *                   properties.
086       * @param properties the properties which should be stored.
087       * @throws ConfigStoreException if an error occured.
088       * @see org.jfree.report.modules.misc.configstore.base.ConfigStorage
089       *      #storeProperties(java.lang.String, java.util.Properties)
090       */
091      public void store(final String configPath, final Configuration config)
092              throws ConfigStoreException
093      {
094        if (ConfigFactory.isValidPath(configPath) == false)
095        {
096          throw new IllegalArgumentException("The give path is not valid.");
097        }
098        final Enumeration keys = config.getConfigProperties();
099        final Properties properties = new Properties();
100        while (keys.hasMoreElements())
101        {
102          final String key = (String) keys.nextElement();
103          final String value = config.getConfigProperty(key);
104          if (value != null && key != null)
105          {
106            properties.put(key, value);
107          }
108        }
109    
110        final File target = new File(baseDirectory, configPath);
111        if (target.exists() == true && target.canWrite() == false)
112        {
113          return;
114        }
115        try
116        {
117          final OutputStream out = new BufferedOutputStream(new FileOutputStream(
118                  target));
119          properties.store(out, CONFIGHEADER);
120          out.close();
121        }
122        catch (Exception e)
123        {
124          throw new ConfigStoreException("Failed to write config " + configPath, e);
125        }
126      }
127    
128      /**
129       * Loads the properties from the given path, specifying the given properties
130       * as default.
131       *
132       * @param configPath the configuration path from where to load the
133       *                   properties.
134       * @param defaults   the property set that acts as fallback to provide default
135       *                   values.
136       * @return the loaded properties.
137       * @throws ConfigStoreException if an error occured.
138       */
139      public Configuration load(final String configPath,
140                                final Configuration defaults)
141              throws ConfigStoreException
142      {
143        if (ConfigFactory.isValidPath(configPath) == false)
144        {
145          throw new IllegalArgumentException("The given path is not valid.");
146        }
147        try
148        {
149          final Properties properties = new Properties();
150          final File target = new File(baseDirectory, configPath);
151          final InputStream in = new BufferedInputStream(new FileInputStream(
152                  target));
153          properties.load(in);
154          in.close();
155    
156          final ModifiableConfiguration config = new HierarchicalConfiguration(defaults);
157          final Iterator keys = properties.keySet().iterator();
158          while (keys.hasNext())
159          {
160            final String key = (String) keys.next();
161            config.setConfigProperty(key, properties.getProperty(key));
162          }
163          return config;
164        }
165        catch (Exception e)
166        {
167          throw new ConfigStoreException("Failed to read config" + configPath, e);
168        }
169      }
170    
171      /**
172       * Tests, whether some configuration data exists for the given configuration.
173       *
174       * @param configPath the configuration path to the property storage.
175       * @return true, if there are properties under this path, false otherwise.
176       */
177      public boolean isAvailable(final String configPath)
178      {
179        if (ConfigFactory.isValidPath(configPath) == false)
180        {
181          throw new IllegalArgumentException("The give path is not valid.");
182        }
183    
184        final File target = new File(baseDirectory, configPath);
185        return target.exists() && target.canRead();
186      }
187    
188      public String toString()
189      {
190        return "FileConfigStorage={baseDir=" + baseDirectory + "}";
191      }
192    }