1 package xuml.tools.util.xml;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.text.DecimalFormat;
6 import java.util.Stack;
7
8 public class TaggedOutputStream {
9
10 public String indentString = " ";
11
12 private final Stack<String> stack = new Stack<String>();
13
14 private boolean tagOpen = false;
15
16 private boolean prettyPrint = false;
17
18 private int startIndent = 0;
19
20 private final OutputStream out;
21
22 private boolean lastOperationWasCloseTag = false;
23
24 public TaggedOutputStream(OutputStream out, boolean prettyPrint) {
25
26 this.out = out;
27 this.prettyPrint = prettyPrint;
28 }
29
30 public TaggedOutputStream(OutputStream out, boolean prettyPrint, int startIndent) {
31
32 this.out = out;
33 this.startIndent = startIndent;
34 this.prettyPrint = prettyPrint;
35
36 }
37
38 public TaggedOutputStream startTag(String tag) {
39 closeBracket();
40 if (prettyPrint) {
41 writeString("\n");
42 for (int i = 0; i < stack.size() + this.startIndent; i++)
43 writeString(this.indentString);
44 }
45 writeString("<" + tag);
46 stack.push(tag);
47 tagOpen = true;
48 lastOperationWasCloseTag = false;
49 return this;
50 }
51
52 private void closeBracket() {
53 if (tagOpen) {
54 writeString(">");
55 tagOpen = false;
56 }
57 }
58
59 public TaggedOutputStream addAttribute(String key, String value) {
60
61 writeString(" " + key + "=\"" + value + "\"");
62 return this;
63 }
64
65 public TaggedOutputStream addAttribute(String key, double d) {
66
67 DecimalFormat df = new DecimalFormat("#.0000000");
68 writeString(" " + key + "=\"" + df.format(d) + "\"");
69 return this;
70
71 }
72
73 public void newLine() {
74 writeString("\n");
75 }
76
77 public TaggedOutputStream closeTag() {
78 if (tagOpen) {
79 writeString("/");
80 closeBracket();
81 stack.pop();
82 } else {
83 if (lastOperationWasCloseTag && prettyPrint) {
84
85
86 writeString("\n");
87 for (int i = 0; i < stack.size() - 1 + this.startIndent; i++)
88 writeString(this.indentString);
89 }
90 String tag = stack.pop();
91 writeString("</" + tag + ">");
92 }
93 lastOperationWasCloseTag = true;
94 return this;
95 }
96
97 public TaggedOutputStream close() {
98 if (stack.size() > 0)
99 throw new Error(stack.size() + "unclosed tags!");
100 return this;
101 }
102
103 private void writeString(String str) {
104 if (str != null) {
105 try {
106 out.write(str.getBytes());
107 } catch (IOException e) {
108 throw new Error("IOException occurred: " + e.getMessage());
109 }
110 }
111 }
112
113 public TaggedOutputStream append(String str) {
114 closeBracket();
115 writeString(str);
116 return this;
117 }
118
119 public TaggedOutputStream append(boolean b) {
120 append(((Boolean) b).toString());
121 return this;
122 }
123
124 public TaggedOutputStream append(double d) {
125 DecimalFormat df = new DecimalFormat("#.0000000");
126 append(df.format(d));
127 return this;
128 }
129
130 public TaggedOutputStream append(long d) {
131 append(((Long) d).toString());
132 return this;
133 }
134
135 public OutputStream getOutputStream() {
136 return this.out;
137 }
138
139 public static void main(String[] args) {
140
141 TaggedOutputStreameam.html#TaggedOutputStream">TaggedOutputStream t = new TaggedOutputStream(System.out, true);
142 t.startTag("info");
143 t.startTag("name");
144 t.append("johnno");
145 t.closeTag();
146 t.startTag("type");
147 t.addAttribute("location", "Canberra");
148 t.startTag("size");
149 t.startTag("range");
150 t.append("large");
151 t.startTag("distrubution");
152 t.append("uniform");
153 t.closeTag();
154 t.closeTag();
155 t.closeTag();
156 t.closeTag();
157 t.startTag("size");
158 t.startTag("range");
159 t.append("large");
160 t.startTag("distrubution");
161 t.append("uniform");
162 t.closeTag();
163 t.closeTag();
164 t.closeTag();
165 t.closeTag();
166 }
167
168 }