KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > util > DjProperties


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, is permitted
5  * provided that the following conditions are met:
6  * - Redistributions of source code must retain the above copyright notice, this list of conditions
7  * and the following disclaimer.
8  * - Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * - All advertising materials mentioning features or use of this software must display the
12  * following acknowledgment: "This product includes Djeneric."
13  * - Products derived from this software may not be called "Djeneric" nor may
14  * "Djeneric" appear in their names without prior written permission of Genimen BV.
15  * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
16  * product includes Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.util;
31
32 import java.io.BufferedWriter JavaDoc;
33 import java.io.IOException JavaDoc;
34 import java.io.OutputStream JavaDoc;
35 import java.io.OutputStreamWriter JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.Comparator JavaDoc;
39 import java.util.Date JavaDoc;
40 import java.util.ListIterator JavaDoc;
41 import java.util.Properties JavaDoc;
42
43 /**
44  * GProperties is a specialized java.util.Properties that Sorts the keys before
45  * writing the properties to the output stream.
46  */

47
48 /**
49  * Implements the method that sorts the properties:
50  * Rule: A string with less dots has higher priority
51  * Strings with equal dotcount are sorted using String.compareTo()
52  *
53  * This results in a registry style layout where levels group keys.
54  */

55
56 class KeyComparator implements Comparator JavaDoc
57 {
58   public int compare(Object JavaDoc o1, Object JavaDoc o2)
59   {
60     String JavaDoc s1 = (String JavaDoc) o1;
61     String JavaDoc s2 = (String JavaDoc) o2;
62
63     int dotCount1 = countDots(s1);
64     int dotCount2 = countDots(s2);
65
66     if (dotCount1 == dotCount2) return s1.compareTo(s2);
67
68     return dotCount1 - dotCount2;
69   }
70
71   public static int countDots(String JavaDoc s)
72   {
73     int idx = s.indexOf(".");
74     int count = 0;
75     while (idx >= 0)
76     {
77       count++;
78       idx = s.indexOf(".", idx + 1);
79     }
80     return count;
81   }
82
83   public boolean equals(Object JavaDoc obj)
84   {
85     return obj == this;
86   }
87
88 }
89
90 public class DjProperties extends Properties JavaDoc
91 {
92   private static final long serialVersionUID = 1L;
93
94   private static final String JavaDoc specialSaveChars = "=: \t\r\n\f#!";
95
96   public synchronized void store(OutputStream JavaDoc out, String JavaDoc header) throws IOException JavaDoc
97   {
98     BufferedWriter JavaDoc awriter;
99     awriter = new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(out, "8859_1"));
100     if (header != null) writeln(awriter, "#" + header);
101
102     writeln(awriter, "#" + new Date JavaDoc().toString());
103
104     ArrayList JavaDoc sortedKeys = new ArrayList JavaDoc(size());
105
106     sortedKeys.addAll(this.keySet());
107     Collections.sort(sortedKeys, new KeyComparator());
108
109     String JavaDoc prevGroupKey = "";
110     int prevDotCount = -1;
111     int groupCount = 1;
112     for (ListIterator JavaDoc e = sortedKeys.listIterator(); e.hasNext();)
113     {
114       String JavaDoc key = (String JavaDoc) e.next();
115       String JavaDoc val = (String JavaDoc) get(key);
116       key = saveConvert(key, true);
117
118       String JavaDoc groupKey = key;
119       int dotIdx = key.lastIndexOf(".");
120       boolean endGroup = false;
121       if (dotIdx != -1)
122       {
123         groupKey = key.substring(0, dotIdx);
124         if (groupKey.equals(prevGroupKey)) groupCount++;
125         else if (groupCount > 1) // More than one within group found, and now there is a new group?
126
{
127           endGroup = true;
128         }
129       }
130       else if (groupCount > 1) // More than one within group found, and now there is a new group?
131
{
132         endGroup = true;
133       }
134
135       int dotCount = KeyComparator.countDots(key);
136       if (dotCount != prevDotCount) endGroup = true;
137       prevDotCount = dotCount;
138
139       if (endGroup)
140       {
141         awriter.newLine(); // add an empty line
142
groupCount = 1; // Start counting the new group
143
}
144
145       prevGroupKey = groupKey;
146
147       /* No need to escape embedded and trailing spaces for value, hence
148        * pass false to flag.
149        */

150       val = saveConvert(val, false);
151       writeln(awriter, key + "=" + val);
152     }
153     awriter.flush();
154   }
155
156   private static void writeln(BufferedWriter JavaDoc bw, String JavaDoc s) throws IOException JavaDoc
157   {
158     bw.write(s);
159     bw.newLine();
160   }
161
162   /*
163    * Converts unicodes to encoded \uxxxx
164    * and writes out any of the characters in specialSaveChars
165    * with a preceding slash
166    */

167   private String JavaDoc saveConvert(String JavaDoc theString, boolean escapeSpace)
168   {
169     int len = theString.length();
170     StringBuffer JavaDoc outBuffer = new StringBuffer JavaDoc(len * 2);
171
172     for (int x = 0; x < len; x++)
173     {
174       char aChar = theString.charAt(x);
175       switch (aChar)
176       {
177         case ' ' :
178           if (x == 0 || escapeSpace) outBuffer.append('\\');
179
180           outBuffer.append(' ');
181           break;
182         case '\\' :
183           outBuffer.append('\\');
184           outBuffer.append('\\');
185           break;
186         case '\t' :
187           outBuffer.append('\\');
188           outBuffer.append('t');
189           break;
190         case '\n' :
191           outBuffer.append('\\');
192           outBuffer.append('n');
193           break;
194         case '\r' :
195           outBuffer.append('\\');
196           outBuffer.append('r');
197           break;
198         case '\f' :
199           outBuffer.append('\\');
200           outBuffer.append('f');
201           break;
202         default :
203           if ((aChar < 0x0020) || (aChar > 0x007e))
204           {
205             outBuffer.append('\\');
206             outBuffer.append('u');
207             outBuffer.append(toHex((aChar >> 12) & 0xF));
208             outBuffer.append(toHex((aChar >> 8) & 0xF));
209             outBuffer.append(toHex((aChar >> 4) & 0xF));
210             outBuffer.append(toHex(aChar & 0xF));
211           }
212           else
213           {
214             if (specialSaveChars.indexOf(aChar) != -1) outBuffer.append('\\');
215             outBuffer.append(aChar);
216           }
217       }
218     }
219     return outBuffer.toString();
220   }
221
222   private static char toHex(int nibble)
223   {
224     return hexDigit[(nibble & 0xF)];
225   }
226
227   /** A table of hex digits */
228   private static final char[] hexDigit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
229       'F' };
230
231 }
Popular Tags