package gnu.java.util.prefs;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.StringTokenizer;
import java.util.prefs.*;
public class NodeWriter {
private final Preferences prefs;
private final BufferedWriter bw;
private boolean subtree;
public NodeWriter(Preferences prefs, Writer w) {
this.prefs = prefs;
if (w instanceof BufferedWriter) {
this.bw = (BufferedWriter) w;
} else {
this.bw = new BufferedWriter(w);
}
}
public NodeWriter(Preferences prefs, OutputStream os) {
this(prefs, new OutputStreamWriter(os));
}
public void writePrefsTree() throws BackingStoreException, IOException {
subtree = true;
writeHeader();
writePreferences();
bw.flush();
}
public void writePrefs() throws BackingStoreException, IOException {
subtree = false;
writeHeader();
writePreferences();
bw.flush();
}
private void writeHeader() throws BackingStoreException, IOException {
bw.write("<?xml version=\"1.0\"?>");
bw.newLine();
bw.newLine();
bw.write("<!-- GNU Classpath java.util.prefs Preferences ");
if (prefs.isUserNode()) {
bw.write("user");
} else {
bw.write("system");
}
if (prefs.parent() == null) {
bw.write(" root");
}
if (subtree) {
bw.write(" tree");
} else {
bw.write(" node");
}
if (prefs.parent() != null) {
bw.newLine();
bw.write(" '");
bw.write(prefs.absolutePath());
bw.write('\'');
bw.newLine();
}
bw.write(" -->");
bw.newLine();
bw.newLine();
}
private void writePreferences() throws BackingStoreException, IOException {
bw.write("<preferences>");
bw.newLine();
writeRoot();
bw.write("</preferences>");
bw.newLine();
}
private void writeRoot() throws BackingStoreException, IOException {
bw.write(" <root type=\"");
if (prefs.isUserNode()) {
bw.write("user");
} else {
bw.write("system");
}
bw.write("\"/>");
writeRootMap();
writeNode();
bw.write(" </root>");
bw.newLine();
}
private void writeRootMap() throws BackingStoreException, IOException {
if(prefs.parent() == null && prefs.keys().length > 0) {
bw.newLine();
writeMap(prefs, 2);
} else {
bw.write("<map/>");
bw.newLine();
}
}
private int writeParents() throws IOException {
int parents;
String path = prefs.absolutePath();
int lastslash = path.lastIndexOf("/");
if (lastslash > 0) {
path = path.substring(1, lastslash);
StringTokenizer st = new StringTokenizer(path);
parents = st.countTokens();
System.out.println("path: " + path);
System.out.println("parents: " + parents);
for (int i=0; i<parents; i++) {
String name = st.nextToken();
indent(i+2);
bw.write("<node name=\"" + name + "\">");
bw.write("<map/>");
bw.write("</node>");
bw.newLine();
}
} else {
parents = 0;
}
return parents;
}
private void writeCloseParents(int parents) throws IOException {
while(parents > 0) {
indent(parents+1);
bw.write("</node>");
bw.newLine();
parents--;
}
}
private void writeNode() throws BackingStoreException, IOException {
int parents = writeParents();
int indent;
if (prefs.parent() == null) {
indent = parents+1;
} else {
indent = parents+2;
}
writeNode(prefs, indent);
writeCloseParents(parents);
}
private void writeNode(Preferences node, int indent)
throws BackingStoreException, IOException
{
if (node.parent() != null) {
indent(indent);
bw.write("<node name=\"" + node.name() + "\">");
if (node.keys().length > 0) {
bw.newLine();
}
writeMap(node, indent+1);
}
if (subtree) {
String[] children = node.childrenNames();
for (int i=0; i<children.length; i++) {
Preferences child = node.node(children[i]);
writeNode(child, indent+1);
}
}
if (node.parent() != null) {
indent(indent);
bw.write("</node>");
bw.newLine();
}
}
private void writeMap(Preferences node, int indent)
throws BackingStoreException, IOException
{
StringBuffer indentBuffer = new StringBuffer(2*indent);
for (int i=0; i < indent; i++)
indentBuffer.append(" ");
String indentString = indentBuffer.toString();
if (node.keys().length > 0) {
bw.write(indentString);
bw.write("<map>");
bw.newLine();
writeEntries(node, indentString + " ");
bw.write(indentString);
bw.write("</map>");
} else {
bw.write("<map/>");
}
bw.newLine();
}
private void writeEntries(Preferences node, String indent)
throws BackingStoreException, IOException
{
String[] keys = node.keys();
for(int i = 0; i < keys.length; i++) {
String value = node.get(keys[i], null);
if (value == null) {
throw new BackingStoreException("null value for key '"
+ keys[i] + "'");
}
bw.write(indent);
bw.write("<entry key=\"" + keys[i] + "\""
+ " value=\"" + value + "\"/>");
bw.newLine();
}
}
private void indent(int x) throws IOException {
for (int i=0; i<x; i++) {
bw.write(" ");
}
}
}