1 // ========================================================================
2 // $Id: Element.java,v 1.10 2005/08/13 00:01:23 gregwilkins Exp $
3 // Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 package org.mortbay.html;
17 import java.io.IOException;
18 import java.io.OutputStream;
19 import java.io.OutputStreamWriter;
20 import java.io.StringWriter;
21 import java.io.Writer;
22 import java.util.Enumeration;
23 import java.util.Hashtable;
24
25 import org.mortbay.log.Log;
26
27
28 /* -------------------------------------------------------------------- */
29 /** HTML Element.
30 * <p>This abstract class is the base for all HTML Elements.
31 * The feature of an abstract HTML Element is that it can be added to
32 * HTML Pages, HTML Composites and several other HTML Elements derivations.
33 * Elements may also have attributes set, which are handled by the derived
34 * Element.
35 * @deprecated Unless somebody steps forward to update and maintain this package
36 * @see Page
37 * @see Composite
38 * @version $Id: Element.java,v 1.10 2005/08/13 00:01:23 gregwilkins Exp $
39 * @author Greg Wilkins
40 */
41 public abstract class Element
42 {
43
44 /* ----------------------------------------------------------------- */
45 public static final String
46 noAttributes="",
47 ALIGN="align",
48 LEFT="left",
49 RIGHT="right",
50 CENTER="center",
51 VALIGN="valign",
52 TOP="top",
53 BOTTOM="bottom",
54 MIDDLE="middle",
55 WIDTH="width",
56 HEIGHT="height",
57 SIZE="size",
58 COLOR="color",
59 BGCOLOR="bgcolor",
60 STYLE="style",
61 CLASS="class",
62 ID="id";
63
64
65
66 /* ----------------------------------------------------------------- */
67 /** Dimensions >=0 if set*/
68 private int width=-1;
69 private int height=-1;
70 private int size=-1;
71
72 /* ----------------------------------------------------------------- */
73 /** The space separated string of HTML element attributes.
74 */
75 private String attributes=null;
76 protected Hashtable attributeMap=null;
77
78 /* ----------------------------------------------------------------- */
79 /** Default constructor.
80 */
81 public Element(){}
82
83 /* ----------------------------------------------------------------- */
84 /** Construct with attributes.
85 * @param attributes The initial attributes of the element
86 */
87 public Element(String attributes)
88 {
89 attribute(attributes);
90 }
91
92 /* ----------------------------------------------------------------- */
93 /** Write element to a Writer.
94 * This abstract method is called by the Page or other containing
95 * Element to write the HTML for this element. This must be implemented
96 * by the derived Element classes.
97 * @param out Writer to write the element to.
98 */
99 public abstract void write(Writer out)
100 throws IOException;
101
102 /* ----------------------------------------------------------------- */
103 /** Write Element to an OutputStream.
104 * Calls print(Writer) and checks errors
105 * Elements that override this method should also override
106 * write(Writer) to avoid infinite recursion.
107 * @param out OutputStream to write the element to.
108 */
109 public void write(OutputStream out)
110 throws IOException
111 {
112 Writer writer = new OutputStreamWriter(out);
113 write(writer);
114 writer.flush();
115 }
116
117 /* ----------------------------------------------------------------- */
118 /** Write Element to an OutputStream.
119 * Calls print(Writer) and checks errors
120 * Elements that override this method should also override
121 * write(Writer) to avoid infinite recursion.
122 * @param out OutputStream to write the element to.
123 */
124 public void write(OutputStream out, String encoding)
125 throws IOException
126 {
127 Writer writer = new OutputStreamWriter(out,encoding);
128 write(writer);
129 writer.flush();
130 }
131
132 /* ----------------------------------------------------------------- */
133 public String attributes()
134 {
135 if (attributes==null && attributeMap==null)
136 return noAttributes;
137
138 StringBuffer buf = new StringBuffer(128);
139 synchronized(buf)
140 {
141 if (attributeMap!=null)
142 {
143 Enumeration e = attributeMap.keys();
144 while (e.hasMoreElements())
145 {
146 buf.append(' ');
147 String a = (String)e.nextElement();
148 buf.append(a);
149 buf.append('=');
150 buf.append(attributeMap.get(a).toString());
151 }
152 }
153
154 if(attributes!=null && attributes.length()>0)
155 {
156 if (!attributes.startsWith(" "))
157 buf.append(' ');
158 buf.append(attributes);
159 }
160 }
161
162 return buf.toString();
163 }
164
165 /* ----------------------------------------------------------------- */
166 /** Add element Attributes.
167 * The attributes are added to the Element attributes (separated with
168 * a space). The attributes are available to the derived class in the
169 * protected member String <I>attributes</I>
170 * @deprecated Use attribute(String).
171 * @param attributes String of HTML attributes to add to the element.
172 * @return This Element so calls can be chained.
173 */
174 public Element attributes(String attributes)
175 {
176 if (attributes==null)
177 {
178 this.attributes=null;
179 return this;
180 }
181
182 if (attributes==noAttributes)
183 return this;
184
185 if (this.attributes==null)
186 this.attributes=attributes;
187 else
188 this.attributes += ' '+attributes;
189 return this;
190 }
191
192 /* ------------------------------------------------------------ */
193 /** Set attributes from another Element.
194 * @param e Element
195 * @return This Element
196 */
197 public Element setAttributesFrom(Element e)
198 {
199 attributes=e.attributes;
200 attributeMap=(Hashtable)e.attributeMap.clone();
201 return this;
202 }
203
204
205 /* ----------------------------------------------------------------- */
206 /** Add element Attributes.
207 * The attributes are added to the Element attributes (separated with
208 * a space). The attributes are available to the derived class in the
209 * protected member String <I>attributes</I>
210 * @param attributes String of HTML attributes to add to the element.
211 * A null attribute clears the current attributes.
212 * @return This Element so calls can be chained.
213 */
214 public Element attribute(String attributes)
215 {
216 if (attributes==null ||
217 this.attributes==null ||
218 this.attributes==noAttributes ||
219 this.attributes.length()==0)
220 this.attributes=attributes;
221 else
222 this.attributes += ' '+attributes;
223 return this;
224 }
225
226 /* ----------------------------------------------------------------- */
227 /** Add quoted element Attributes and value.
228 * @param attribute String of HTML attribute tag
229 * @param value String value of the attribute to be quoted
230 * @return This Element so calls can be chained.
231 */
232 public Element attribute(String attribute, Object value)
233 {
234 if (attributeMap==null)
235 attributeMap=new Hashtable(10);
236
237 if (value!=null)
238 {
239 if (value instanceof String && ((String)value).indexOf('"')!=-1)
240 {
241 String s=(String)value;
242 int q=0;
243 while((q=s.indexOf('"',q))>=0)
244 {
245 s=s.substring(0,q)+"""+s.substring(++q);
246 q+=6;
247 }
248 value=s;
249 }
250
251 attributeMap.put(attribute,"\""+value+'"');
252 }
253 return this;
254 }
255
256 /* ----------------------------------------------------------------- */
257 /** Add quoted element Attributes and value.
258 * @param attribute String of HTML attribute tag
259 * @param value String value of the attribute to be quoted
260 * @return This Element so calls can be chained.
261 */
262 public Element attribute(String attribute, long value)
263 {
264 if (attributeMap==null)
265 attributeMap=new Hashtable(10);
266
267 attributeMap.put(attribute,Long.toString(value));
268 return this;
269 }
270
271 /* ----------------------------------------------------------------- */
272 /** Convert Element to String.
273 * Uses write() to convert the HTML Element to a string.
274 * @return String of the HTML element
275 */
276 public String toString()
277 {
278 try{
279 StringWriter out = new StringWriter();
280 write(out);
281 out.flush();
282 return out.toString();
283 }
284 catch(IOException e){
285 Log.ignore(e);
286 }
287 return null;
288 }
289
290 /* ----------------------------------------------------------------- */
291 /** left justify.
292 * Convenience method equivalent to attribute("align","left"). Not
293 * applicable to all Elements.
294 */
295 public Element left()
296 {
297 return attribute(ALIGN,LEFT);
298 }
299
300 /* ----------------------------------------------------------------- */
301 /** right justify.
302 * Convenience method equivalent to attribute("align","right"). Not
303 * applicable to all Elements.
304 */
305 public Element right()
306 {
307 return attribute(ALIGN,RIGHT);
308 }
309
310 /* ----------------------------------------------------------------- */
311 /** Center.
312 * Convenience method equivalent to attribute("align","center"). Not
313 * applicable to all Elements.
314 */
315 public Element center()
316 {
317 return attribute(ALIGN,CENTER);
318 }
319
320 /* ----------------------------------------------------------------- */
321 /** Top align.
322 * Convenience method equivalent to attribute("valign","top"). Not
323 * applicable to all Elements.
324 */
325 public Element top()
326 {
327 return attribute(VALIGN,TOP);
328 }
329
330 /* ----------------------------------------------------------------- */
331 /** Bottom align.
332 * Convenience method equivalent to attribute("valign","bottom"). Not
333 * applicable to all Elements.
334 */
335 public Element bottom()
336 {
337 return attribute(VALIGN,BOTTOM);
338 }
339
340 /* ----------------------------------------------------------------- */
341 /** Middle align.
342 * Convenience method equivalent to attribute("valign","middle"). Not
343 * applicable to all Elements.
344 */
345 public Element middle()
346 {
347 return attribute(VALIGN,MIDDLE);
348 }
349
350 /* ----------------------------------------------------------------- */
351 /** set width.
352 * Convenience method equivalent to attribute("width",w). Not
353 * applicable to all Elements.
354 */
355 public Element width(int w)
356 {
357 width=w;
358 return attribute(WIDTH,w);
359 }
360
361 /* ----------------------------------------------------------------- */
362 /** set width.
363 * Convenience method equivalent to attribute("width",w). Not
364 * applicable to all Elements.
365 */
366 public Element width(String w)
367 {
368 width=-1;
369 return attribute(WIDTH,w);
370 }
371
372 /* ----------------------------------------------------------------- */
373 public int width()
374 {
375 return width;
376 }
377
378 /* ----------------------------------------------------------------- */
379 /** set height.
380 * Convenience method equivalent to attribute("height",h). Not
381 * applicable to all Elements.
382 */
383 public Element height(int h)
384 {
385 height=h;
386 return attribute(HEIGHT,h);
387 }
388
389 /* ----------------------------------------------------------------- */
390 /** set height.
391 * Convenience method equivalent to attribute("height",h). Not
392 * applicable to all Elements.
393 */
394 public Element height(String h)
395 {
396 height=-1;
397 return attribute(HEIGHT,h);
398 }
399
400 /* ----------------------------------------------------------------- */
401 public int height()
402 {
403 return height;
404 }
405
406 /* ----------------------------------------------------------------- */
407 /** set size.
408 * Convenience method equivalent to attribute("size",s). Not
409 * applicable to all Elements.
410 */
411 public Element size(int s)
412 {
413 size=s;
414 return attribute(SIZE,s);
415 }
416
417 /* ----------------------------------------------------------------- */
418 /** set size.
419 * Convenience method equivalent to attribute("size",s). Not
420 * applicable to all Elements.
421 */
422 public Element size(String s)
423 {
424 size=-1;
425 return attribute(SIZE,s);
426 }
427
428 /* ----------------------------------------------------------------- */
429 public int size()
430 {
431 return size;
432 }
433
434 /* ----------------------------------------------------------------- */
435 /** set color.
436 * Convenience method equivalent to attribute("color",color). Not
437 * applicable to all Elements.
438 */
439 public Element color(String color)
440 {
441 return attribute(COLOR,color);
442 }
443
444 /* ----------------------------------------------------------------- */
445 /** set BGCOLOR.
446 * Convenience method equivalent to attribute("bgcolor",color). Not
447 * applicable to all Elements.
448 */
449 public Element bgColor(String color)
450 {
451 return attribute(BGCOLOR,color);
452 }
453
454 /* ----------------------------------------------------------------- */
455 /** set CSS CLASS.
456 */
457 public Element cssClass(String c)
458 {
459 return attribute(CLASS,c);
460 }
461
462 /* ----------------------------------------------------------------- */
463 /** set CSS ID.
464 * Convenience method equivalent to attribute("id",id).
465 */
466 public Element cssID(String id)
467 {
468 return attribute(ID,id);
469 }
470
471 /* ----------------------------------------------------------------- */
472 /** set Style.
473 * Convenience method equivalent to attribute("style",style).
474 */
475 public Element style(String style)
476 {
477 return attribute(STYLE,style);
478 }
479 }
480
481
482
483