KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > util > VariableBundle


1 package net.suberic.util;
2 import java.util.*;
3 import java.io.*;
4
5 /**
6  * VariableBundle is a combination of a Properties object, a ResourceBundle
7  * object, and (optionally) a second Properties object to act as the 'parent'
8  * properties. This allows both for a single point of reference for
9  * variables, as well as the ability to do hierarchical lookups with the
10  * parent (see getProperty() for an example).
11  *
12  * The order of lookup is as follows: Local properties are checked first,
13  * then parent properties, and then finally (if the value is not found in
14  * any properties) the ResourceBundle is checked.
15  */

16
17 public class VariableBundle extends Object JavaDoc {
18   private Properties properties;
19   private Properties writableProperties;
20   private Properties temporaryProperties = new Properties();
21   private ResourceBundle resources;
22   private VariableBundle parentProperties;
23   private File mSaveFile;
24   private Set removeSet = new HashSet();
25   private Hashtable VCListeners = new Hashtable();
26   private Hashtable VCGlobListeners = new Hashtable();
27
28   public VariableBundle(InputStream propertiesFile, String JavaDoc resourceFile, VariableBundle newParentProperties) {
29     configure(propertiesFile, resourceFile, newParentProperties);
30   }
31
32   public VariableBundle(File propertiesFile, VariableBundle newParentProperties) throws java.io.FileNotFoundException JavaDoc {
33     FileInputStream fis = new FileInputStream(propertiesFile);
34     configure(fis, null, newParentProperties);
35     try {
36       fis.close();
37     } catch (java.io.IOException JavaDoc ioe) {
38     }
39     mSaveFile = propertiesFile;
40
41   }
42
43   public VariableBundle(InputStream propertiesFile, String JavaDoc resourceFile) {
44     this(propertiesFile, resourceFile, null);
45   }
46
47   public VariableBundle(InputStream propertiesFile, VariableBundle newParentProperties) {
48     this(propertiesFile, null, newParentProperties);
49   }
50
51   public VariableBundle(Properties editableProperties, VariableBundle newParentProperties) {
52     writableProperties = editableProperties;
53     parentProperties = newParentProperties;
54     properties = new Properties();
55     resources = null;
56   }
57
58   /**
59    * Configures the VariableBundle.
60    */

61   protected void configure(InputStream propertiesFile, String JavaDoc resourceFile, VariableBundle newParentProperties) {
62
63     writableProperties = new Properties();
64
65     if (resourceFile != null)
66       try {
67         resources = ResourceBundle.getBundle(resourceFile, Locale.getDefault());
68       } catch (MissingResourceException mre) {
69         System.err.println("Error loading resource " + mre.getClassName() + mre.getKey() + ": trying default locale.");
70         try {
71           resources = ResourceBundle.getBundle(resourceFile, Locale.US);
72         } catch (MissingResourceException mreTwo){
73           System.err.println("Unable to load default (US) resource bundle; exiting.");
74           System.exit(1);
75         }
76       }
77     else
78       resources=null;
79
80     properties = new Properties();
81
82     if (propertiesFile != null)
83       try {
84         properties.load(propertiesFile);
85       } catch (java.io.IOException JavaDoc ioe) {
86         System.err.println(ioe.getMessage() + ": " + propertiesFile);
87       }
88
89     List includeStreams = getPropertyAsList("VariableBundle.include", "");
90     if (includeStreams != null && includeStreams.size() > 0) {
91       for (int i = 0; i < includeStreams.size(); i++) {
92         String JavaDoc current = (String JavaDoc) includeStreams.get(i);
93         try {
94           if (current != null && ! current.equals("")) {
95             java.net.URL JavaDoc url = this.getClass().getResource(current);
96
97             java.io.InputStream JavaDoc is = url.openStream();
98
99             properties.load(is);
100           }
101         } catch (java.io.IOException JavaDoc ioe) {
102           System.err.println("error including file " + current + ": " + ioe.getMessage());
103           ioe.printStackTrace();
104         }
105       }
106     }
107
108     parentProperties = newParentProperties;
109
110
111   }
112
113   public String JavaDoc getProperty(String JavaDoc key, String JavaDoc defaultValue) {
114     String JavaDoc returnValue = "";
115
116     if (! propertyIsRemoved(key)) {
117       returnValue = temporaryProperties.getProperty(key, "");
118     }
119     if (returnValue == "") {
120       if (! propertyIsRemoved(key)) {
121         returnValue = writableProperties.getProperty(key, "");
122       }
123       if (returnValue == "") {
124         if (! propertyIsRemoved(key)) {
125           returnValue = properties.getProperty(key, "");
126         }
127         if (returnValue == "") {
128           returnValue=getParentProperty(key, "");
129           if (returnValue == "") {
130             if (resources != null)
131               try {
132                 returnValue = resources.getString(key);
133               } catch (MissingResourceException mre) {
134                 returnValue=defaultValue;
135               }
136             else
137               returnValue = defaultValue;
138           }
139         }
140       }
141     }
142     return returnValue;
143   }
144
145   public String JavaDoc getProperty(String JavaDoc key) throws MissingResourceException {
146     String JavaDoc returnValue;
147
148     returnValue = getProperty(key, "");
149     if (returnValue == "") {
150       throw new MissingResourceException(key, "", key);
151     }
152     return returnValue;
153   }
154
155
156
157   private String JavaDoc getParentProperty(String JavaDoc key, String JavaDoc defaultValue) {
158     if (parentProperties==null) {
159       return defaultValue;
160     } else {
161       return parentProperties.getProperty(key, defaultValue);
162     }
163   }
164
165
166   public ResourceBundle getResources() {
167     return resources;
168   }
169
170   public void setResourceBundle (ResourceBundle newResources) {
171     resources = newResources;
172   }
173
174   public Properties getProperties() {
175     return properties;
176   }
177
178   /**
179    * Sets the Properties object for this VariableBundle.
180    */

181   public void setProperties(Properties newProperties) {
182     properties = newProperties;
183   }
184
185   public VariableBundle getParentProperties() {
186     return parentProperties;
187   }
188
189   public Properties getWritableProperties() {
190     return writableProperties;
191   }
192
193   public void setProperty(String JavaDoc propertyName, String JavaDoc propertyValue) {
194     internSetProperty(propertyName, propertyValue, true);
195   }
196
197   /**
198    * Sets a group of properties at once, not firing any valueChanged events
199    * until all properties are set.
200    */

201   public void setAllProperties(Properties properties) {
202     for (String JavaDoc propertyName: properties.stringPropertyNames()) {
203       String JavaDoc propertyValue = properties.getProperty(propertyName);
204       internSetProperty(propertyName, propertyValue, false);
205     }
206     for (String JavaDoc propertyName: properties.stringPropertyNames()) {
207       fireValueChanged(propertyName);
208     }
209   }
210
211   private void internSetProperty(String JavaDoc propertyName, String JavaDoc propertyValue, boolean notify) {
212
213     temporaryProperties.remove(propertyName);
214     if (propertyValue == null || propertyValue.equalsIgnoreCase("")) {
215       removeProperty(propertyName);
216       writableProperties.remove(propertyName);
217     } else {
218       unRemoveProperty(propertyName);
219       writableProperties.setProperty(propertyName, propertyValue);
220     }
221     if (notify) {
222       fireValueChanged(propertyName);
223     }
224   }
225
226   /**
227    * sets a property as temporary (so it won't be saved).
228    */

229   public void setProperty(String JavaDoc propertyName, String JavaDoc propertyValue, boolean temporary) {
230     if (temporary) {
231       temporaryProperties.setProperty(propertyName, propertyValue);
232       fireValueChanged(propertyName);
233     } else {
234       setProperty(propertyName, propertyValue);
235     }
236   }
237
238   /**
239    * Returns a property which has multiple values separated by a ':' (colon)
240    * as a java.util.Enumeration.
241    */

242
243   public Enumeration getPropertyAsEnumeration(String JavaDoc propertyName, String JavaDoc defaultValue) {
244     StringTokenizer tokens = new StringTokenizer(getProperty(propertyName, defaultValue), ":");
245     return tokens;
246   }
247
248   /**
249    * Converts a value which has multiple values separated by a ':' (colon)
250    * to a java.util.Vector.
251    */

252   public static Vector<String JavaDoc> convertToVector(String JavaDoc value) {
253     Vector<String JavaDoc> returnValue = new Vector<String JavaDoc>();
254     StringTokenizer tokens = new StringTokenizer(value, ":");
255     while (tokens.hasMoreElements())
256       returnValue.add((String JavaDoc)tokens.nextElement());
257     return returnValue;
258   }
259
260   /**
261    * Converts the given property value to a Vector using the convertToVector
262    * call.
263    */

264   public Vector<String JavaDoc> getPropertyAsVector(String JavaDoc propertyName, String JavaDoc defaultValue) {
265     return convertToVector(getProperty(propertyName, defaultValue));
266   }
267
268   /**
269    * Converts a value which has multiple values separated by a ':' (colon)
270    * to a java.util.List.
271    */

272   public static List<String JavaDoc> convertToList(String JavaDoc value) {
273     List<String JavaDoc> returnValue = new ArrayList<String JavaDoc>();
274     StringTokenizer tokens = new StringTokenizer(value, ":");
275     while (tokens.hasMoreElements())
276       returnValue.add((String JavaDoc)tokens.nextElement());
277     return returnValue;
278   }
279
280   /**
281    * Converts the given property value to a List using the convertToList
282    * call.
283    */

284   public List<String JavaDoc> getPropertyAsList(String JavaDoc propertyName, String JavaDoc defaultValue) {
285     return convertToList(getProperty(propertyName, defaultValue));
286   }
287
288   /**
289    * Converts a List of Strings to a colon-delimited String.
290    */

291   public static String JavaDoc convertToString(List pValue) {
292     if (pValue == null || pValue.size() == 0)
293       return "";
294     else {
295       StringBuffer JavaDoc returnBuffer = new StringBuffer JavaDoc();
296       Iterator it = pValue.iterator();
297       while (it.hasNext()) {
298         returnBuffer.append((String JavaDoc) it.next());
299         if (it.hasNext()) {
300           returnBuffer.append(":");
301         }
302       }
303
304       return returnBuffer.toString();
305     }
306   }
307
308   /**
309    * Returns all property keys in this VariableBundle.
310    */

311   public Set<String JavaDoc> getPropertyNames() {
312     HashSet<String JavaDoc> returnValue = new HashSet<String JavaDoc>();
313     returnValue.addAll(temporaryProperties.stringPropertyNames());
314     returnValue.addAll(writableProperties.stringPropertyNames());
315     returnValue.addAll(properties.stringPropertyNames());
316     if (parentProperties != null)
317       returnValue.addAll(parentProperties.getPropertyNames());
318     if (resources != null)
319       returnValue.addAll(resources.keySet());
320
321     return returnValue;
322   }
323
324   /**
325    * Returns all property keys in this VariableBundle that start with
326    * the given string.
327    */

328   public Set<String JavaDoc> getPropertyNamesStartingWith(String JavaDoc startsWith) {
329     Set<String JavaDoc> returnValue = new HashSet<String JavaDoc>();
330     Set<String JavaDoc> allProps = getPropertyNames();
331     for (String JavaDoc prop: allProps) {
332       if (prop.startsWith(startsWith))
333         returnValue.add(prop);
334     }
335
336     return returnValue;
337   }
338
339   /**
340    * Saves the current properties in the VariableBundle to a file. Note
341    * that this only saves the writableProperties of this particular
342    * VariableBundle--underlying defaults are not written.
343    */

344   public void saveProperties() {
345     if (mSaveFile != null) {
346       saveProperties(mSaveFile);
347     }
348   }
349
350   /**
351    * Saves the current properties in the VariableBundle to a file. Note
352    * that this only saves the writableProperties of this particular
353    * VariableBundle--underlying defaults are not written.
354    */

355   public void saveProperties(File pSaveFile) {
356     if (pSaveFile == null)
357       return;
358
359     synchronized(this) {
360       if (writableProperties.size() > 0) {
361         File outputFile;
362         String JavaDoc currentLine, key;
363         int equalsLoc;
364
365         try {
366           if (! pSaveFile.exists())
367             pSaveFile.createNewFile();
368
369           outputFile = pSaveFile.createTempFile(pSaveFile.getName(), ".tmp", pSaveFile.getParentFile());
370
371           BufferedReader readSaveFile = new BufferedReader(new FileReader(pSaveFile));
372           BufferedWriter writeSaveFile = new BufferedWriter(new FileWriter(outputFile));
373           currentLine = readSaveFile.readLine();
374           while (currentLine != null) {
375             equalsLoc = currentLine.indexOf('=');
376             if (equalsLoc != -1) {
377               String JavaDoc rawKey = currentLine.substring(0, equalsLoc);
378               key = unEscapeString(rawKey);
379
380               if (!propertyIsRemoved(key)) {
381                 if (writableProperties.getProperty(key, "").equals("")) {
382
383                   writeSaveFile.write(currentLine);
384                   writeSaveFile.newLine();
385
386                 } else {
387                   writeSaveFile.write(rawKey + "=" + escapeWhiteSpace(writableProperties.getProperty(key, "")));
388                   writeSaveFile.newLine();
389                   properties.setProperty(key, writableProperties.getProperty(key, ""));
390                   writableProperties.remove(key);
391                 }
392               } else {
393                 properties.remove(key);
394               }
395             } else {
396               writeSaveFile.write(currentLine);
397               writeSaveFile.newLine();
398             }
399             currentLine = readSaveFile.readLine();
400           }
401
402           // write out the rest of the writableProperties
403

404           Set<String JavaDoc> propsLeft = writableProperties.stringPropertyNames();
405           List<String JavaDoc> propsLeftList = new ArrayList<String JavaDoc>(propsLeft);
406           Collections.sort(propsLeftList);
407           for (String JavaDoc nextKey: propsLeftList) {
408             String JavaDoc nextKeyEscaped = escapeWhiteSpace(nextKey);
409             String JavaDoc nextValueEscaped = escapeWhiteSpace(writableProperties.getProperty(nextKey, ""));
410             writeSaveFile.write(nextKeyEscaped + "=" + nextValueEscaped);
411             writeSaveFile.newLine();
412
413             properties.setProperty(nextKey, writableProperties.getProperty(nextKey, ""));
414             writableProperties.remove(nextKey);
415           }
416
417           clearRemoveList();
418
419           readSaveFile.close();
420           writeSaveFile.flush();
421           writeSaveFile.close();
422
423           // if you don't delete the .old file first, then the
424
// rename fails under Windows.
425
String JavaDoc oldSaveName = pSaveFile.getAbsolutePath() + ".old";
426           File oldSave = new File (oldSaveName);
427           if (oldSave.exists())
428             oldSave.delete();
429
430           String JavaDoc fileName = new String JavaDoc(pSaveFile.getAbsolutePath());
431           pSaveFile.renameTo(oldSave);
432           outputFile.renameTo(new File(fileName));
433
434         } catch (Exception JavaDoc e) {
435           System.out.println(getProperty("VariableBundle.saveError", "Error saving properties file: " + pSaveFile.getName() + ": " + e.getMessage()));
436           e.printStackTrace(System.err);
437         }
438       }
439     }
440   }
441
442   /*
443    * Converts encoded &#92;uxxxx to unicode chars
444    * and changes special saved chars to their original forms
445    *
446    * ripped directly from java.util.Properties; hope they don't mind.
447    */

448   private String JavaDoc loadConvert (String JavaDoc theString) {
449     char aChar;
450     int len = theString.length();
451     StringBuffer JavaDoc outBuffer = new StringBuffer JavaDoc(len);
452
453     for(int x=0; x<len; ) {
454       aChar = theString.charAt(x++);
455       if (aChar == '\\') {
456         aChar = theString.charAt(x++);
457         if(aChar == 'u') {
458           // Read the xxxx
459
int value=0;
460           for (int i=0; i<4; i++) {
461             aChar = theString.charAt(x++);
462             switch (aChar) {
463             case '0': case '1': case '2': case '3': case '4':
464             case '5': case '6': case '7': case '8': case '9':
465               value = (value << 4) + aChar - '0';
466               break;
467             case 'a': case 'b': case 'c':
468             case 'd': case 'e': case 'f':
469               value = (value << 4) + 10 + aChar - 'a';
470               break;
471             case 'A': case 'B': case 'C':
472             case 'D': case 'E': case 'F':
473               value = (value << 4) + 10 + aChar - 'A';
474               break;
475             default:
476               throw new IllegalArgumentException JavaDoc(
477                                                  "Malformed \\uxxxx encoding.");
478             }
479           }
480           outBuffer.append((char)value);
481         } else {
482           if (aChar == 't') aChar = '\t';
483           else if (aChar == 'r') aChar = '\r';
484           else if (aChar == 'n') aChar = '\n';
485           else if (aChar == 'f') aChar = '\f';
486           outBuffer.append(aChar);
487         }
488       } else
489         outBuffer.append(aChar);
490     }
491     return outBuffer.toString();
492   }
493
494   /*
495    * Converts unicodes to encoded &#92;uxxxx
496    * and writes out any of the characters in specialSaveChars
497    * with a preceding slash
498    *
499    * ripped directly from java.util.Properties; hope they don't mind.
500    */

501   private String JavaDoc saveConvert(String JavaDoc theString, boolean escapeSpace) {
502     int len = theString.length();
503     StringBuffer JavaDoc outBuffer = new StringBuffer JavaDoc(len*2);
504
505     for(int x=0; x<len; x++) {
506       char aChar = theString.charAt(x);
507       switch(aChar) {
508       case ' ':
509         if (x == 0 || escapeSpace)
510           outBuffer.append('\\');
511
512         outBuffer.append(' ');
513         break;
514       case '\\':outBuffer.append('\\'); outBuffer.append('\\');
515         break;
516       case '\t':outBuffer.append('\\'); outBuffer.append('t');
517         break;
518       case '\n':outBuffer.append('\\'); outBuffer.append('n');
519         break;
520       case '\r':outBuffer.append('\\'); outBuffer.append('r');
521         break;
522       case '\f':outBuffer.append('\\'); outBuffer.append('f');
523         break;
524       default:
525         if ((aChar < 0x0020) || (aChar > 0x007e)) {
526           outBuffer.append('\\');
527           outBuffer.append('u');
528           outBuffer.append(toHex((aChar >> 12) & 0xF));
529           outBuffer.append(toHex((aChar >> 8) & 0xF));
530           outBuffer.append(toHex((aChar >> 4) & 0xF));
531           outBuffer.append(toHex( aChar & 0xF));
532         } else {
533           if (specialSaveChars.indexOf(aChar) != -1)
534             outBuffer.append('\\');
535           outBuffer.append(aChar);
536         }
537       }
538     }
539     return outBuffer.toString();
540   }
541
542   /**
543    * Escapes whitespace in a string by putting a '\' in front of each
544    * whitespace character.
545    */

546   public String JavaDoc escapeWhiteSpace(String JavaDoc sourceString) {
547     /*
548       char[] origString = sourceString.toCharArray();
549       StringBuffer returnString = new StringBuffer();
550       for (int i = 0; i < origString.length; i++) {
551       char currentChar = origString[i];
552       if (Character.isWhitespace(currentChar) || '\\' == currentChar)
553       returnString.append('\\');
554
555       returnString.append(currentChar);
556       }
557
558       return returnString.toString();
559     */

560     return saveConvert(sourceString, true);
561   }
562
563   /**
564    * resolves a whitespace-escaped string.
565    */

566   public String JavaDoc unEscapeString(String JavaDoc sourceString) {
567     return loadConvert(sourceString);
568   }
569
570   /**
571    * Clears the removeList. This should generally be called after
572    * you do a writeProperties();
573    */

574   public void clearRemoveList() {
575     removeSet.clear();
576   }
577
578   /**
579    * This removes the property from the current VariableBundle.
580    */

581   private void removeProperty(String JavaDoc remProp) {
582     if (remProp != null) {
583       removeSet.add(remProp.intern());
584     }
585   }
586
587   /**
588    * Removes a property from the removeList. Only necessary if a property
589    * had been removed since the last save, and now has been set to a new
590    * value. It's probably a good idea, though, to call this method any
591    * time a property has its value set.
592    */

593   private void unRemoveProperty(String JavaDoc unRemProp) {
594     if (unRemProp != null) {
595       removeSet.remove(unRemProp.intern());
596     }
597   }
598
599   /**
600    * Returns true if the property has been removed.
601    */

602   public boolean propertyIsRemoved(String JavaDoc prop) {
603     if (prop != null) {
604       return removeSet.contains(prop.intern());
605     }
606     return false;
607   }
608
609   /**
610    * This notifies all registered listeners for changedValue that its
611    * value has changed.
612    */

613   public void fireValueChanged(String JavaDoc changedValue) {
614     // only notify each listener once.
615
Set notified = new HashSet();
616
617     Vector listeners = (Vector)VCListeners.get(changedValue);
618     if (listeners != null) {
619       Iterator iter = listeners.iterator();
620       while (iter.hasNext()) {
621         ValueChangeListener vcl = (ValueChangeListener) iter.next();
622         vcl.valueChanged(changedValue);
623         notified.add(vcl);
624       }
625     }
626
627     // now add the glob listeners.
628

629     Enumeration keys = VCGlobListeners.keys();
630     while (keys.hasMoreElements()) {
631       String JavaDoc currentPattern = (String JavaDoc) keys.nextElement();
632       if (changedValue.startsWith(currentPattern)) {
633         Vector globListeners = (Vector) VCGlobListeners.get(currentPattern);
634         if (globListeners != null && globListeners.size() > 0) {
635           for (int i = 0; i < globListeners.size(); i++) {
636             ValueChangeListener currentListener = ((ValueChangeListener)globListeners.elementAt(i));
637             if (!notified.contains(currentListener)) {
638               currentListener.valueChanged(changedValue);
639               notified.add(currentListener);
640             }
641           }
642         }
643       }
644     }
645
646   }
647
648   /**
649    * This adds the ValueChangeListener to listen for changes in the
650    * given property.
651    */

652   public void addValueChangeListener(ValueChangeListener vcl, String JavaDoc property) {
653     if (property.endsWith("*")) {
654       String JavaDoc startProperty = property.substring(0, property.length() - 1);
655       Vector listeners = (Vector)VCGlobListeners.get(startProperty);
656       if (listeners == null) {
657         listeners = new Vector();
658         listeners.add(vcl);
659         VCGlobListeners.put(startProperty, listeners);
660       } else {
661         if (!listeners.contains(vcl))
662           listeners.add(vcl);
663       }
664
665     } else {
666       Vector listeners = (Vector)VCListeners.get(property);
667       if (listeners == null) {
668         listeners = new Vector();
669         listeners.add(vcl);
670         VCListeners.put(property, listeners);
671       } else {
672         if (!listeners.contains(vcl))
673           listeners.add(vcl);
674       }
675     }
676   }
677
678   /**
679    * This removes the given ValueChangeListener for all the values that
680    * it's listening to.
681    */

682   public void removeValueChangeListener(ValueChangeListener vcl) {
683     Enumeration keys = VCListeners.keys();
684     Vector currentListenerList;
685     while (keys.hasMoreElements()) {
686       currentListenerList = (Vector)VCListeners.get(keys.nextElement());
687       while (currentListenerList != null && currentListenerList.contains(vcl))
688         currentListenerList.remove(vcl);
689     }
690
691     keys = VCGlobListeners.keys();
692     while (keys.hasMoreElements()) {
693       currentListenerList = (Vector)VCGlobListeners.get(keys.nextElement());
694       while (currentListenerList != null && currentListenerList.contains(vcl))
695         currentListenerList.remove(vcl);
696     }
697   }
698
699   /**
700    * This removes the given ValueChangeListener from listening on the
701    * given property.
702    */

703   public void removeValueChangeListener(ValueChangeListener vcl, String JavaDoc property) {
704     Vector currentListenerList;
705     currentListenerList = (Vector)VCListeners.get(property);
706     while (currentListenerList != null && currentListenerList.contains(vcl))
707       currentListenerList.remove(vcl);
708
709     currentListenerList = (Vector)VCGlobListeners.get(property);
710     while (currentListenerList != null && currentListenerList.contains(vcl))
711       currentListenerList.remove(vcl);
712   }
713
714   /**
715    * Returns all of the ValueChangeListeners registered.
716    */

717   public Map getAllListeners() {
718     HashMap returnValue = new HashMap(VCListeners);
719     returnValue.putAll(VCGlobListeners);
720     return returnValue;
721   }
722
723   /**
724    * Returns a formatted message using the given key and the appropriate
725    * objects. If no message corresponding to the given key exists, uses
726    * the key string as the pattern instead.
727    */

728   public String JavaDoc formatMessage(String JavaDoc key, Object JavaDoc... arguments) {
729     String JavaDoc pattern = getProperty(key, key);
730     return java.text.MessageFormat.format(pattern, arguments);
731   }
732
733   /**
734    * Convert a nibble to a hex character
735    * @paramnibblethe nibble to convert.
736    */

737   private static char toHex(int nibble) {
738     return hexDigit[(nibble & 0xF)];
739   }
740
741   /** A table of hex digits */
742   private static final char[] hexDigit = {
743     '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
744   };
745
746   //private static final String keyValueSeparators = "=: \t\r\n\f";
747

748   //private static final String strictKeyValueSeparators = "=:";
749

750   private static final String JavaDoc specialSaveChars = "=: \t\r\n\f#!";
751
752   private static final String JavaDoc whiteSpaceChars = " \t\r\n\f";
753
754   /**
755    * Returns the current saveFile.
756    */

757   public File getSaveFile() {
758     return mSaveFile;
759   }
760
761   /**
762    * Sets the save file.
763    */

764   public void setSaveFile(File newFile) {
765     mSaveFile = newFile;
766   }
767 }
768
769
770
Popular Tags