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.alert.Alerts;
27  import org.millscript.millscript.datatypes.CDATA;
28  import org.millscript.millscript.datatypes.XmlComment;
29  import org.millscript.millscript.datatypes.XmlElement;
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 HTML.
37   * As such it delegates most of it's rendering methods to a normal HTML
38   * renderer.
39   */
40  public final class HTMLCDATARenderer implements Renderer {
41  
42      /**
43       * The parent HTML renderer to delegate rendering calls to.
44       */
45      private final HTMLRenderer parentRenderer;
46  
47      /**
48       * Constructs a new HTML CDATA renderer, to use the specified HTML renderer
49       * for rendering.
50       *
51       * @param hr    the HTML renderer to delegate to
52       */
53      public HTMLCDATARenderer( final HTMLRenderer 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         // It's not clear we need to do anything special to render a
145         // CDATA object in HTML, even though this is the CDATA renderer!
146         parentRenderer.renderCDATA( c );
147     }
148 
149     /**
150      * @see org.millscript.millscript.render.Renderer#renderDocumentFooter()
151      */
152     public void renderDocumentFooter() throws IOException {
153         parentRenderer.renderDocumentFooter();
154     }
155 
156     /**
157      * @see org.millscript.millscript.render.Renderer#renderDocumentHeader()
158      */
159     public void renderDocumentHeader() throws IOException {
160         parentRenderer.renderDocumentHeader();
161     }
162 
163     /**
164      * @see org.millscript.millscript.render.Renderer#renderObject(java.lang.Object)
165      */
166     public void renderObject( final Object o ) throws IOException {
167         parentRenderer.appendNoEscape( o.toString() );
168     }
169 
170     /**
171      * @see org.millscript.millscript.render.Renderer#renderXMLComment(org.millscript.millscript.datatypes.XmlComment)
172      */
173     public void renderXMLComment( final XmlComment c ) throws IOException {
174         parentRenderer.renderXMLComment( c );
175     }
176 
177     /**
178      * @see org.millscript.millscript.render.Renderer#renderXMLElement(org.millscript.millscript.datatypes.XmlElement)
179      */
180     public void renderXMLElement( final XmlElement x ) throws IOException {
181         parentRenderer.appendNoEscape( '<' );
182         parentRenderer.appendNoEscape( x.tagName() );
183 
184         MapIterator it = x.getAttributes().iterator( true );
185         while ( it.hasNext() ) {
186             Object key = it.nextKey();
187             Object val = it.currentValue();
188             if ( key != null ) {
189                 parentRenderer.appendNoEscape( ' ' );
190                 parentRenderer.appendNoEscape( key.toString() );
191                 if ( val != null ) {
192                     parentRenderer.appendNoEscape( "=\"" );
193                     if ( HTMLRenderer.URI_ATTRS.contains( key ) ) {
194                         parentRenderer.renderURI( val );
195                     } else {
196                         parentRenderer.appendNoEscape( val.toString() );
197                     }
198                     parentRenderer.appendNoEscape( '"' );
199                 }
200             }
201         }
202 
203         final Object[] kids = x.getChildren();
204         final int nkids = kids.length;
205 
206         if ( nkids == 0 ) {
207             parentRenderer.appendNoEscape( '>' );
208             if ( !HTMLRenderer.EMPTY_TAGS.contains( x.tagName() ) ) {
209                 parentRenderer.appendNoEscape( "</" );
210                 parentRenderer.appendNoEscape( x.tagName() );
211                 parentRenderer.appendNoEscape( '>' );
212             }
213         } else {
214             if ( HTMLRenderer.EMPTY_TAGS.contains( x.tagName() ) ) {
215                 throw(
216                     Alerts.eval(
217                         "Cannot render children of this element",
218                         "This is a mandatory empty element"
219                     ).culprit( "element", x ).mishap()
220                 );
221             } else {
222                 parentRenderer.appendNoEscape( '>' );
223                 for ( int i = 0; i < nkids; i++ ) {
224                     this.render( kids[ i ] );
225                 }
226                 parentRenderer.appendNoEscape( "</" );
227                 parentRenderer.appendNoEscape( x.tagName() );
228                 parentRenderer.appendNoEscape( '>' );
229             }
230         }
231     }
232 
233 }