Clover coverage report - JBind Project
Coverage timestamp: Fr Mai 28 2004 11:17:36 CEST
file stats: LOC: 237   Methods: 8
NCLOC: 139   Classes: 1
This license of Clover is provided to support the development of JBind only. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover.
 
 Source file Conditionals Statements Methods TOTAL
Prefs.java 7,9% 12,6% 50% 13,5%
 1   
 /*
 2   
  * JBind
 3   
  *
 4   
  * Copyright (c) by Stefan Wachter. All rights reserved.
 5   
  *
 6   
  * Usage, modification, and redistribution is subject to license terms that are
 7   
  * available at 'http://www.jbind.org'. The JBind license is like the
 8   
  * 'Apache Software License V 1.1'.
 9   
  */
 10   
 package org.jbind.util.other;
 11   
 
 12   
 import java.io.BufferedInputStream;
 13   
 import java.io.BufferedOutputStream;
 14   
 import java.io.File;
 15   
 import java.io.FileInputStream;
 16   
 import java.io.FileOutputStream;
 17   
 import java.io.InputStream;
 18   
 import java.io.OutputStream;
 19   
 import java.util.prefs.Preferences;
 20   
 
 21   
 import org.jbind.base.Console;
 22   
 
 23   
 /**
 24   
  * Base class for managing preferences. Derived classes can use the {@link
 25   
  * #doMain} method to easily create a main method to manage the preferences.
 26   
  */
 27   
 public abstract class Prefs {
 28   
 
 29   
   private boolean mySystemNotUser;
 30   
   private Preferences myPreferences = null;
 31   
 
 32   
   /**
 33   
    * Creates a prefs object that manages the preferences of class this instance
 34   
    * belongs to.
 35   
    *
 36   
    * @param aSystemNotUser Determines if user or system preferences are to be
 37   
    * managed.
 38   
    */
 39  3
   protected Prefs(boolean aSystemNotUser) {
 40  3
     mySystemNotUser = aSystemNotUser;
 41   
   }
 42   
 
 43   
   /**
 44   
    * Gets the preferences of the class of this instance.
 45   
    *
 46   
    * @return <i>(required)</i>.
 47   
    */
 48  2985
   protected Preferences getPrefs() {
 49  2985
     if (null == myPreferences) {
 50  6
       if (mySystemNotUser) {
 51  0
         myPreferences = Preferences.systemNodeForPackage(getClass());
 52   
       } else {
 53  6
         myPreferences = Preferences.userNodeForPackage(getClass());
 54   
       }
 55   
     }
 56  2985
     return myPreferences;
 57   
   }
 58   
 
 59  3
   protected void resetPrefs() {
 60  3
     getPrefs();
 61  3
     try {
 62  3
       myPreferences.removeNode();
 63   
     } catch (Exception e) {
 64  0
       e.printStackTrace();
 65   
     }
 66  3
     myPreferences = null;
 67  3
     doResetPrefs();
 68   
   }
 69   
 
 70   
   /**
 71   
    * Gets preferences addressed by an either relative or absolute path.
 72   
    *
 73   
    * @param aPath <i>(required)</i>.
 74   
    * @return <i>(required)</i>.
 75   
    */
 76  2982
   protected Preferences getPrefs(String aPath) {
 77  2982
     return getPrefs().node(aPath);
 78   
   }
 79   
 
 80   
   /**
 81   
    * Prints usage information for the {@link #doMain} method on {@link org.jbind.base.Console#err Console.err}.
 82   
    */
 83  0
   protected void usage() {
 84  0
     Console.err("usage:");
 85  0
     Console.err("\tjava " + getClass().getName() + " -export <fileName> -import <fileName> -remove -reset -path [<path>] -setKeyValue <key> <value> -removeKey <key>");
 86  0
     Console.err("\t\texport     : exports the preferences to a file");
 87  0
     Console.err("\t\timport     : imports preferences from a file. Any former preferences are replaced");
 88  0
     Console.err("\t\tremove     : removes the preferences");
 89  0
     Console.err("\t\treset      : resets the preferences");
 90  0
     Console.err("\t\tpath       : sets the current path.");
 91  0
     Console.err("\t\tsetKeyValue: sets a key value pair (at the current path). The value can not contain a space.");
 92  0
     Console.err("\t\tremoveKey  : removes a key value pair (at the current path).");
 93  0
     Console.err("The arguments are processed in the same sequence as they appear on the command line.");
 94   
   }
 95   
 
 96   
   /**
 97   
    * Manages the preferences by applying the arguments supplied in an argument
 98   
    * array. The argument array may contain the following options:
 99   
    * <ul>
 100   
    * <li>-export <fileName></li>
 101   
    * <li>-import <fileName</li>
 102   
    * <li>-remove</li>
 103   
    * <li>-reset</li>
 104   
    * <li>-path [<path>]</li>
 105   
    * <li>-setKeyValue <key> <value></li>
 106   
    * <li>-removeKey <key></li>
 107   
    * <li><i>(any additional arguments that are handled by a derived class)</i></li>
 108   
    * </ul>
 109   
    * The arguments are processed in the same sequence as they appear in the
 110   
    * argument array.
 111   
    *
 112   
    * @param anArgs <i>(required)</i>.
 113   
    */
 114  0
   protected void doMain(String[] anArgs) {
 115  0
     String path = null;
 116  0
     try {
 117  0
       boolean operated = false;
 118  0
       for (int i = 0; i < anArgs.length; i++) {
 119  0
         String a = anArgs[i];
 120  0
         if ("-import".equals(a)) {
 121  0
           if (i + 1 >= anArgs.length) {
 122  0
             Console.err("missing import file name");
 123  0
             usage();
 124  0
             System.exit(-1);
 125   
           }
 126  0
           InputStream is = new BufferedInputStream(new FileInputStream(new File(anArgs[++i])));
 127  0
           Preferences.importPreferences(is);
 128  0
           operated = true;
 129  0
         } else if ("-export".equals(a)) {
 130  0
           if (i + 1 >= anArgs.length) {
 131  0
             Console.err("missing export file name");
 132  0
             usage();
 133  0
             System.exit(-1);
 134   
           }
 135  0
           OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(anArgs[++i])));
 136  0
           getPrefs().exportSubtree(os);
 137  0
           operated = true;
 138  0
         } else if ("-setKeyValue".equals(a)) {
 139  0
           if (i + 2 >= anArgs.length) {
 140  0
             Console.err("missing parameters for setKeyValue");
 141  0
             usage();
 142  0
             System.exit(-1);
 143   
           }
 144  0
           if (null == path) {
 145  0
             getPrefs(anArgs[++i]).put(anArgs[++i], anArgs[++i]);
 146   
           } else {
 147  0
             getPrefs(path).put(anArgs[++i], anArgs[++i]);
 148   
           }
 149  0
           operated = true;
 150  0
         } else if ("-removeKey".equals(a)) {
 151  0
           if (i + 1 >= anArgs.length) {
 152  0
             Console.err("missing parameters for removeKey");
 153  0
             usage();
 154  0
             System.exit(-1);
 155   
           }
 156  0
           if (null == path) {
 157  0
             getPrefs().remove(anArgs[++i]);
 158   
           } else {
 159  0
             getPrefs(path).remove(anArgs[++i]);
 160   
           }
 161  0
           operated = true;
 162  0
         } else if ("-remove".equals(a)) {
 163  0
           getPrefs().removeNode();
 164  0
           myPreferences = null;
 165  0
           operated = true;
 166  0
         } else if ("-path".equals(a)) {
 167  0
           if ((i + 1 < anArgs.length) && !anArgs[i + 1].startsWith("-")) {
 168  0
             path = anArgs[++i];
 169   
           } else {
 170  0
             path = null;
 171   
           }
 172  0
           operated = true;
 173  0
         } else if ("-reset".equals(a)) {
 174  0
           resetPrefs();
 175  0
           operated = true;
 176   
         } else {
 177  0
           int tmp = doAcceptArgument(anArgs, i);
 178  0
           if (tmp < 0) {
 179  0
             Console.err("unknown option: " + a);
 180  0
             usage();
 181  0
             System.exit(-1);
 182   
           } else {
 183  0
             i = tmp;
 184   
           }
 185   
         }
 186   
       }
 187  0
       if (!operated) {
 188  0
         Console.err("missing option(s)");
 189  0
         usage();
 190  0
         System.exit(-1);
 191   
       }
 192   
     } catch (Exception e) {
 193  0
       e.printStackTrace();
 194  0
       System.exit(-1);
 195   
     }
 196   
   }
 197   
 
 198   
   /**
 199   
    * Hook method that is called if the &quot;reset&quot; option is handled.
 200   
    * Before the hook method is called the current preferences are removed and new
 201   
    * preferences will be created on demand.
 202   
    * <p>
 203   
    * Subclasses should implement this method by setting default values for the
 204   
    * various preferences. This enables one to first reset the preferences and
 205   
    * then to export them. The exported preferences should contain enough structural
 206   
    * information to allow manual editing, i.e. ideally all possible preference
 207   
    * keys with default values are present.
 208   
    * <p>
 209   
    * The default implementation does nothing.
 210   
    */
 211  0
   protected void doResetPrefs() {}
 212   
 
 213   
   /**
 214   
    * Hook method to accept an argument. This hook method is called if an argument
 215   
    * is not known to the base class.
 216   
    * <p>
 217   
    * The default implementation returns -1, indicating that it can not handle the
 218   
    * argument.
 219   
    *
 220   
    * @param anArgs <i>(required)</i>. The argument array that was supplied
 221   
    * to the {@link #doMain} method.
 222   
    * @param anIndex The index of the argument in the argument array that has to
 223   
    * be accept.
 224   
    * @return The new index. A negative value indicates that the hook method
 225   
    * could not handle the argument. If the hook method can handle the argument
 226   
    * then it returns the index of the last argument in the argument array that
 227   
    * was processed by the call. For example if the hook method accepts an
 228   
    * argument with no additional parameters then the supplied index paramter
 229   
    * &quot;anIndex&quot; is returned. If the hook method handled the argument
 230   
    * with an additional parameter then the returned index is one more than the
 231   
    * supplied index.
 232   
    */
 233  0
   protected int doAcceptArgument(String[] anArgs, int anIndex) {
 234  0
     return -1;
 235   
   }
 236   
 }
 237