View Javadoc

1   /*
2    *  Copyright 2006 Simon Raess
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
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 }