View Javadoc

1   // ========================================================================
2   // $Id: Page.java,v 1.5 2004/09/23 02:15:15 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.Writer;
19  import java.util.Dictionary;
20  import java.util.Hashtable;
21  
22  /* --------------------------------------------------------------------- */
23  /** HTML Page.
24   * A HTML Page extends composite with the addition of the HTML Header
25   * tags, fields and elements.
26   * Furthermore, individual parts of the page may be written or the
27   * progressive page be output with flush.
28   * <p>
29   * Pages contain parameters and named sections. These are used by
30   * derived Page classes that implement a Look and Feel.  Page users
31   * may add to name sections such as "Margin" or "Footer" and set
32   * parameters such as "HelpUrl" without knowledge of how the look and feel
33   * will arrange these.  To assist with standard look and feel creation
34   * Page defines a set of standard names for many common parameters
35   * and sections.
36   * <p>
37   * If named sections are used, the page constructor or completeSections
38   * must add the named section to the page in the appropriate places.
39   * If named sections are not added to the page, then they can only be
40   * written with an explicit call to write(out,"section",end);
41   * Changes in behaviour to section creation and adding, should be controlled
42   * via page properties.
43   * <p>
44   * @deprecated Unless somebody steps forward to update and maintain this package
45   * @see Composite
46   * @version $Id: Page.java,v 1.5 2004/09/23 02:15:15 gregwilkins Exp $
47   * @author Greg Wilkins
48   */
49  public class Page extends Composite
50  {
51      /* ----------------------------------------------------------------- */
52      public static final String
53          Request="Request",
54          Response="Response",
55          Header="Header",
56          Title="Title",
57          Section="Section",
58          HeaderSize="HdrSize",  // HeaderSize string suitable for FRAMESET
59          Footer="Footer",
60          FooterSize="FtrSize",  // FooterSize string suitable for FRAMESET
61          Content="Content",
62          ContentSize="CntSize",
63          Margin="Margin",
64          MarginSize="MrgSize",
65          LeftMargin="Left",
66          LeftMarginSize="LMSize",
67          RightMargin="Right",
68          RightMarginSize="RMSize",
69          Help="Help",
70          Home="Home",
71          Heading="Heading", 
72          Up="Up",
73          Prev="Prev",
74          Next="Next",
75          Back="Back",
76          Target="Target",
77          BaseUrl="BaseUrl",
78          FgColour="FgColour",
79          BgColour="BgColour",
80          HighlightColour="HlColour",
81          PageType="PageType",
82          NoTitle="No Title"
83          ;
84  
85      /* ----------------------------------------------------------------- */
86      protected Hashtable properties = new Hashtable(10);
87  
88      /* ----------------------------------------------------------------- */
89      Hashtable sections = new Hashtable(10);
90      private Composite head= new Composite();
91      private String base="";
92      private boolean writtenHtmlHead = false;
93      private boolean writtenBodyTag = false;
94  
95      /* ----------------------------------------------------------------- */
96      public Page()
97      {
98          this(NoTitle);
99      }
100 
101     /* ----------------------------------------------------------------- */
102     public Page(String title)
103     {
104         title(title);
105     }
106 
107     /* ----------------------------------------------------------------- */
108     public Page(String title, String attributes)
109     {
110         title(title);
111         attribute(attributes);
112     }
113 
114     /* ----------------------------------------------------------------- */
115     /** Set page title.
116      * @return This Page (for chained commands)
117      */
118     public Page title(String title)
119     {
120         properties.put(Title,title);
121         String heading = (String)properties.get(Heading);
122         if (heading==null||heading.equals(NoTitle))
123             properties.put(Heading,title);
124         return this;
125     }
126 
127     /* ----------------------------------------------------------------- */
128     /** Add element or object to the page header.
129      * @param o The Object to add. If it is a String or Element, it is
130      * added directly, otherwise toString() is called.
131      * @return This Page (for chained commands)
132      */    
133     public Page addHeader(Object o)
134     {
135         head.add("\n");
136         head.add(o);
137         return this;
138     }
139   
140     /* ----------------------------------------------------------------- */
141     /** Set page background image.
142      * @return This Page (for chained commands)
143      */
144     public final Page setBackGroundImage(String bg)
145     {
146         attribute("background",bg);
147         return this;
148     }
149   
150     /* ----------------------------------------------------------------- */
151     /** Set page background color.
152      * @return This Page (for chained commands)
153      */
154     public final Page setBackGroundColor(String color)
155     {
156         properties.put(BgColour,color);
157         attribute("bgcolor",color);
158         return this;
159     }
160   
161     /* ----------------------------------------------------------------- */
162     /** Set the URL Base for the Page.
163      * @param target Default link target, null if none.
164      * @param href Default absolute href, null if none.
165      * @return This Page (for chained commands)
166      */
167     public final Page setBase(String target, String href)
168     {
169         base="<base " +
170             ((target!=null)?("TARGET=\""+target+"\""):"") +
171             ((href!=null)?("HREF=\""+href+"\""):"") +
172             ">";
173         return this;
174     }
175 
176     /* ----------------------------------------------------------------- */
177     /** Write the entire page by calling:<br>
178      * writeHtmlHead(out)<br>
179      * writeBodyTag(out)<br>
180      * writeElements(out)<br>
181      * writeHtmlEnd(out)
182      */
183     public void write(Writer out)
184          throws IOException
185     {
186         writeHtmlHead(out);
187         writeBodyTag(out);
188         writeElements(out);
189         writeHtmlEnd(out);
190     }
191     
192     /* ------------------------------------------------------------ */
193     /** Write HTML page head tags.
194      * Write tags &ltHTML&gt&lthead&gt .... &lt/head&gt
195      */
196     public void writeHtmlHead(Writer out)
197          throws IOException
198     {
199         if (!writtenHtmlHead)
200         {
201             writtenHtmlHead=true;
202             completeSections();
203             out.write("<html><head>");
204             String title=(String)properties.get(Title);
205             if (title!=null && title.length()>0 && !title.equals(NoTitle))
206                 out.write("<title>"+title+"</title>");
207             head.write(out);
208             out.write(base);
209             out.write("\n</head>\n");
210         }
211     }
212     
213     /* ------------------------------------------------------------ */
214     /** Write HTML page body tag.
215      * Write tags &ltBODY page attributes&gt.
216      */
217     public void writeBodyTag(Writer out)
218          throws IOException
219     {
220         if (!writtenBodyTag)
221         {
222             writtenBodyTag = true;          
223             out.write("<body "+attributes()+">\n");
224         }
225     }
226 
227     /* ------------------------------------------------------------ */
228     /** Write end BODY and end HTML tags.
229      */
230     public void writeHtmlEnd(Writer out)
231          throws IOException
232     {
233         out.write("\n</body>\n");
234         out.write("</html>\n");
235     }
236     
237     /* ------------------------------------------------------------ */
238     /** Write any body elements of the page.
239      */
240     public void writeElements(Writer out)
241          throws IOException
242     {
243         super.write(out);
244     }
245     
246     /* ------------------------------------------------------------ */
247     /** Write page section.
248      * The page is written containing only the named section.
249      * If a head and bodyTag have not been written, then they
250      * are written before the section. If endHtml is true, the
251      * end HTML tag is also written.
252      * If the named section is Content and it cannot be found,
253      * then the normal page contents are written.
254      */
255     public void write(Writer out,
256                       String section,
257                       boolean endHtml)
258          throws IOException
259     {
260         writeHtmlHead(out);
261         writeBodyTag(out);
262         Composite s = getSection(section);
263         if (s==null)
264         {
265             if (section.equals(Content))
266                 writeElements(out);
267         }
268         else
269             s.write(out);
270         if (endHtml)
271             writeHtmlEnd(out);
272         out.flush();
273     }
274     
275     /* ------------------------------------------------------------ */
276     /* Flush the current contents of the page.
277      * writeHtmlEnd() is not called and should either be
278      * explicitly called or called via an eventual call to write()
279      */
280     public void flush(Writer out)
281          throws IOException
282     {
283         writeHtmlHead(out);
284         writeBodyTag(out);
285         super.flush(out);
286     }
287     
288     /* ------------------------------------------------------------ */
289     /* Reset the page status to not written.
290      * This is useful if you want to send a page more than once.
291      */
292      public void rewind()
293     {
294         writtenHtmlHead = false;
295         writtenBodyTag = false;
296     }
297     
298     /* ------------------------------------------------------------ */
299     /** Access the page properties.  It is up to a derived Page class
300      * to interpret these properties.
301      */
302     public Dictionary properties()
303     {
304         return properties;
305     }
306 
307     /* ------------------------------------------------------------ */
308     /** Return the preferred FrameSet to be used with a specialized Page.
309      * The Frames will be named after the sections they are to
310      * contain.
311      * The default implementation returns null
312      */
313     public FrameSet frameSet()
314     {
315         return null;
316     }
317 
318     /* ------------------------------------------------------------ */
319     /** Set a composite as a named section.  Other Page users may.
320      * add to the section by calling addTo().  It is up to the section
321      * creator to add the section to the page in it appropriate position.
322      */
323     public void setSection(String section, Composite composite)
324     {
325         sections.put(section,composite);
326     }
327     
328     /* ------------------------------------------------------------ */
329     /** Set a composite as a named section and add it to the.
330      * contents of the page
331      */
332     public void addSection(String section, Composite composite)
333     {
334         sections.put(section,composite);
335         add(composite);
336     }
337     
338     /* ------------------------------------------------------------ */
339     /** Get a composite as a named section. 
340      */
341     public Composite getSection(String section)
342     {
343         return (Composite)sections.get(section);
344     }
345 
346     /* ------------------------------------------------------------ */
347     /** Add content to a named sections.  If the named section cannot.
348      * be found, the content is added to the page.
349      */
350     public void addTo(String section, Object element)
351     {
352         Composite s = (Composite)sections.get(section);
353         if (s==null)
354             add(element);
355         else
356             s.add(element);
357     }
358     
359     /* ------------------------------------------------------------ */
360     /** This call back is called just before writeHeaders() actually
361      * writes the HTML page headers. It can be implemented by a derived
362      * Page class to complete a named section after the rest of the Page
363      * has been created and appropriate properties set.
364      */
365     protected void completeSections()
366     {
367     }
368 }