Source for gnu.java.util.prefs.NodeReader

   1: /* NodeReader - Reads and imports preferences nodes from files
   2:    Copyright (C) 2001 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.java.util.prefs;
  39: 
  40: import java.io.BufferedReader;
  41: import java.io.IOException;
  42: import java.io.InputStream;
  43: import java.io.InputStreamReader;
  44: import java.io.Reader;
  45: import java.util.prefs.InvalidPreferencesFormatException;
  46: import java.util.prefs.Preferences;
  47: import java.util.prefs.PreferencesFactory;
  48: 
  49: /**
  50:  * Reads and imports preferences nodes from files.
  51:  *
  52:  * @author Mark Wielaard (mark@klomp.org)
  53:  */
  54: public class NodeReader {
  55: 
  56:     private final BufferedReader br;
  57:     private String line = "";
  58: 
  59:     private final PreferencesFactory factory;
  60: 
  61:     public NodeReader(Reader r, PreferencesFactory factory) {
  62:         if(r instanceof BufferedReader) {
  63:             br = (BufferedReader) r;
  64:         } else {
  65:             br = new BufferedReader(r);
  66:         }
  67:         this.factory = factory;
  68:     }
  69: 
  70:     public NodeReader(InputStream is, PreferencesFactory factory) {
  71:         this(new InputStreamReader(is), factory);
  72:     }
  73: 
  74:     public void importPreferences()
  75:                     throws InvalidPreferencesFormatException, IOException
  76:     {
  77:         readPreferences();
  78:     }
  79: 
  80:     private void readPreferences()
  81:                     throws InvalidPreferencesFormatException, IOException
  82:     {
  83:         // Begin starting tag
  84:         skipTill("<preferences");
  85: 
  86:         readRoot();
  87: 
  88:         // Ending tag
  89:         skipTill("</preferences>");
  90:     }
  91: 
  92:     private void readRoot()
  93:                     throws InvalidPreferencesFormatException, IOException
  94:     {
  95:         // Begin starting tag
  96:         skipTill("<root");
  97: 
  98:         // type attribute
  99:         skipTill("type=\"");
 100:         String type = readTill("\"");
 101:         Preferences root;
 102:         if ("user".equals(type)) {
 103:             root = factory.userRoot();
 104:         } else if ("system".equals(type)) {
 105:             root = factory.systemRoot();
 106:         } else {
 107:             throw new InvalidPreferencesFormatException("Unknown type: "
 108:                                                         + type);
 109:         }
 110: 
 111:         // Read root map and subnodes
 112:         readMap(root);
 113:         readNodes(root);
 114: 
 115:         // Ending tag
 116:         skipTill("</root>");
 117:     }
 118: 
 119:     private void readNodes(Preferences node)
 120:                     throws InvalidPreferencesFormatException, IOException
 121:     {
 122:         while ("node".equals(nextTag())) {
 123:             skipTill("<node");
 124:             skipTill("name=\"");
 125:             String name = readTill("\"");
 126:             Preferences subnode = node.node(name);
 127:             readMap(subnode);
 128:             readNodes(subnode);
 129:             skipTill("</node>");
 130:         }
 131: 
 132:     }
 133: 
 134:     private void readMap(Preferences node)
 135:                     throws InvalidPreferencesFormatException, IOException
 136:     {
 137:         // Begin map tag
 138:         skipTill("<map");
 139: 
 140:         // Empty map?
 141:         if (line.startsWith("/>")) {
 142:             line = line.substring(2);
 143:             return;
 144:         }
 145: 
 146:         // Map entries
 147:         readEntries(node);
 148: 
 149:         // Ending tag
 150:         skipTill("</map>");
 151:     }
 152: 
 153:     private void readEntries(Preferences node)
 154:                     throws InvalidPreferencesFormatException, IOException
 155:     {
 156:         while ("entry".equals(nextTag())) {
 157:             skipTill("<entry");
 158:             skipTill("key=\"");
 159:             String key = readTill("\"");
 160:             skipTill("value=\"");
 161:             String value = readTill("\"");
 162:             node.put(key, value);
 163:         }
 164:     }
 165: 
 166:     private void skipTill(String s)
 167:                     throws InvalidPreferencesFormatException, IOException
 168:     {
 169:         while(true) {
 170:             if (line == null)
 171:                 throw new InvalidPreferencesFormatException(s + " not found");
 172: 
 173:             int index = line.indexOf(s);
 174:             if (index == -1)  {
 175:                 line = br.readLine();
 176:             } else {
 177:                 line = line.substring(index+s.length());
 178:                 return;
 179:             }
 180:         }
 181:     }
 182: 
 183:     private String readTill(String s)
 184:                     throws InvalidPreferencesFormatException
 185:     {
 186:         int index = line.indexOf(s);
 187:         if (index == -1)
 188:                 throw new InvalidPreferencesFormatException(s + " not found");
 189: 
 190:         String read = line.substring(0, index);
 191:         line = line.substring(index+s.length());
 192: 
 193:         return read;
 194:     }
 195: 
 196:     private String nextTag()
 197:                     throws InvalidPreferencesFormatException, IOException
 198:     {
 199:         while(true) {
 200:             if (line == null)
 201:                 throw new InvalidPreferencesFormatException("unexpected EOF");
 202: 
 203:             int start = line.indexOf("<");
 204:             if (start == -1)  {
 205:                 line = br.readLine();
 206:             } else {
 207:                 // Find end of tag
 208:                 int end = start+1;
 209:                 while (end != line.length()
 210:                        && " \t\r\n".indexOf(line.charAt(end)) == -1) {
 211:                     end++;
 212:                 }
 213:                 // Line now starts at the found tag
 214:                 String tag = line.substring(start+1,end);
 215:                 line = line.substring(start);
 216:                 return tag;
 217:             }
 218:         }
 219:     }
 220: 
 221: }