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: ConfigFactory.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.base;
033    
034    
035    /**
036     * The config factory is used to access the currently active config storage
037     * implementation. The implementation itself allows to read or store a set of properties
038     * stored under a certain path.
039     *
040     * @author Thomas Morgner
041     */
042    public final class ConfigFactory
043    {
044      /**
045       * The selector configuration key that defines the active config storage
046       * implementation.
047       */
048      public static final String CONFIG_TARGET_KEY = "org.jfree.report.ConfigStore";
049    
050      /**
051       * The singleton instance of the config factory.
052       */
053      private static ConfigFactory factory;
054      /**
055       * The user storage is used to store user dependend settings.
056       */
057      private ConfigStorage userStorage;
058      /**
059       * The system storage is used to store system wide settings.
060       */
061      private ConfigStorage systemStorage;
062    
063      /**
064       * Returns the singleton instance of the config factory.
065       *
066       * @return the config factory
067       */
068      public static synchronized ConfigFactory getInstance ()
069      {
070        if (factory == null)
071        {
072          factory = new ConfigFactory();
073          factory.defineSystemStorage(new NullConfigStorage());
074          factory.defineUserStorage(new NullConfigStorage());
075        }
076        return factory;
077      }
078    
079      /**
080       * DefaultConstructor.
081       */
082      private ConfigFactory ()
083      {
084      }
085    
086      /**
087       * Defines the user storage implementation that should be used. This method should only
088       * be called by the module initialization methods.
089       *
090       * @param storage the user settings storage implementation.
091       */
092      public void defineUserStorage (final ConfigStorage storage)
093      {
094        if (storage == null)
095        {
096          throw new NullPointerException();
097        }
098        this.userStorage = storage;
099      }
100    
101      /**
102       * Defines the system storage implementation that should be used. This method should
103       * only be called by the module initialization methods.
104       *
105       * @param storage the system settings storage implementation.
106       */
107      public void defineSystemStorage (final ConfigStorage storage)
108      {
109        if (storage == null)
110        {
111          throw new NullPointerException();
112        }
113        this.systemStorage = storage;
114      }
115    
116      /**
117       * Returns the user settings storage implementation used in the config subsystem.
118       *
119       * @return the user settingsstorage provider.
120       */
121      public ConfigStorage getUserStorage ()
122      {
123        return userStorage;
124      }
125    
126      /**
127       * Returns the system settings storage implementation used in the config subsystem.
128       *
129       * @return the system settings storage provider.
130       */
131      public ConfigStorage getSystemStorage ()
132      {
133        return systemStorage;
134      }
135    
136      /**
137       * Checks, whether the given string denotes a valid config storage path. Such an path
138       * must not contain whitespaces or non-alphanumeric characters.
139       *
140       * @param path the path that should be tested.
141       * @return true, if the path is valid, false otherwise.
142       */
143      public static boolean isValidPath (final String path)
144      {
145        final char[] data = path.toCharArray();
146        for (int i = 0; i < data.length; i++)
147        {
148          if (Character.isJavaIdentifierPart(data[i]) == false)
149          {
150            return false;
151          }
152        }
153        return true;
154      }
155    
156      /**
157       * Encodes the given configuration path. All non-ascii characters get
158       * replaced by an escape sequence.
159       *
160       * @param path the path.
161       * @return the translated path.
162       */
163      public static String encodePath (final String path)
164      {
165        final char[] data = path.toCharArray();
166        final StringBuffer encoded = new StringBuffer();
167        for (int i = 0; i < data.length; i++)
168        {
169          if (data[i] == '$')
170          {
171            // double quote
172            encoded.append('$');
173            encoded.append('$');
174          }
175          else if (Character.isJavaIdentifierPart(data[i]) == false)
176          {
177            // padded hex string
178            encoded.append('$');
179            final String hex = Integer.toHexString(data[i]);
180            for (int x = hex.length(); x < 4; x++)
181            {
182              encoded.append('0');
183            }
184            encoded.append(hex);
185          }
186          else
187          {
188            encoded.append(data[i]);
189          }
190        }
191        return encoded.toString();
192    
193      }
194    }