Remove the redundant gss top-level directory.
[pithos] / src / gr / ebs / gss / server / webdav / DOMWriter.java
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package gr.ebs.gss.server.webdav;
19
20 import java.io.OutputStreamWriter;
21 import java.io.PrintWriter;
22 import java.io.UnsupportedEncodingException;
23 import java.io.Writer;
24
25 import org.w3c.dom.Attr;
26 import org.w3c.dom.Document;
27 import org.w3c.dom.NamedNodeMap;
28 import org.w3c.dom.Node;
29 import org.w3c.dom.NodeList;
30
31 /**
32  * A sample DOM writer. This sample program illustrates how to
33  * traverse a DOM tree in order to print a document that is parsed.
34  */
35 public class DOMWriter {
36
37         //
38         // Data
39         //
40
41         /** Default Encoding */
42         private static  String
43         PRINTWRITER_ENCODING = "UTF8";
44
45         /**
46          *
47          */
48         private static String MIME2JAVA_ENCODINGS[] =
49         { "Default", "UTF-8", "US-ASCII", "ISO-8859-1", "ISO-8859-2", "ISO-8859-3", "ISO-8859-4",
50                 "ISO-8859-5", "ISO-8859-6", "ISO-8859-7", "ISO-8859-8", "ISO-8859-9", "ISO-2022-JP",
51                 "SHIFT_JIS", "EUC-JP","GB2312", "BIG5", "EUC-KR", "ISO-2022-KR", "KOI8-R", "EBCDIC-CP-US",
52                 "EBCDIC-CP-CA", "EBCDIC-CP-NL", "EBCDIC-CP-DK", "EBCDIC-CP-NO", "EBCDIC-CP-FI", "EBCDIC-CP-SE",
53                 "EBCDIC-CP-IT", "EBCDIC-CP-ES", "EBCDIC-CP-GB", "EBCDIC-CP-FR", "EBCDIC-CP-AR1",
54                 "EBCDIC-CP-HE", "EBCDIC-CP-CH", "EBCDIC-CP-ROECE","EBCDIC-CP-YU",
55                 "EBCDIC-CP-IS", "EBCDIC-CP-AR2", "UTF-16"
56         };
57
58         /** Output qualified names */
59         private boolean qualifiedNames = true;
60
61         /** Print writer. */
62         protected PrintWriter out;
63
64         /** Canonical output. */
65         protected boolean canonical;
66
67
68         /**
69          * @param encoding
70          * @param _canonical
71          * @throws UnsupportedEncodingException
72          */
73         public DOMWriter(String encoding, boolean _canonical)
74         throws UnsupportedEncodingException {
75                 out = new PrintWriter(new OutputStreamWriter(System.out, encoding));
76                 canonical = _canonical;
77         } // <init>(String,boolean)
78
79         //
80         // Constructors
81         //
82
83         /** Default constructor.
84          * @param _canonical
85          * @throws UnsupportedEncodingException
86          */
87         public DOMWriter(boolean _canonical) throws UnsupportedEncodingException {
88                 this( getWriterEncoding(), _canonical);
89         }
90
91         /**
92          * @param writer
93          * @param _canonical
94          */
95         public DOMWriter(Writer writer, boolean _canonical) {
96                 out = new PrintWriter(writer);
97                 canonical = _canonical;
98         }
99
100         /**
101          * @return the qualifiedNames
102          */
103         public boolean getQualifiedNames() {
104                 return qualifiedNames;
105         }
106
107         /**
108          * @param _qualifiedNames
109          */
110         public void setQualifiedNames(boolean _qualifiedNames) {
111                 qualifiedNames = _qualifiedNames;
112         }
113
114         /**
115          * @return the PrintWriter encoding
116          */
117         public static String getWriterEncoding( ) {
118                 return PRINTWRITER_ENCODING;
119         }// getWriterEncoding
120
121         /**
122          * @param encoding
123          */
124         public static void  setWriterEncoding( String encoding ) {
125                 if( encoding.equalsIgnoreCase( "DEFAULT" ) )
126                         PRINTWRITER_ENCODING  = "UTF8";
127                 else if( encoding.equalsIgnoreCase( "UTF-16" ) )
128                         PRINTWRITER_ENCODING  = "Unicode";
129                 else
130                         PRINTWRITER_ENCODING = MIME2Java.convert( encoding );
131         }// setWriterEncoding
132
133
134         /**
135          * @param encoding
136          * @return true if the encoding is valid
137          */
138         public static boolean isValidJavaEncoding( String encoding ) {
139                 for ( int i = 0; i < MIME2JAVA_ENCODINGS.length; i++ )
140                         if ( encoding.equals( MIME2JAVA_ENCODINGS[i] ) )
141                                 return true;
142
143                 return false;
144         }// isValidJavaEncoding
145
146
147         /** Prints the specified node, recursively.
148          * @param node
149          */
150         public void print(Node node) {
151
152                 // is there anything to do?
153                 if ( node == null )
154                         return;
155
156                 int type = node.getNodeType();
157                 switch ( type ) {
158                         // print document
159                         case Node.DOCUMENT_NODE: {
160                                 if ( !canonical ) {
161                                         String  Encoding = getWriterEncoding();
162                                         if( Encoding.equalsIgnoreCase( "DEFAULT" ) )
163                                                 Encoding = "UTF-8";
164                                         else if( Encoding.equalsIgnoreCase( "Unicode" ) )
165                                                 Encoding = "UTF-16";
166                                         else
167                                                 Encoding = MIME2Java.reverse( Encoding );
168
169                                         out.println("<?xml version=\"1.0\" encoding=\""+
170                                                                 Encoding + "\"?>");
171                                 }
172                                 print(((Document)node).getDocumentElement());
173                                 out.flush();
174                                 break;
175                         }
176
177                         // print element with attributes
178                         case Node.ELEMENT_NODE: {
179                                 out.print('<');
180                                 if (qualifiedNames)
181                                         out.print(node.getNodeName());
182                                 else
183                                         out.print(node.getLocalName());
184                                 Attr attrs[] = sortAttributes(node.getAttributes());
185                                 for ( int i = 0; i < attrs.length; i++ ) {
186                                         Attr attr = attrs[i];
187                                         out.print(' ');
188                                         if (qualifiedNames)
189                                                 out.print(attr.getNodeName());
190                                         else
191                                                 out.print(attr.getLocalName());
192
193                                         out.print("=\"");
194                                         out.print(normalize(attr.getNodeValue()));
195                                         out.print('"');
196                                 }
197                                 out.print('>');
198                                 NodeList children = node.getChildNodes();
199                                 if ( children != null ) {
200                                         int len = children.getLength();
201                                         for ( int i = 0; i < len; i++ )
202                                                 print(children.item(i));
203                                 }
204                                 break;
205                         }
206
207                         // handle entity reference nodes
208                         case Node.ENTITY_REFERENCE_NODE: {
209                                 if ( canonical ) {
210                                         NodeList children = node.getChildNodes();
211                                         if ( children != null ) {
212                                                 int len = children.getLength();
213                                                 for ( int i = 0; i < len; i++ )
214                                                         print(children.item(i));
215                                         }
216                                 } else {
217                                         out.print('&');
218                                         if (qualifiedNames)
219                                                 out.print(node.getNodeName());
220                                         else
221                                                 out.print(node.getLocalName());
222                                         out.print(';');
223                                 }
224                                 break;
225                         }
226
227                         // print cdata sections
228                         case Node.CDATA_SECTION_NODE: {
229                                 if ( canonical )
230                                         out.print(normalize(node.getNodeValue()));
231                                 else {
232                                         out.print("<![CDATA[");
233                                         out.print(node.getNodeValue());
234                                         out.print("]]>");
235                                 }
236                                 break;
237                         }
238
239                         // print text
240                         case Node.TEXT_NODE: {
241                                 out.print(normalize(node.getNodeValue()));
242                                 break;
243                         }
244
245                         // print processing instruction
246                         case Node.PROCESSING_INSTRUCTION_NODE: {
247                                 out.print("<?");
248                                 if (qualifiedNames)
249                                         out.print(node.getNodeName());
250                                 else
251                                         out.print(node.getLocalName());
252
253                                 String data = node.getNodeValue();
254                                 if ( data != null && data.length() > 0 ) {
255                                         out.print(' ');
256                                         out.print(data);
257                                 }
258                                 out.print("?>");
259                                 break;
260                         }
261                 }
262
263                 if ( type == Node.ELEMENT_NODE ) {
264                         out.print("</");
265                         if (qualifiedNames)
266                                 out.print(node.getNodeName());
267                         else
268                                 out.print(node.getLocalName());
269                         out.print('>');
270                 }
271
272                 out.flush();
273
274         } // print(Node)
275
276         /** Returns a sorted list of attributes.
277          * @param attrs
278          * @return
279          */
280         protected Attr[] sortAttributes(NamedNodeMap attrs) {
281
282                 int len = attrs != null ? attrs.getLength() : 0;
283                 Attr array[] = new Attr[len];
284                 for ( int i = 0; i < len; i++ )
285                         array[i] = (Attr)attrs.item(i);
286                 for ( int i = 0; i < len - 1; i++ ) {
287                         String name = null;
288                         if (qualifiedNames)
289                                 name  = array[i].getNodeName();
290                         else
291                                 name  = array[i].getLocalName();
292                         int    index = i;
293                         for ( int j = i + 1; j < len; j++ ) {
294                                 String curName = null;
295                                 if (qualifiedNames)
296                                         curName = array[j].getNodeName();
297                                 else
298                                         curName = array[j].getLocalName();
299                                 if ( curName.compareTo(name) < 0 ) {
300                                         name  = curName;
301                                         index = j;
302                                 }
303                         }
304                         if ( index != i ) {
305                                 Attr temp    = array[i];
306                                 array[i]     = array[index];
307                                 array[index] = temp;
308                         }
309                 }
310
311                 return array;
312
313         } // sortAttributes(NamedNodeMap):Attr[]
314
315
316         /** Normalizes the given string.
317          * @param s
318          * @return
319          */
320         @SuppressWarnings("fallthrough")
321         protected String normalize(String s) {
322                 StringBuffer str = new StringBuffer();
323
324                 int len = s != null ? s.length() : 0;
325                 for ( int i = 0; i < len; i++ ) {
326                         char ch = s.charAt(i);
327                         switch ( ch ) {
328                                 case '<': {
329                                         str.append("&lt;");
330                                         break;
331                                 }
332                                 case '>': {
333                                         str.append("&gt;");
334                                         break;
335                                 }
336                                 case '&': {
337                                         str.append("&amp;");
338                                         break;
339                                 }
340                                 case '"': {
341                                         str.append("&quot;");
342                                         break;
343                                 }
344                                 case '\r':
345                                 case '\n': {
346                                         if ( canonical ) {
347                                                 str.append("&#");
348                                                 str.append(Integer.toString(ch));
349                                                 str.append(';');
350                                                 break;
351                                         }
352                                         // else, default append char
353                                 }
354                                 default: {
355                                         str.append(ch);
356                                 }
357                         }
358                 }
359
360                 return str.toString();
361
362         } // normalize(String):String
363
364         /**
365          *
366          */
367         private static void printValidJavaEncoding() {
368                 System.err.println( "    ENCODINGS:" );
369                 System.err.print( "   " );
370                 for( int i = 0;
371                 i < MIME2JAVA_ENCODINGS.length; i++) {
372                         System.err.print( MIME2JAVA_ENCODINGS[i] + " " );
373                         if( i % 7 == 0 ){
374                                 System.err.println();
375                                 System.err.print( "   " );
376                         }
377                 }
378
379         } // printJavaEncoding()
380
381 }