View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2005 Open World Ltd
4   // Copyright (C) 2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript.render;
23  
24  import org.millscript.commons.util.IList;
25  import org.millscript.commons.util.MapIterator;
26  import org.millscript.millscript.datatypes.CDATA;
27  import org.millscript.millscript.datatypes.XmlComment;
28  import org.millscript.millscript.datatypes.XmlElement;
29  import org.millscript.millscript.tools.StringTools;
30  
31  import java.io.IOException;
32  import java.util.Iterator;
33  import java.util.List;
34  
35  /**
36   * This renderer is used for rendering the CDATA content of an element in XML.
37   * As such it delegates most of it's rendering methods to a normal XML
38   * renderer.
39   */
40  public final class XMLCDATARenderer implements Renderer {
41  
42      /**
43       * The parent XML renderer to delegate rendering calls to.
44       */
45      private final Renderer parentRenderer;
46  
47      /**
48       * Constructs a new XML CDATA renderer, to use the specified XML renderer
49       * for rendering.
50       *
51       * @param hr    the XML renderer to delegate to
52       */
53      public XMLCDATARenderer( final Renderer hr ) {
54          this.parentRenderer = hr;
55      }
56  
57      /**
58       * @see org.millscript.millscript.render.Renderer#append(char)
59       */
60      public void append( final char ch ) throws IOException {
61          parentRenderer.append( ch );
62      }
63  
64      /**
65       * @see org.millscript.millscript.render.Renderer#append(java.lang.CharSequence)
66       */
67      public void append( final CharSequence cs ) throws IOException {
68          parentRenderer.append( cs );
69      }
70  
71      /**
72       * @see org.millscript.millscript.render.Renderer#appendEscapeFor(char)
73       */
74      public void appendEscapeFor( final char ch ) throws IOException {
75          parentRenderer.appendEscapeFor( ch );
76      }
77  
78      /**
79       * @see org.millscript.millscript.render.Renderer#appendNoEscape(char)
80       */
81      public void appendNoEscape( final char ch ) throws IOException {
82          parentRenderer.appendNoEscape( ch );
83      }
84  
85      /**
86       * @see org.millscript.millscript.render.Renderer#appendNoEscape(java.lang.CharSequence)
87       */
88      public void appendNoEscape( final CharSequence cs ) throws IOException {
89          parentRenderer.appendNoEscape( cs );
90      }
91  
92      /**
93       * @see org.millscript.millscript.render.Renderer#canEncode(char)
94       */
95      public boolean canEncode( final char ch ) {
96          return parentRenderer.canEncode( ch );
97      }
98  
99      /**
100      * @see org.millscript.millscript.render.Renderer#render(java.lang.Object)
101      */
102     public void render( final Object o ) throws IOException {
103         if ( o == null ) {
104             return;
105         } else if ( o instanceof Renderable ) {
106             ((Renderable) o).render( this );
107         } else if ( o instanceof IList ) {
108             MapIterator it = ((IList) o).iterator( true );
109             while ( it.hasNext() ) {
110                 this.render( it.nextValue() );
111             }
112         } else if ( o instanceof List ) {
113             Iterator it = ((List)o).iterator();
114             while ( it.hasNext() ) {
115                 this.render( it.next() );
116             }
117         } else {
118             // FIXME - This code should use the standard
119             // AbstractRenderer.append(CharSequence) but we need to provide a way to
120             // parse database content into an XmlElement before we can change
121             // it.
122             this.renderObject( o );
123         }
124     }
125 
126     /**
127      * @see org.millscript.millscript.render.Renderer#renderAsDocument(java.lang.Object)
128      */
129     public void renderAsDocument( final Object o ) {
130         parentRenderer.renderAsDocument( o );
131     }
132 
133     /**
134      * @see org.millscript.millscript.render.Renderer#renderAsFragment(org.millscript.commons.util.IList)
135      */
136     public void renderAsFragment( final IList l ) {
137         parentRenderer.renderAsFragment( l );
138     }
139 
140     /**
141      * @see org.millscript.millscript.render.Renderer#renderCDATA(org.millscript.millscript.datatypes.CDATA)
142      */
143     public void renderCDATA( final CDATA c ) throws IOException {
144         parentRenderer.appendNoEscape( "<![CDATA[" );
145         final Object[] kids = c.getStore();
146         final int nkids = kids.length;
147         for ( int i = 0; i < nkids; i++ ) {
148             this.render( kids[ i ] );
149         }
150         parentRenderer.appendNoEscape( "]]>" );
151     }
152 
153     /**
154      * @see org.millscript.millscript.render.Renderer#renderDocumentFooter()
155      */
156     public void renderDocumentFooter() throws IOException {
157         parentRenderer.renderDocumentFooter();
158     }
159 
160     /**
161      * @see org.millscript.millscript.render.Renderer#renderDocumentHeader()
162      */
163     public void renderDocumentHeader() throws IOException {
164         parentRenderer.renderDocumentHeader();
165     }
166 
167     /**
168      * @see org.millscript.millscript.render.Renderer#renderObject(java.lang.Object)
169      */
170     public void renderObject( final Object o ) throws IOException {
171         // TODO - This isn't the most efficient way to deal with this problem
172         // but it's the easiest. This won't be on the critical path when
173         // rendering anyway.
174         parentRenderer.appendNoEscape(
175             StringTools.substituteAll(
176                 o.toString(),
177                 "]]>",
178                 "]]]]><![CDATA[>"
179             )
180         );
181     }
182 
183     /**
184      * @see org.millscript.millscript.render.Renderer#renderXMLComment(org.millscript.millscript.datatypes.XmlComment)
185      */
186     public void renderXMLComment( final XmlComment c ) throws IOException {
187         parentRenderer.renderXMLComment( c );
188     }
189 
190     /**
191      * @see org.millscript.millscript.render.Renderer#renderXMLElement(org.millscript.millscript.datatypes.XmlElement)
192      */
193     public void renderXMLElement( final XmlElement x ) throws IOException {
194         parentRenderer.appendNoEscape( '<' );
195         parentRenderer.appendNoEscape( x.tagName() );
196 
197         MapIterator it = x.getAttributes().iterator( true );
198         while ( it.hasNext() ) {
199             Object key = it.nextKey();
200             Object val = it.currentValue();
201             if ( key != null ) {
202                 parentRenderer.appendNoEscape( ' ' );
203                 parentRenderer.appendNoEscape( key.toString() );
204                 // All attributes have the equals and quotes even if there is
205                 // no value.
206                 parentRenderer.appendNoEscape( "=\"" );
207                 if ( val != null ) {
208                     parentRenderer.appendNoEscape( val.toString() );
209                 }
210                 parentRenderer.appendNoEscape( '"' );
211             }
212         }
213 
214         final Object[] kids = x.getChildren();
215         final int nkids = kids.length;
216 
217         if ( nkids == 0 ) {
218             parentRenderer.appendNoEscape( " />" );
219         } else {
220             parentRenderer.appendNoEscape( '>' );
221             for ( int i = 0; i < nkids; i++ ) {
222                 this.render( kids[ i ] );
223             }
224             parentRenderer.appendNoEscape( "</" );
225             parentRenderer.appendNoEscape( x.tagName() );
226             parentRenderer.appendNoEscape( '>' );
227         }
228     }
229 
230 }