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 <HTML><head> .... </head> 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 <BODY page attributes>. 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 }