KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ecs > ConcreteElement


1 /*
2  * ====================================================================
3  *
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowlegement:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "The Jakarta Project", "Jakarta Element Construction Set",
29  * "Jakarta ECS" , and "Apache Software Foundation" must not be used
30  * to endorse or promote products derived
31  * from this software without prior written permission. For written
32  * permission, please contact apache@apache.org.
33  *
34  * 5. Products derived from this software may not be called "Apache",
35  * "Jakarta Element Construction Set" nor "Jakarta ECS" nor may "Apache"
36  * appear in their names without prior written permission of the Apache Group.
37  *
38  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
39  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
40  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
45  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
47  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
48  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49  * SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This software consists of voluntary contributions made by many
53  * individuals on behalf of the Apache Software Foundation. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  *
57  */

58 package org.apache.ecs;
59
60 import java.io.OutputStream;
61 import java.io.PrintWriter;
62 import java.io.Writer;
63 import java.io.IOException;
64 import java.io.ByteArrayInputStream;
65 import java.io.ByteArrayOutputStream;
66 import java.io.ObjectInputStream;
67 import java.io.ObjectOutputStream;
68 import java.io.StreamCorruptedException;
69 import java.util.Enumeration;
70 import java.util.Vector;
71 import java.util.Hashtable;
72
73 /**
74     This class is to be subclassed by those elements that are made up of
75     other elements. i.e. BODY,HEAD,etc.
76
77     @version $Id: ConcreteElement.java,v 1.31 2003/05/13 12:23:18 rdonkin Exp $
78     @author <a HREF="mailto:snagy@servletapi.com">Stephan Nagy</a>
79     @author <a HREF="mailto:jon@clearink.com">Jon S. Stevens</a>
80 */

81 public class ConcreteElement extends ElementAttributes implements Cloneable
82 {
83     /** The line separator to use for pretty printing */
84     private static String lineSeparator = System.getProperty("line.separator");
85
86     /** @serial registry registry */
87     private Hashtable registry = new Hashtable(4); // keep a list of elements that need to be added to the element
88
/** Maintain an ordered list of elements */
89     private Vector registryList = new Vector(2);
90
91     public ConcreteElement()
92     {
93     }
94
95     /**
96         If the object is in the registry return otherwise return null.
97         @param element the name of the object to locate.
98     */

99     public ConcreteElement getElement(String element)
100     {
101         if(registry.containsKey(element))
102         {
103             return (ConcreteElement)registry.get(element);
104         }
105         return null;
106     }
107
108     /**
109         Registers an element in the head element list
110         @param element element to be added to the registry.
111     */

112     public Element addElementToRegistry(Element element)
113     {
114         if ( element == null )
115             return(this);
116         addElementToRegistry(Integer.toString(element.hashCode()),element);
117         return(this);
118     }
119
120     /**
121         Registers an element in the head element list
122         @param hashcode internal name of element
123         @param element element to be added to the registry.
124     */

125     public Element addElementToRegistry(String hashcode,Element element)
126     {
127         if ( hashcode == null || element == null )
128             return(this);
129
130          element.setFilterState(getFilterState());
131          if(ECSDefaults.getDefaultPrettyPrint() != element.getPrettyPrint())
132               element.setPrettyPrint(getPrettyPrint());
133          registry.put(hashcode,element);
134          if(!registryList.contains(hashcode))
135             registryList.addElement(hashcode);
136          return(this);
137     }
138
139     /**
140         Registers an element in the head element list
141         @hashcode named element for hashcode
142         @param element element to be added to the registry.
143         @param filter does this need to be filtered?
144     */

145     public Element addElementToRegistry(Element element,boolean filter)
146     {
147         if ( element == null )
148             return(this);
149         setFilterState(filter);
150         addElementToRegistry(Integer.toString(element.hashCode()),element);
151         return(this);
152     }
153
154     /**
155         Registers an element in the head element list
156         @param element element to be added to the registry.
157         @param filter should we filter this element?
158     */

159     public Element addElementToRegistry(String hashcode, Element element,boolean filter)
160     {
161         if ( hashcode == null )
162             return(this);
163         setFilterState(filter);
164         addElementToRegistry(hashcode,element);
165         return(this);
166     }
167
168     /**
169         Registers an element in the head element list
170         @param element element to be added to the registry.
171         @param filter does this need to be filtered?
172     */

173     public Element addElementToRegistry(String value,boolean filter)
174     {
175         if ( value == null )
176             return(this);
177         setFilterState(filter);
178         addElementToRegistry(Integer.toString(value.hashCode()),value);
179         return(this);
180     }
181
182     /**
183         Registers an element in the head element list
184         @hashcode named element for hashcode
185         @param element element to be added to the registry.
186         @param filter does this need to be filtered?
187     */

188     public Element addElementToRegistry(String hashcode, String value,boolean filter)
189     {
190         if ( hashcode == null )
191             return(this);
192         setFilterState(filter);
193         addElementToRegistry(hashcode,value);
194         return(this);
195     }
196
197     /**
198         Registers an element in the head element list
199         @param element element to be added to the registry.
200     */

201     public Element addElementToRegistry(String value)
202     {
203         if ( value == null )
204             return(this);
205         addElementToRegistry(new StringElement(value));
206         return(this);
207     }
208
209     /**
210         Registers an element in the head element list
211         @param element element to be added to the registry.
212     */

213     public Element addElementToRegistry(String hashcode,String value)
214     {
215         if ( hashcode == null )
216             return(this);
217
218         // We do it this way so that filtering will work.
219
// 1. create a new StringElement(element) - this is the only way that setTextTag will get called
220
// 2. copy the filter state of this string element to this child.
221
// 3. copy the prettyPrint state of the element to this child
222
// 4. copy the filter for this string element to this child.
223

224         StringElement se = new StringElement(value);
225         se.setFilterState(getFilterState());
226         se.setFilter(getFilter());
227         se.setPrettyPrint(getPrettyPrint());
228         addElementToRegistry(hashcode,se);
229         return(this);
230     }
231
232     /**
233         Removes an element from the element registry
234         @param element element to be added to the registry.
235     */

236     public Element removeElementFromRegistry(Element element)
237     {
238         removeElementFromRegistry(Integer.toString(element.hashCode()));
239         return(this);
240     }
241
242     /**
243         Removes an element from the head element registry
244         @param hashcode element to be added to the registry.
245     */

246     public Element removeElementFromRegistry(String hashcode)
247     {
248         registry.remove(hashcode);
249         registryList.removeElement(hashcode);
250         return(this);
251     }
252
253     /**
254         Find out if this element is in the element registry.
255         @param element find out if this element is in the registry
256     */

257     public boolean registryHasElement(Element element)
258     {
259         return(registry.contains(element));
260     }
261
262     /**
263         Get the keys of this element.
264     */

265     public Enumeration keys()
266     {
267         return(registryList.elements());
268     }
269
270     /**
271         Get an enumeration of the elements that this element contains.
272     */

273     public Enumeration elements()
274     {
275         return(registry.elements());
276     }
277
278     /**
279         Find out if this element is in the element registry.
280         @param element find out if this element is in the registry
281     */

282     public boolean registryHasElement(String hashcode)
283     {
284         return(registry.containsKey(hashcode));
285     }
286
287     /**
288         Overload output(OutputStream).
289         @param output OutputStream to write to.
290         @param ConcreteElement Instance of ConcreteElement
291     */

292     public static void output(OutputStream out, ConcreteElement ce)
293     {
294         // use the encoding for the given element
295
String encoding = ce.getCodeSet();
296         if ( encoding == null )
297         {
298            // By default use Big Endian Unicode.
299
// In this way we will not loose any information.
300
encoding = "UTF-16BE";
301         }
302         
303         boolean prettyPrint = ce.getPrettyPrint();
304         int tabLevel = ce.getTabLevel();
305         try
306         {
307             if (ce.registry.size() == 0)
308             {
309                 ce.output(out);
310             }
311             else
312             {
313                 if ((prettyPrint && ce instanceof Printable) && (tabLevel > 0))
314                     ce.putTabs(tabLevel, out);
315
316                 out.write(ce.createStartTag().getBytes(encoding));
317
318                 // If this is a StringElement that has ChildElements still print the TagText
319
if(ce.getTagText() != null)
320                     out.write(ce.getTagText().getBytes(encoding));
321
322                 Enumeration enum = ce.registryList.elements();
323
324                 while(enum.hasMoreElements())
325                 {
326                     Object obj = ce.registry.get((String)enum.nextElement());
327                     if(obj instanceof GenericElement)
328                     {
329                         Element e = (Element)obj;
330                         if (prettyPrint && ce instanceof Printable)
331                         {
332                             if ( ce.getNeedLineBreak() )
333                             {
334                                 out.write(ce.lineSeparator.getBytes(encoding));
335                                 e.setTabLevel(tabLevel + 1);
336                             }
337                         }
338                         e.output(out);
339                     }
340                     else
341                     {
342                         if (prettyPrint && ce instanceof Printable)
343                         {
344                             if ( ce.getNeedLineBreak() )
345                             {
346                                 out.write(ce.lineSeparator.getBytes(encoding));
347                                 ce.putTabs(tabLevel + 1, out);
348                             }
349                         }
350                         String string = obj.toString();
351                         out.write(string.getBytes(encoding));
352                     }
353                 }
354                 if (ce.getNeedClosingTag())
355                 {
356                     if (prettyPrint && ce instanceof Printable)
357                     {
358                         if ( ce.getNeedLineBreak() )
359                         {
360                             out.write(ce.lineSeparator.getBytes(encoding));
361                             if (tabLevel > 0)
362                                 ce.putTabs(tabLevel, out);
363                         }
364                     }
365                 out.write(ce.createEndTag().getBytes(encoding));
366                 }
367             }
368         }
369         catch(IOException ioe)
370         {
371             ioe.printStackTrace(new PrintWriter(out));
372         }
373     }
374     
375     /**
376         Override output(OutputStream) incase any elements are in the registry.
377         @param output OutputStream to write to.
378     */

379     public void output(OutputStream out)
380     {
381         if (this.registry.size() == 0)
382         {
383                 int tabLevel = getTabLevel();
384                 if ((getPrettyPrint() && this instanceof Printable) && (tabLevel > 0))
385                 {
386                     try
387                     {
388                         this.putTabs(tabLevel, out);
389                     }
390                     catch(IOException ioe)
391                     {
392                         ioe.printStackTrace(new PrintWriter(out));
393                     }
394                 }
395                 super.output(out);
396         }
397         else
398         {
399             output(out,this);
400         }
401     }
402
403     /**
404         Writer version of this method.
405     */

406     public void output(Writer out)
407     {
408         PrintWriter pw = new PrintWriter(out);
409         output ( pw );
410         pw.flush();
411     }
412     
413     /**
414         Override output(BufferedWriter) incase any elements are in the registry.
415         @param output OutputStream to write to.
416     */

417     public void output(PrintWriter out)
418     {
419         boolean prettyPrint = getPrettyPrint();
420         int tabLevel = getTabLevel();
421         if (registry.size() == 0)
422         {
423             if ((prettyPrint && this instanceof Printable) && (tabLevel > 0))
424                 putTabs(tabLevel, out);
425
426             super.output(out);
427         }
428         else
429         {
430             if ((prettyPrint && this instanceof Printable) && (tabLevel > 0))
431                 putTabs(tabLevel, out);
432
433             out.write(createStartTag());
434             // If this is a StringElement that has ChildElements still print the TagText
435
if(getTagText() != null)
436                 out.write(getTagText());
437
438             Enumeration enum = registryList.elements();
439             while(enum.hasMoreElements())
440             {
441                 Object obj = registry.get((String)enum.nextElement());
442                 if(obj instanceof GenericElement)
443                 {
444                     Element e = (Element)obj;
445                     if (prettyPrint && this instanceof Printable)
446                     {
447                         if (getNeedLineBreak()) {
448                             out.write(lineSeparator);
449                             e.setTabLevel(tabLevel + 1);
450                         }
451                     }
452                     e.output(out);
453                 }
454                 else
455                 {
456                     if (prettyPrint && this instanceof Printable)
457                     {
458                         if (getNeedLineBreak()) {
459                             out.write(lineSeparator);
460                             putTabs(tabLevel + 1, out);
461                         }
462                     }
463                     String string = obj.toString();
464                     if(getFilterState())
465                         out.write(getFilter().process(string));
466                     else
467                         out.write(string);
468                 }
469             }
470             if (getNeedClosingTag())
471             {
472                 if (prettyPrint && this instanceof Printable)
473                 {
474                     if (getNeedLineBreak()) {
475                         out.write(lineSeparator);
476                         if (tabLevel > 0)
477                             putTabs(tabLevel, out);
478                     }
479                 }
480                out.write(createEndTag());
481             }
482         }
483     }
484
485     /**
486         Allows all Elements the ability to be cloned.
487     */

488     public Object clone()
489     {
490         try
491         {
492             ByteArrayOutputStream baos = new ByteArrayOutputStream();
493             ObjectOutputStream out = new ObjectOutputStream(baos);
494             out.writeObject(this);
495             out.close();
496             ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray());
497             ObjectInputStream in = new ObjectInputStream(bin);
498             Object clone = in.readObject();
499             in.close();
500             return(clone);
501         }
502         catch(ClassNotFoundException cnfe)
503         {
504             throw new InternalError(cnfe.toString());
505         }
506         catch(StreamCorruptedException sce)
507         {
508             throw new InternalError(sce.toString());
509         }
510         catch(IOException ioe)
511         {
512             throw new InternalError(ioe.toString());
513         }
514     }
515     
516     public boolean isEmpty()
517     {
518         return registryList.isEmpty();
519     }
520 }
521
Popular Tags