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