OSDN Git Service

* gnu/java/util/prefs/NodeWriter.java (writeParents): Removed
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / util / prefs / NodeWriter.java
1 /* NodeWriter - Writes and exports preferences nodes to files
2    Copyright (C) 2001, 2006 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.BufferedWriter;
41 import java.io.IOException;
42 import java.io.OutputStream;
43 import java.io.OutputStreamWriter;
44 import java.io.UnsupportedEncodingException;
45 import java.io.Writer;
46
47 import java.util.StringTokenizer;
48
49 import java.util.prefs.*;
50
51 /**
52  * Writes and exports preferences nodes to files
53  *
54  * @author Mark Wielaard (mark@klomp.org)
55  */
56 public class NodeWriter {
57
58     /** The Preferences node to write. */
59     private final Preferences prefs;
60
61     /** The bufferedWriter to write the node to. */
62     private final BufferedWriter bw;
63
64     /**
65      * True if the complete sub tree should be written,
66      * false if only the node should be written.
67      */
68     private boolean subtree;
69
70     /**
71      * Creates a new NodeWriter for the given preferences node and
72      * outputstream. Creates a new OutputStreamWriter.
73      */
74     public NodeWriter(Preferences prefs, OutputStream os) {
75         this.prefs = prefs;
76         Writer w;
77         try
78           {
79             w = new OutputStreamWriter(os, "UTF-8");
80           }
81         catch (UnsupportedEncodingException uee)
82           {
83             // Shouldn't happen, since we always have UTF-8 available.
84             InternalError ie = new InternalError("UTF-8 encoding missing");
85             ie.initCause(uee);
86             throw ie;
87           }
88         this.bw = new BufferedWriter(w);
89     }
90
91     /**
92      * Writes the preference node plus the complete subtree.
93      */
94     public void writePrefsTree() throws BackingStoreException, IOException {
95         subtree = true;
96         writeHeader();
97         writePreferences();
98         bw.flush();
99     }
100
101     /**
102      * Writes only the preference node.
103      */
104     public void writePrefs() throws BackingStoreException, IOException {
105         subtree = false;
106         writeHeader();
107         writePreferences();
108         bw.flush();
109     }
110
111     /**
112      * Writes the standard header.
113      */
114     private void writeHeader() throws BackingStoreException, IOException {
115         bw.write("<?xml version=\"1.0\"?>");
116         bw.newLine();
117         bw.write("<!DOCTYPE preferences SYSTEM "
118                  + "\"http://java.sun.com/dtd/preferences.dtd\">");
119         bw.newLine();
120         bw.newLine();
121         bw.write("<!-- GNU Classpath java.util.prefs Preferences ");
122
123         if (prefs.isUserNode()) {
124             bw.write("user");
125         } else {
126             bw.write("system");
127         }
128
129         // root node?
130         if (prefs.parent() == null) {
131             bw.write(" root");
132         }
133
134         if (subtree) {
135             bw.write(" tree");
136         } else {
137             bw.write(" node");
138         }
139
140         // no root?
141         if (prefs.parent() != null) {
142             bw.newLine();
143             bw.write("     '");
144             bw.write(prefs.absolutePath());
145             bw.write('\'');
146             bw.newLine();
147         }
148         bw.write(" -->");
149         bw.newLine();
150         bw.newLine();
151     }
152
153     /**
154      * Write the preferences tag and the root.
155      */
156     private void writePreferences() throws BackingStoreException, IOException {
157         bw.write("<preferences>");
158         bw.newLine();
159         writeRoot();
160         bw.write("</preferences>");
161         bw.newLine();
162     }
163
164     private void writeRoot() throws BackingStoreException, IOException {
165         bw.write("  <root type=\"");
166         if (prefs.isUserNode()) {
167             bw.write("user");
168         } else {
169             bw.write("system");
170         }
171         bw.write("\">");
172
173         writeRootMap();
174         writeNode();
175
176         bw.write("  </root>");
177         bw.newLine();
178     }
179
180     private void writeRootMap() throws BackingStoreException, IOException {
181         // Is it a root node?
182         if(prefs.parent() == null && prefs.keys().length > 0) {
183             bw.newLine();
184             writeMap(prefs, 2);
185         } else {
186             bw.write("<map/>");
187             bw.newLine();
188         }
189     }
190
191     /**
192      * Writes all the parents of the preferences node without any entries.
193      * Returns the number of parents written, which has to be used as
194      * argument to <code>writeCloseParents()</code> after writing the node
195      * itself.
196      */
197     private int writeParents() throws IOException {
198         int parents;
199         String path = prefs.absolutePath();
200         int lastslash = path.lastIndexOf("/");
201         if (lastslash > 0) {
202             path = path.substring(1, lastslash);
203             StringTokenizer st = new StringTokenizer(path);
204             parents = st.countTokens();
205
206             for (int i=0; i<parents; i++) {
207                 String name = st.nextToken();
208                 indent(i+2);
209                 bw.write("<node name=\"" + name + "\">");
210                 bw.write("<map/>");
211                 bw.write("</node>");
212                 bw.newLine();
213             }
214         } else {
215             parents = 0;
216         }
217
218         return parents;
219     }
220
221     private void writeCloseParents(int parents) throws IOException {
222         while(parents > 0) {
223             indent(parents+1);
224             bw.write("</node>");
225             bw.newLine();
226             parents--;
227         }
228     }
229
230     private void writeNode() throws BackingStoreException, IOException {
231         int parents = writeParents();
232         // root?
233         int indent;
234         if (prefs.parent() == null) {
235             indent = parents+1;
236         } else {
237             indent = parents+2;
238         }
239         writeNode(prefs, indent);
240         writeCloseParents(parents);
241     }
242
243     private void writeNode(Preferences node, int indent)
244                                     throws BackingStoreException, IOException
245     {
246         // not root?
247         if (node.parent() != null) {
248             indent(indent);
249             bw.write("<node name=\"" + node.name() + "\">");
250             if (node.keys().length > 0) {
251                 bw.newLine();
252             }
253             writeMap(node, indent+1);
254         }
255
256         if (subtree) {
257             String[] children = node.childrenNames();
258             for (int i=0; i<children.length; i++) {
259                 Preferences child = node.node(children[i]);
260                 writeNode(child, indent+1);
261             }
262         }
263
264         // not root?
265         if (node.parent() != null) {
266             indent(indent);
267             bw.write("</node>");
268             bw.newLine();
269         }
270     }
271
272     private void writeMap(Preferences node, int indent) 
273                                     throws BackingStoreException, IOException
274     {
275         // construct String used for indentation
276         StringBuffer indentBuffer = new StringBuffer(2*indent);
277         for (int i=0; i < indent; i++)
278             indentBuffer.append("  ");
279         String indentString = indentBuffer.toString();
280
281         if (node.keys().length > 0) {
282             bw.write(indentString);
283             bw.write("<map>");
284             bw.newLine();
285             writeEntries(node, indentString + "  ");
286             bw.write(indentString);
287             bw.write("</map>");
288         } else {
289             bw.write("<map/>");
290         }
291         bw.newLine();
292     }
293
294     private void writeEntries(Preferences node, String indent)
295                                     throws BackingStoreException, IOException
296     {
297         String[] keys = node.keys();
298         for(int i = 0; i < keys.length; i++) {
299             String value = node.get(keys[i], null);
300             if (value == null) {
301                 throw new BackingStoreException("null value for key '"
302                                                 + keys[i] + "'");
303             }
304
305             bw.write(indent);
306             bw.write("<entry key=\"" + keys[i] + "\""
307                     + " value=\"" + value + "\"/>");
308             bw.newLine();
309         }
310     }
311
312     private void indent(int x) throws IOException {
313         for (int i=0; i<x; i++) {
314             bw.write("  ");
315         }
316     }
317 }