View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.log4j.chainsaw.prefs;
    18
    19  import java.io.BufferedInputStream;
    20  import java.io.BufferedOutputStream;
    21  import java.io.File;
    22  import java.io.FileInputStream;
    23  import java.io.FileOutputStream;
    24  import java.io.IOException;
    25  import java.io.InputStream;
    26  import java.io.OutputStream;
    27  import java.net.URLEncoder;
    28  import java.util.EventListener;
    29  import java.util.Properties;
    30
    31  import javax.swing.event.EventListenerList;
    32
    33
    34  /**
    35   * SettingManager allows components to register interest in Saving/Loading
    36   * of general application preferences/settings.
    37   *
    38   * @author Paul Smith &lt;psmith@apache.org&gt;
    39   * @author Scott Deboy &lt;sdeboy@apache.org&gt;
    40   *
    41   */
    42  public final class SettingsManager {
    43      private static final SettingsManager instance = new SettingsManager();
    44      private static final String GLOBAL_SETTINGS_FILE_NAME = "chainsaw.settings.properties";
    45      private static final String HEADER = "Chainsaws Settings Files";
    46      private EventListenerList listenerList = new EventListenerList();
    47      private Properties defaultProperties = new Properties();
    48
    49      /**
    50       * Initialises the SettingsManager by loading the default Properties from
    51       * a resource
    52       *
    53       */
    54      private SettingsManager() {
    55          //	load the default properties as a Resource
    56          InputStream is = null;
    57
    58          try {
    59              is = this.getClass().getClassLoader()
    60                       .getResource("org/apache/log4j/chainsaw/prefs/default.properties")
    61                       .openStream();
    62              defaultProperties.load(is);
    63
    64              //      defaultProperties.list(System.out);
    65              is.close();
    66          } catch (IOException e) {
    67              e.printStackTrace();
    68          } finally {
    69              if (is != null) {
    70                  try {
    71                      is.close();
    72                  } catch (Exception e) {
    73                  }
    74              }
    75          }
    76      }
    77
    78      /**
    79       * Returns the singleton instance of the SettingsManager
    80       * @return settings manager
    81       */
    82      public static SettingsManager getInstance() {
    83          return instance;
    84      }
    85
    86      /**
    87       * Registers the listener with the manager
    88       * @param listener
    89       */
    90      public void addSettingsListener(SettingsListener listener) {
    91          listenerList.add(SettingsListener.class, listener);
    92      }
    93
    94      /**
    95       * Requests that the settings be loaded, all listeners will be notified of
    96       * this call, and configure themselves according to the values found in the
    97       * loaded settings
    98       *
    99       */
    100     public void loadSettings() {
    101         /*
    102          * Ok, note we ensure we have a .chainsaw directory in the users
    103          * home folder, and create a chainsaw.settings.properties file..
    104          */
    105         File settingsDir = getSettingsDirectory();
    106
    107         if (!settingsDir.exists()) {
    108             settingsDir.mkdir();
    109         }
    110
    111         loadGlobalSettings();
    112         loadProfileableSettings();
    113     }
    114
    115     /**
    116      *
    117      */
    118     private void loadProfileableSettings() {
    119         EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
    120
    121         for (int i = 0; i < listeners.length; i++) {
    122             SettingsListener settingsListener = (SettingsListener) listeners[i];
    123
    124             if (settingsListener instanceof Profileable) {
    125                 Profileable p = (Profileable) settingsListener;
    126                 loadProfileble(p);
    127             }
    128         }
    129     }
    130
    131     private void loadProfileble(Profileable p) {
    132         LoadSettingsEvent event = createProfilebleEvent(p);
    133         p.loadSettings(event);
    134     }
    135
    136     private LoadSettingsEvent createProfilebleEvent(Profileable p) {
    137         Properties loadedProperties = new Properties();
    138         loadedProperties.putAll(getDefaultSettings());
    139         loadedProperties.putAll(loadProperties(p));
    140
    141
    142         LoadSettingsEvent event = new LoadSettingsEvent(this, loadedProperties);
    143
    144         return event;
    145     }
    146
    147     /**
    148      * @param p
    149      * @return
    150      */
    151     private Properties loadProperties(Profileable p) {
    152         Properties properties = new Properties(defaultProperties);
    153         InputStream is = null;
    154
    155         File f = new File(getSettingsDirectory(),
    156         		URLEncoder.encode(p.getNamespace() + ".properties"));
    157
    158         if (!f.exists()) {
    159         	f = new File(getSettingsDirectory(),
    160             		p.getNamespace() + ".properties");
    161         }
    162
    163         if (f.exists()) {
    164             try {
    165                 is = new BufferedInputStream(new FileInputStream(f));
    166
    167                 Properties toLoad = new Properties();
    168                 toLoad.load(is);
    169                 properties.putAll(toLoad);
    170             } catch (IOException ioe) {
    171                 ioe.printStackTrace();
    172             } finally {
    173                 if (is != null) {
    174                     try {
    175                         is.close();
    176                     } catch (IOException e1) {
    177                         e1.printStackTrace();
    178                     }
    179                 }
    180             }
    181         }
    182
    183         return properties;
    184     }
    185
    186     private void loadGlobalSettings() {
    187         EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
    188         LoadSettingsEvent event = null;
    189
    190         for (int i = 0; i < listeners.length; i++) {
    191             SettingsListener settingsListener = (SettingsListener) listeners[i];
    192
    193             if (event == null) {
    194                 Properties loadedProperties = loadGlobalProperties();
    195
    196                 //        loadedProperties.list(System.out);
    197                 event = new LoadSettingsEvent(this, loadedProperties);
    198             }
    199
    200             settingsListener.loadSettings(event);
    201         }
    202     }
    203
    204     /**
    205      * Creates a SaveSettingsEvent and calls all the SettingsListeners
    206      * to populate the properties with configuration information
    207      *
    208      */
    209     public void saveSettings() {
    210         /*
    211          * Ok, note we ensure we have a .chainsaw directory in the users
    212          * home folder, and create a chainsaw.settings.properties file..
    213          */
    214         File settingsDir = getSettingsDirectory();
    215
    216         if (!settingsDir.exists()) {
    217             settingsDir.mkdir();
    218         }
    219
    220         saveGlobalSettings(settingsDir);
    221         saveProfileableSetting(settingsDir);
    222     }
    223
    224     /**
    225      * Looks up all the Profileable's that have been registered
    226      * and creates a new event for each of them, and ensures that they
    227      * are saved within a separate external store
    228      * @param settingsDir
    229      */
    230     private void saveProfileableSetting(File settingsDir) {
    231         EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
    232         SaveSettingsEvent event = null;
    233
    234         for (int i = 0; i < listeners.length; i++) {
    235             SettingsListener settingsListener = (SettingsListener) listeners[i];
    236
    237             if (settingsListener instanceof Profileable) {
    238                 Profileable profileable = (Profileable) settingsListener;
    239                 event = new SaveSettingsEvent(this, getSettingsDirectory());
    240
    241                 profileable.saveSettings(event);
    242
    243                 OutputStream os = null;
    244
    245                 try {
    246                     os = new BufferedOutputStream(new FileOutputStream(
    247                                 new File(settingsDir,
    248                                 		 URLEncoder.encode(profileable.getNamespace()) + ".properties")));
    249                     event.getProperties().store(os, HEADER);
    250                 } catch (Exception e) {
    251                     e.printStackTrace();
    252                 } finally {
    253                     if (os != null) {
    254                         try {
    255                             os.close();
    256                         } catch (IOException e1) {
    257                             e1.printStackTrace();
    258                         }
    259                     }
    260                 }
    261             }
    262         }
    263     }
    264
    265     private void saveGlobalSettings(File settingsDir) {
    266         EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
    267         SaveSettingsEvent event = null;
    268
    269         for (int i = 0; i < listeners.length; i++) {
    270             SettingsListener settingsListener = (SettingsListener) listeners[i];
    271
    272             if (!(settingsListener instanceof Profileable)) {
    273                 if (event == null) {
    274                     event = new SaveSettingsEvent(this, getSettingsDirectory());
    275                 }
    276
    277                 settingsListener.saveSettings(event);
    278             }
    279         }
    280
    281         OutputStream os = null;
    282
    283         try {
    284             os = new BufferedOutputStream(new FileOutputStream(
    285                         new File(settingsDir, GLOBAL_SETTINGS_FILE_NAME)));
    286             event.getProperties().store(os, HEADER);
    287         } catch (Exception e) {
    288             e.printStackTrace();
    289         } finally {
    290             if (os != null) {
    291                 try {
    292                     os.close();
    293                 } catch (IOException e1) {
    294                     e1.printStackTrace();
    295                 }
    296             }
    297         }
    298     }
    299
    300     public File getSettingsDirectory() {
    301         return new File(System.getProperty("user.home"), ".chainsaw");
    302     }
    303
    304     public void configure(SettingsListener listener) {
    305         if (listener instanceof Profileable) {
    306             loadProfileble((Profileable) listener);
    307         } else {
    308             Properties loadedProperties = loadGlobalProperties();
    309             LoadSettingsEvent event = new LoadSettingsEvent(this,
    310                     loadedProperties);
    311             listener.loadSettings(event);
    312         }
    313     }
    314
    315     /**
    316      * Returns the current Properties settings for this user
    317      * by merging the default Properties with the ones we find in their directory.
    318      *
    319      * @return
    320      */
    321     private Properties loadGlobalProperties() {
    322         Properties properties = new Properties(defaultProperties);
    323         InputStream is = null;
    324
    325         File f = new File(getSettingsDirectory(), GLOBAL_SETTINGS_FILE_NAME);
    326
    327         if (f.exists()) {
    328             try {
    329                 is = new BufferedInputStream(new FileInputStream(f));
    330
    331                 Properties toLoad = new Properties();
    332                 toLoad.load(is);
    333                 properties.putAll(toLoad);
    334             } catch (IOException ioe) {
    335                 ioe.printStackTrace();
    336             } finally {
    337                 if (is != null) {
    338                     try {
    339                         is.close();
    340                     } catch (IOException e1) {
    341                         e1.printStackTrace();
    342                     }
    343                 }
    344             }
    345         }
    346
    347         return properties;
    348     }
    349
    350     /**
    351      * Returns the loaded default settings, which can be used by
    352      * other classes within this package.
    353      * @return Properties defaults
    354      */
    355     public Properties getDefaultSettings() {
    356         return defaultProperties;
    357     }
    358 }