blob: 44dfb890d476032193ffc02d29e66e7873c185e2 [file] [log] [blame]
Stephane Frenotcb0356f2006-07-20 09:36:47 +00001/*
2 * Copyright (C) MX4J.
3 * All rights reserved.
4 *
5 * This software is distributed under the terms of the MX4J License version 1.0.
6 * See the terms of the MX4J License in the documentation provided with this software.
7 */
8/*
9 * Copyright 2005 The Apache Software Foundation
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *
23 */
24package org.apache.felix.mosgi.jmx.httpconnector.mx4j.tools.adaptor.http;
25
26import java.io.ByteArrayOutputStream;
27import java.io.IOException;
28import java.io.PrintWriter;
29
30import org.w3c.dom.Attr;
31import org.w3c.dom.Document;
32import org.w3c.dom.NamedNodeMap;
33import org.w3c.dom.Node;
34import org.w3c.dom.NodeList;
35
36import org.osgi.framework.ServiceReference;
37import org.osgi.service.log.LogService;
38
39import org.apache.felix.mosgi.jmx.httpconnector.HttpConnectorActivator;
40
41
42/**
43 * DefaultPostProcessor doesn't alter the result, just publising the xml file
44 *
45 * @author <a href="mailto:tibu@users.sourceforge.net">Carlos Quiroz</a>
46 * @version $Revision: 1.1.1.1 $
47 */
48
49public class DefaultProcessor implements ProcessorMBean
50{
51
52 private final static String ENCODING = "UTF-8";
53 private boolean canonical = false;
54 public String getName()
55 {
56 return "Default XML Processor";
57 }
58
59 public void writeResponse(HttpOutputStream out, HttpInputStream in, Document document)
60 throws IOException
61 {
62 out.setCode(HttpConstants.STATUS_OKAY);
63 out.setHeader("Content-Type", "text/xml");
64 out.sendHeaders();
65 print(new PrintWriter(out), document);
66 ByteArrayOutputStream o = new ByteArrayOutputStream();
67 print(new PrintWriter(o), document);
68 DefaultProcessor.log(LogService.LOG_INFO,new String(o.toByteArray()),null);
69 }
70
71 public void writeError(HttpOutputStream out, HttpInputStream in, Exception e)
72 throws IOException
73 {
74 if (e instanceof HttpException)
75 {
76 out.setCode(((HttpException)e).getCode());
77 out.setHeader("Content-Type", "text/xml");
78 out.sendHeaders();
79 print(new PrintWriter(out), ((HttpException)e).getResponseDoc());
80 }
81 }
82
83 public String preProcess(String path)
84 {
85 // The only special case. The root is routed to the the server request
86 if (path.equals("/"))
87 {
88 path = "/server";
89 }
90 return path;
91 }
92
93 public String notFoundElement(String path, HttpOutputStream out, HttpInputStream in)
94 throws IOException, HttpException
95 {
96 // no processing. Unknown elements are not found
97 throw new HttpException(HttpConstants.STATUS_NOT_FOUND, "Path " + path + " not found");
98 }
99
100 // ripped from Xerces samples
101 protected void print(PrintWriter out, Node node)
102 {
103 // is there anything to do?
104 if (node == null)
105 {
106 return;
107 }
108 int type = node.getNodeType();
109 switch (type)
110 {
111 // print document
112 case Node.DOCUMENT_NODE:
113 {
114 if (!canonical)
115 {
116 out.println("<?xml version=\"1.0\" encoding=\"" + ENCODING + "\"?>");
117 }
118 NodeList children = node.getChildNodes();
119 for (int iChild = 0; iChild < children.getLength(); iChild++)
120 {
121 print(out, children.item(iChild));
122 }
123 out.flush();
124 break;
125 }
126 // print element with attributes
127 case Node.ELEMENT_NODE:
128 {
129 out.print('<');
130 out.print(node.getNodeName());
131 Attr attrs[] = sortAttributes(node.getAttributes());
132 for (int i = 0; i < attrs.length; i++)
133 {
134 Attr attr = attrs[i];
135 out.print(' ');
136 out.print(attr.getNodeName());
137 out.print("=\"");
138 out.print(normalize(attr.getNodeValue()));
139 out.print('"');
140 }
141 out.print('>');
142 NodeList children = node.getChildNodes();
143 if (children != null)
144 {
145 int len = children.getLength();
146 for (int i = 0; i < len; i++)
147 {
148 print(out, children.item(i));
149 }
150 }
151 break;
152 }
153 // handle entity reference nodes
154 case Node.ENTITY_REFERENCE_NODE:
155 {
156 if (canonical)
157 {
158 NodeList children = node.getChildNodes();
159 if (children != null)
160 {
161 int len = children.getLength();
162 for (int i = 0; i < len; i++)
163 {
164 print(out, children.item(i));
165 }
166 }
167 }
168 else
169 {
170 out.print('&');
171 out.print(node.getNodeName());
172 out.print(';');
173 }
174 break;
175 }
176 // print cdata sections
177 case Node.CDATA_SECTION_NODE:
178 {
179 if (canonical)
180 {
181 out.print(normalize(node.getNodeValue()));
182 }
183 else
184 {
185 out.print("<![CDATA[");
186 out.print(node.getNodeValue());
187 out.print("]]>");
188 }
189 break;
190 }
191 // print text
192 case Node.TEXT_NODE:
193 {
194 out.print(normalize(node.getNodeValue()));
195 break;
196 }
197 // print processing instruction
198 case Node.PROCESSING_INSTRUCTION_NODE:
199 {
200 out.print("<?");
201 out.print(node.getNodeName());
202 String data = node.getNodeValue();
203 if (data != null && data.length() > 0)
204 {
205 out.print(' ');
206 out.print(data);
207 }
208 out.println("?>");
209 break;
210 }
211 }
212 if (type == Node.ELEMENT_NODE)
213 {
214 out.print("</");
215 out.print(node.getNodeName());
216 out.print('>');
217 }
218 out.flush();
219 }
220 // print(Node)
221
222 /**
223 * Returns a sorted list of attributes.
224 *
225 * @param attrs Description of Parameter
226 * @return Description of the Returned Value
227 * @since
228 */
229
230 protected Attr[] sortAttributes(NamedNodeMap attrs)
231 {
232 int len = (attrs != null) ? attrs.getLength() : 0;
233 Attr array[] = new Attr[len];
234 for (int i = 0; i < len; i++)
235 {
236 array[i] = (Attr)attrs.item(i);
237 }
238 for (int i = 0; i < len - 1; i++)
239 {
240 String name = array[i].getNodeName();
241 int index = i;
242 for (int j = i + 1; j < len; j++)
243 {
244 String curName = array[j].getNodeName();
245 if (curName.compareTo(name) < 0)
246 {
247 name = curName;
248 index = j;
249 }
250 }
251 if (index != i)
252 {
253 Attr temp = array[i];
254 array[i] = array[index];
255 array[index] = temp;
256 }
257 }
258 return (array);
259 }
260
261 /**
262 * Normalizes the given string.
263 *
264 * @param s Description of Parameter
265 * @return Description of the Returned Value
266 * @since
267 */
268
269 protected String normalize(String s)
270 {
271 StringBuffer str = new StringBuffer();
272 int len = (s != null) ? s.length() : 0;
273 for (int i = 0; i < len; i++)
274 {
275 char ch = s.charAt(i);
276 switch (ch)
277 {
278 case '<':
279 {
280 str.append("&lt;");
281 break;
282 }
283 case '>':
284 {
285 str.append("&gt;");
286 break;
287 }
288 case '&':
289 {
290 str.append("&amp;");
291 break;
292 }
293 case '"':
294 {
295 str.append("&quot;");
296 break;
297 }
298 case '\'':
299 {
300 str.append("&apos;");
301 break;
302 }
303 case '\r':
304 case '\n':
305 {
306 if (canonical)
307 {
308 str.append("&#");
309 str.append(Integer.toString(ch));
310 str.append(';');
311 break;
312 }
313 // else, default append char
314 }
315 default:
316 {
317 str.append(ch);
318 }
319 }
320 }
321 return (str.toString());
322 }
323
324 private static void log(int prio, String message, Throwable t){
325 if (HttpConnectorActivator.bc!=null){
326 ServiceReference logSR=HttpConnectorActivator.bc.getServiceReference(LogService.class.getName());
327 if (logSR!=null){
328 ((LogService)HttpConnectorActivator.bc.getService(logSR)).log(prio, message, t);
329 }else{
330 System.out.println("No Log Service");
331 }
332 }else{
333 System.out.println(DefaultProcessor.class.getName()+".log: No bundleContext");
334 }
335 }
336}