1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.beep4j.internal.profile;
17
18 import static net.sf.beep4j.internal.profile.XMLConstants.A_CODE;
19 import static net.sf.beep4j.internal.profile.XMLConstants.A_ENCODING;
20 import static net.sf.beep4j.internal.profile.XMLConstants.A_NUMBER;
21 import static net.sf.beep4j.internal.profile.XMLConstants.A_URI;
22 import static net.sf.beep4j.internal.profile.XMLConstants.ENCODING_BASE64;
23 import static net.sf.beep4j.internal.profile.XMLConstants.E_CLOSE;
24 import static net.sf.beep4j.internal.profile.XMLConstants.E_ERROR;
25 import static net.sf.beep4j.internal.profile.XMLConstants.E_GREETING;
26 import static net.sf.beep4j.internal.profile.XMLConstants.E_OK;
27 import static net.sf.beep4j.internal.profile.XMLConstants.E_PROFILE;
28 import static net.sf.beep4j.internal.profile.XMLConstants.E_START;
29
30 import java.io.PrintWriter;
31 import java.io.Writer;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.LinkedList;
36 import java.util.Map;
37
38 import net.sf.beep4j.Message;
39 import net.sf.beep4j.MessageBuilder;
40 import net.sf.beep4j.ProfileInfo;
41
42 public final class SaxMessageBuilder implements ChannelManagementMessageBuilder {
43
44 public Message createClose(MessageBuilder builder, int channelNumber, int code) {
45 WriterHandler handler = new WriterHandler(builder.getWriter());
46 Map<String,String> attributes = new HashMap<String,String>();
47 attributes.put(A_NUMBER, Integer.toString(channelNumber));
48 attributes.put(A_CODE, Integer.toString(200));
49 handler.startElement(E_CLOSE, attributes);
50 handler.endElement();
51 handler.close();
52 return builder.getMessage();
53 }
54
55 public Message createError(MessageBuilder builder, int code, String message) {
56 WriterHandler handler = new WriterHandler(builder.getWriter());
57 Map<String,String> attributes = new HashMap<String,String>();
58 attributes.put(A_CODE, Integer.toString(code));
59 handler.startElement(E_ERROR, attributes);
60 handler.characters(message);
61 handler.endElement();
62 handler.close();
63 return builder.getMessage();
64 }
65
66 public Message createGreeting(MessageBuilder builder, String[] profiles) {
67 WriterHandler handler = new WriterHandler(builder.getWriter());
68 Map<String,String> attributes = Collections.emptyMap();
69 handler.startElement(E_GREETING, attributes);
70 for (int i = 0; i < profiles.length; i++) {
71 String profile = profiles[i];
72 handler.startElement(E_PROFILE, Collections.singletonMap(A_URI, profile));
73 handler.endElement();
74 }
75 handler.endElement();
76 handler.close();
77 return builder.getMessage();
78 }
79
80 public Message createOk(MessageBuilder builder) {
81 WriterHandler handler = new WriterHandler(builder.getWriter());
82 Map<String,String> attributes = Collections.emptyMap();
83 handler.startElement(E_OK, attributes);
84 handler.endElement();
85 handler.close();
86 return builder.getMessage();
87 }
88
89 public Message createProfile(MessageBuilder builder, ProfileInfo profile) {
90 WriterHandler handler = new WriterHandler(builder.getWriter());
91 handler.startElement(E_PROFILE, Collections.singletonMap(A_URI, profile.getUri()));
92 if (profile.hasContent()) {
93 StringBuilder str = new StringBuilder();
94 profile.appendTo(str);
95 handler.characters(str.toString());
96 }
97 handler.endElement();
98 handler.close();
99 return builder.getMessage();
100 }
101
102 public Message createStart(MessageBuilder builder, int channelNumber,
103 ProfileInfo[] infos) {
104 WriterHandler handler = new WriterHandler(builder.getWriter());
105 handler.startElement(E_START, Collections.singletonMap(A_NUMBER, Integer.toString(channelNumber)));
106 for (int i = 0; i < infos.length; i++) {
107 ProfileInfo info = infos[i];
108 Map<String,String> attributes = new HashMap<String,String>();
109 attributes.put(A_URI, info.getUri());
110 if (info.isBase64Encoded()) {
111 attributes.put(A_ENCODING, ENCODING_BASE64);
112 }
113 handler.startElement(E_PROFILE, attributes);
114 if (info.hasContent()) {
115 StringBuilder appendable = new StringBuilder();
116 info.appendTo(appendable);
117 handler.characters(appendable.toString());
118 }
119 handler.endElement();
120 }
121 handler.endElement();
122 handler.close();
123 return builder.getMessage();
124 }
125
126 private static class WriterHandler implements ElementHandler {
127
128 private final PrintWriter writer;
129
130 private final LinkedList<String> path = new LinkedList<String>();
131
132 private boolean afterStartTag;
133
134 private WriterHandler(Writer writer) {
135 this.writer = new PrintWriter(writer);
136 }
137
138 public void startElement(String name, Map<String, String> attributes) {
139 if (afterStartTag) {
140 writer.write(">");
141 }
142 writer.write("<" + name);
143 Iterator<String> it = attributes.keySet().iterator();
144 while (it.hasNext()) {
145 String attributeName = (String) it.next();
146 writer.write(" " + attributeName);
147 writer.write("=\"" + attributes.get(attributeName) + "\"");
148 }
149 afterStartTag = true;
150 path.addLast(name);
151 }
152
153 public void characters(String content) {
154 if (afterStartTag) {
155 writer.write(">");
156 afterStartTag = false;
157 }
158 writer.write(content);
159 }
160
161 public void endElement() {
162 String top = path.removeLast();
163 if (afterStartTag) {
164 writer.write(" />");
165 } else {
166 writer.write("</" + top + ">");
167 }
168 afterStartTag = false;
169 }
170
171 public void close() {
172 writer.close();
173 }
174
175 }
176
177 }