1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
119
120
121
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
145
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 }