Coverage Report - org.apache.turbine.util.template.HtmlPageAttributes
 
Classes in this File Line Coverage Branch Coverage Complexity
HtmlPageAttributes
42%
39/91
60%
6/10
1,238
HtmlPageAttributes$LinkTag
0%
0/19
0%
0/8
1,238
 
 1  
 package org.apache.turbine.util.template;
 2  
 
 3  
 
 4  
 /*
 5  
  * Licensed to the Apache Software Foundation (ASF) under one
 6  
  * or more contributor license agreements.  See the NOTICE file
 7  
  * distributed with this work for additional information
 8  
  * regarding copyright ownership.  The ASF licenses this file
 9  
  * to you under the Apache License, Version 2.0 (the
 10  
  * "License"); you may not use this file except in compliance
 11  
  * with the License.  You may obtain a copy of the License at
 12  
  *
 13  
  *   http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing,
 16  
  * software distributed under the License is distributed on an
 17  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 18  
  * KIND, either express or implied.  See the License for the
 19  
  * specific language governing permissions and limitations
 20  
  * under the License.
 21  
  */
 22  
 
 23  
 
 24  
 import java.util.ArrayList;
 25  
 import java.util.LinkedHashMap;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 
 29  
 import org.apache.commons.lang3.StringUtils;
 30  
 import org.apache.turbine.TurbineConstants;
 31  
 import org.apache.turbine.annotation.TurbineConfiguration;
 32  
 import org.apache.turbine.services.pull.ApplicationTool;
 33  
 
 34  
 /**
 35  
  * Template context tool that can be used to set various attributes of a
 36  
  * HTML page.  This tool does not automatically make the changes in the HTML
 37  
  * page for you.  You must use this tool in your layout template to retrieve
 38  
  * the attributes.
 39  
  * <p>
 40  
  * The set/add methods are can be used from a screen template, action, screen
 41  
  * class, layour template, or anywhere else.  The get methods should be used in
 42  
  * your layout template(s) to construct the appropriate HTML tags.
 43  
  * </p>
 44  
  * 
 45  
  *<p>
 46  
  * Example usage of this tool to build the HEAD and BODY tags in your layout
 47  
  * templates:
 48  
  * </p>
 49  
  * 
 50  
  * <p>
 51  
  *  <code>
 52  
  *  ## Set defaults for all pages using this layout.  Anything set here can<br>
 53  
  *  ## be overridden in the screen template.<br>
 54  
  *  $page.setTitle("My default page title");<br>
 55  
  *  $page.setHttpEquiv("Content-Style-Type","text/css")<br>
 56  
  *  $page.addStyleSheet($content.getURI("myStyleSheet.css"))<br>
 57  
  *  $page.addScript($content.getURI("globalJavascriptCode.js"))<br>
 58  
  *  <br>
 59  
  *  ## build the HTML, HEAD, and BODY tags dynamically<br>
 60  
  *  &lt;html&gt;<br>
 61  
  *    &lt;head&gt;<br>
 62  
  *      #if( $page.Title != "" )<br>
 63  
  *      &lt;title&gt;$page.Title&lt;/title&gt;<br>
 64  
  *      #end<br>
 65  
  *      #foreach($metaTag in $page.MetaTags.keySet())<br>
 66  
  *      &lt;meta name="$metaTag" content="$page.MetaTags.get($metaTag)"&gt;<br>
 67  
  *      #end<br>
 68  
  *      #foreach($httpEquiv in $page.HttpEquivs.keySet())<br>
 69  
  *      &lt;meta http-equiv="$httpEquiv" content="$page.HttpEquivs.get($httpEquiv)"&gt;<br>
 70  
  *      #end<br>
 71  
  *      #foreach( $styleSheet in $page.StyleSheets )<br>
 72  
  *        &lt;link rel="stylesheet" href="$styleSheet.Url"<br>
 73  
  *          #if($styleSheet.Type != "" ) type="$styleSheet.Type" #end<br>
 74  
  *          #if($styleSheet.Media != "") media="$styleSheet.Media" #end<br>
 75  
  *          #if($styleSheet.Title != "") title="$styleSheet.Title" #end<br>
 76  
  *        &gt;<br>
 77  
  *      #end<br>
 78  
  *      #foreach( $script in $page.Scripts )<br>
 79  
  *        &lt;script type="text/javascript" src="$script" language="JavaScript"&gt;&lt;/script&gt;<br>
 80  
  *      #end<br>
 81  
  *    &lt;/head&gt;<br>
 82  
  *<br>
 83  
  *    ## Construct the body tag.  Iterate through the body attributes to build the opening tag<br>
 84  
  *    &lt;body<br>
 85  
  *      #foreach( $attributeName in $page.BodyAttributes.keySet() )<br>
 86  
  *        $attributeName = "$page.BodyAttributes.get($attributeName)"<br>
 87  
  *      #end<br>
 88  
  *     &gt;
 89  
  * </code>
 90  
  * </p>
 91  
  * 
 92  
  * <p>
 93  
  * Example usages of this tool in your screen templates:<br>
 94  
  *   <code>$page.addScript($content.getURI("myJavascript.js")<br>
 95  
  *   $page.setTitle("My page title")<br>
 96  
  *   $page.setHttpEquiv("refresh","5; URL=http://localhost/nextpage.html")</code>
 97  
  * </p>
 98  
  *
 99  
  * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
 100  
  * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
 101  
  * @version $Id: HtmlPageAttributes.java 1850675 2019-01-07 18:48:42Z painter $
 102  
  */
 103  
 public class HtmlPageAttributes
 104  
         implements ApplicationTool
 105  
 {
 106  
     /** The title */
 107  
     private String title;
 108  
 
 109  
     /** Body Attributes */
 110  27
     private final Map<String, String> bodyAttributes = new LinkedHashMap<String, String>();
 111  
 
 112  
     /** Script references */
 113  27
     private final List<String> scripts = new ArrayList<String>();
 114  
 
 115  
     /** External references */
 116  27
     private final List<LinkTag> linkTags = new ArrayList<LinkTag>();
 117  
 
 118  
     /** Inline styles */
 119  27
     private final List<String> styles = new ArrayList<String>();
 120  
 
 121  
     /** Meta tags for the HEAD */
 122  27
     private final Map<String, String> metaTags = new LinkedHashMap<String, String>();
 123  
 
 124  
     /** http-equiv tags */
 125  27
     private final Map<String, String> httpEquivs = new LinkedHashMap<String, String>();
 126  
 
 127  
     /** Doctype */
 128  27
     private String doctype = null;
 129  
 
 130  27
     @TurbineConfiguration( TurbineConstants.DEFAULT_HTML_DOCTYPE_ROOT_ELEMENT_KEY )
 131  
     private String defaultHtmlDoctypeRootElement = TurbineConstants.DEFAULT_HTML_DOCTYPE_ROOT_ELEMENT_DEFAULT;
 132  
 
 133  
     @TurbineConfiguration( TurbineConstants.DEFAULT_HTML_DOCTYPE_IDENTIFIER_KEY )
 134  
     private String defaultHtmlDoctypeIdentifier;
 135  
 
 136  
     @TurbineConfiguration( TurbineConstants.DEFAULT_HTML_DOCTYPE_URI_KEY )
 137  
     private String defaultHtmlDoctypeUri;
 138  
 
 139  
     /**
 140  
      * Construct a new instance
 141  
      */
 142  
     public HtmlPageAttributes()
 143  27
     {
 144  27
         init(null);
 145  27
     }
 146  
 
 147  
     /**
 148  
      * Initialize this instance.
 149  
      * (ApplicationTool method)
 150  
      *
 151  
      * @param data not used
 152  
      */
 153  
     @Override
 154  
     public void init(Object data)
 155  
     {
 156  54
         this.title = null;
 157  54
         this.bodyAttributes.clear();
 158  54
         this.scripts.clear();
 159  54
         this.linkTags.clear();
 160  54
         this.styles.clear();
 161  54
         this.metaTags.clear();
 162  54
         this.httpEquivs.clear();
 163  54
     }
 164  
 
 165  
     /**
 166  
      * Refresh method - does nothing
 167  
      */
 168  
     @Override
 169  
     public void refresh()
 170  
     {
 171  
         // empty
 172  0
     }
 173  
 
 174  
     /**
 175  
      * Set the title in the page.  This returns an empty String so
 176  
      * that the template doesn't complain about getting a null return
 177  
      * value.  Subsequent calls to this method will replace the current
 178  
      * title.
 179  
      *
 180  
      * @param title A String with the title.
 181  
      * @return a <code>HtmlPageAttributes</code> (self).
 182  
      */
 183  
     public HtmlPageAttributes setTitle(String title)
 184  
     {
 185  0
         this.title = title;
 186  0
         return this;
 187  
     }
 188  
 
 189  
     /**
 190  
      * Get the title in the page.  This returns an empty String if
 191  
      * empty so that the template doesn't complain about getting a null
 192  
      * return value.
 193  
      *
 194  
      * @return A String with the title.
 195  
      */
 196  
     public String getTitle()
 197  
     {
 198  0
         if (StringUtils.isEmpty(this.title))
 199  
         {
 200  0
             return "";
 201  
         }
 202  0
         return title;
 203  
     }
 204  
 
 205  
     /**
 206  
      * Adds an attribute to the BODY tag.
 207  
      *
 208  
      * @param name A String.
 209  
      * @param value A String.
 210  
      * @return a <code>HtmlPageAttributes</code> (self).
 211  
      */
 212  
     public HtmlPageAttributes addBodyAttribute(String name, String value)
 213  
     {
 214  0
         this.bodyAttributes.put(name, value);
 215  0
         return this;
 216  
     }
 217  
 
 218  
     /**
 219  
      * Returns the map of body attributes
 220  
      *
 221  
      * @return the map
 222  
      */
 223  
     public Map<String, String> getBodyAttributes()
 224  
     {
 225  0
         return this.bodyAttributes;
 226  
     }
 227  
 
 228  
     /**
 229  
      * Adds a script reference
 230  
      *
 231  
      * @param scriptURL the url
 232  
      * @return a <code>HtmlPageAttributes</code> (self).
 233  
      */
 234  
     public HtmlPageAttributes addScript(String scriptURL)
 235  
     {
 236  0
         this.scripts.add(scriptURL);
 237  0
         return this;
 238  
     }
 239  
 
 240  
     /**
 241  
      * Returns a collection of script URLs
 242  
      *
 243  
      * @return list of String objects containing URLs of javascript files
 244  
      * to include
 245  
      */
 246  
     public List<String> getScripts()
 247  
     {
 248  0
         return this.scripts;
 249  
     }
 250  
 
 251  
     /**
 252  
      * Adds a style sheet reference
 253  
      *
 254  
      * @param styleSheetURL URL of the style sheet
 255  
      * @return a <code>HtmlPageAttributes</code> (self).
 256  
      */
 257  
     public HtmlPageAttributes addStyleSheet(String styleSheetURL)
 258  
     {
 259  0
         addStyleSheet(styleSheetURL, "screen", null, "text/css");
 260  0
         return this;
 261  
     }
 262  
 
 263  
     /**
 264  
      * Adds a style sheet reference
 265  
      *
 266  
      * @param styleSheetURL URL of the style sheet
 267  
      * @param media name of the media
 268  
      * @param title title of the stylesheet
 269  
      * @param type content type
 270  
      * @return a <code>HtmlPageAttributes</code> (self).
 271  
      */
 272  
     public HtmlPageAttributes addStyleSheet(String styleSheetURL,
 273  
                                             String media, String title, String type)
 274  
     {
 275  0
         LinkTag ss = new LinkTag("stylesheet", styleSheetURL);
 276  0
         ss.setMedia(media);
 277  0
         ss.setTitle(title);
 278  0
         ss.setType(type);
 279  0
         this.linkTags.add(ss);
 280  0
         return this;
 281  
     }
 282  
 
 283  
     /**
 284  
      * Adds a generic external reference
 285  
      *
 286  
      * @param relation type of the reference (prev, next, first, last, top, etc.)
 287  
      * @param linkURL URL of the reference
 288  
      * @return a <code>HtmlPageAttributes</code> (self).
 289  
      */
 290  
     public HtmlPageAttributes addLink(String relation, String linkURL)
 291  
     {
 292  0
         return addLink(relation, linkURL, null, null);
 293  
     }
 294  
 
 295  
     /**
 296  
      * Adds a generic external reference
 297  
      *
 298  
      * @param relation type of the reference (prev, next, first, last, top, etc.)
 299  
      * @param linkURL URL of the reference
 300  
      * @param title title of the reference
 301  
      * @return a <code>HtmlPageAttributes</code> (self).
 302  
      */
 303  
     public HtmlPageAttributes addLink(String relation, String linkURL, String title)
 304  
     {
 305  0
         return addLink(relation, linkURL, title, null);
 306  
     }
 307  
 
 308  
     /**
 309  
      * Adds a generic external reference
 310  
      *
 311  
      * @param relation type of the reference (prev, next, first, last, top, etc.)
 312  
      * @param linkURL URL of the reference
 313  
      * @param title title of the reference
 314  
      * @param type content type
 315  
      * @return a <code>HtmlPageAttributes</code> (self).
 316  
      */
 317  
     public HtmlPageAttributes addLink(String relation, String linkURL, String title,
 318  
                                         String type)
 319  
     {
 320  0
         LinkTag ss = new LinkTag(relation, linkURL);
 321  0
         ss.setTitle(title);
 322  0
         ss.setType(type);
 323  0
         this.linkTags.add(ss);
 324  0
         return this;
 325  
     }
 326  
 
 327  
     /**
 328  
      * Returns a collection of link URLs
 329  
      *
 330  
      * @return list LinkTag objects (inner class)
 331  
      */
 332  
     public List<LinkTag> getLinks()
 333  
     {
 334  0
         return this.linkTags;
 335  
     }
 336  
 
 337  
     /**
 338  
      * Adds a STYLE element to the HEAD of the page with the provided content.
 339  
      *
 340  
      * @param styleText The contents of the <code>style</code> tag.
 341  
      * @return a <code>HtmlPageAttributes</code> (self).
 342  
      */
 343  
     public HtmlPageAttributes addStyle(String styleText)
 344  
     {
 345  0
         this.styles.add(styleText);
 346  0
         return this;
 347  
     }
 348  
 
 349  
     /**
 350  
      * Returns a collection of styles
 351  
      *
 352  
      * @return list of String objects containing the contents of style tags
 353  
      */
 354  
     public List<String> getStyles()
 355  
     {
 356  0
         return this.styles;
 357  
     }
 358  
 
 359  
     /**
 360  
      * Set a keywords META tag in the HEAD of the page.
 361  
      *
 362  
      * @param keywords A String.
 363  
      * @return a <code>HtmlPageAttributes</code> (self).
 364  
      */
 365  
     public HtmlPageAttributes setKeywords(String keywords)
 366  
     {
 367  0
         this.metaTags.put("keywords", keywords);
 368  0
         return this;
 369  
     }
 370  
 
 371  
     /**
 372  
      * Sets a HttpEquiv META tag in the HEAD of the page, usage:
 373  
      * <br><code>setHttpEquiv("refresh", "5; URL=http://localhost/nextpage.html")</code>
 374  
      * <br><code>setHttpEquiv("Expires", "Tue, 20 Aug 1996 14:25:27 GMT")</code>
 375  
      *
 376  
      * @param httpEquiv The value to use for the http-equiv attribute.
 377  
      * @param content   The text for the content attribute of the meta tag.
 378  
      * @return a <code>HtmlPageAttributes</code> (self).
 379  
      */
 380  
     public HtmlPageAttributes setHttpEquiv(String httpEquiv, String content)
 381  
     {
 382  0
         this.httpEquivs.put(httpEquiv, content);
 383  0
         return this;
 384  
     }
 385  
 
 386  
     /**
 387  
      * Add a description META tag to the HEAD of the page.
 388  
      *
 389  
      * @param description A String.
 390  
      * @return a <code>HtmlPageAttributes</code> (self).
 391  
      */
 392  
     public HtmlPageAttributes setDescription(String description)
 393  
     {
 394  0
         this.metaTags.put("description", description);
 395  0
         return this;
 396  
     }
 397  
 
 398  
     /**
 399  
      * Set the background image for the BODY tag.
 400  
      *
 401  
      * @param url A String.
 402  
      * @return a <code>HtmlPageAttributes</code> (self).
 403  
      */
 404  
     public HtmlPageAttributes setBackground(String url)
 405  
     {
 406  0
         this.bodyAttributes.put("background", url);
 407  0
         return this;
 408  
     }
 409  
 
 410  
     /**
 411  
      * Set the background color for the BODY tag.  You can use either
 412  
      * color names or color values (e.g. "white" or "#ffffff" or
 413  
      * "ffffff").
 414  
      *
 415  
      * @param color A String.
 416  
      * @return a <code>HtmlPageAttributes</code> (self).
 417  
      */
 418  
     public HtmlPageAttributes setBgColor(String color)
 419  
     {
 420  0
         this.bodyAttributes.put("BGCOLOR", color);
 421  0
         return this;
 422  
     }
 423  
 
 424  
     /**
 425  
      * Set the text color for the BODY tag.  You can use either color
 426  
      * names or color values (e.g. "white" or "#ffffff" or "ffffff").
 427  
      *
 428  
      * @param color A String.
 429  
      * @return a <code>HtmlPageAttributes</code> (self).
 430  
      */
 431  
     public HtmlPageAttributes setTextColor(String color)
 432  
     {
 433  0
         this.bodyAttributes.put("TEXT", color);
 434  0
         return this;
 435  
     }
 436  
 
 437  
     /**
 438  
      * Set the link color for the BODY tag.  You can use either color
 439  
      * names or color values (e.g. "white" or "#ffffff" or "ffffff").
 440  
      *
 441  
      * @param color A String.
 442  
      * @return a <code>HtmlPageAttributes</code> (self).
 443  
      */
 444  
     public HtmlPageAttributes setLinkColor(String color)
 445  
     {
 446  0
         this.bodyAttributes.put("LINK", color);
 447  0
         return this;
 448  
     }
 449  
 
 450  
     /**
 451  
      * Set the visited link color for the BODY tag.
 452  
      *
 453  
      * @param color A String.
 454  
      * @return a <code>HtmlPageAttributes</code> (self).
 455  
      */
 456  
     public HtmlPageAttributes setVlinkColor(String color)
 457  
     {
 458  0
         this.bodyAttributes.put("VLINK", color);
 459  0
         return this;
 460  
     }
 461  
 
 462  
     /**
 463  
      * Set the active link color for the BODY tag.
 464  
      *
 465  
      * @param color A String.
 466  
      * @return a <code>HtmlPageAttributes</code> (self).
 467  
      */
 468  
     public HtmlPageAttributes setAlinkColor(String color)
 469  
     {
 470  0
         this.bodyAttributes.put("ALINK", color);
 471  0
         return this;
 472  
     }
 473  
 
 474  
     /**
 475  
      * Gets the map of http equiv tags
 476  
      *
 477  
      * @return Map of http equiv names to the contents
 478  
      */
 479  
     public Map<String, String> getHttpEquivs()
 480  
     {
 481  0
         return this.httpEquivs;
 482  
     }
 483  
 
 484  
     /**
 485  
      * Gets the map of meta tags
 486  
      *
 487  
      * @return Map of http equiv names to the contents
 488  
      */
 489  
     public Map<String, String> getMetaTags()
 490  
     {
 491  0
         return this.metaTags;
 492  
     }
 493  
 
 494  
     /**
 495  
      * A dummy toString method that returns an empty string.
 496  
      *
 497  
      * @return An empty String ("").
 498  
      */
 499  
     @Override
 500  
     public String toString()
 501  
     {
 502  81
         return "";
 503  
     }
 504  
 
 505  
     /**
 506  
      * Helper class to hold data about a &lt;link ... /&gt; html header tag
 507  
      */
 508  
     public static class LinkTag
 509  
     {
 510  
         private String relation;
 511  
         private String url;
 512  
         private String title;
 513  
         private String media;
 514  
         private String type;
 515  
 
 516  
         /**
 517  
          * Constructor requiring the URL and relation to be set
 518  
          *
 519  
          * @param relation Relation type the external link such as prev, next,
 520  
          *        stylesheet, shortcut icon
 521  
          * @param url URL of the external link
 522  
          */
 523  
         public LinkTag(String relation, String url)
 524  0
         {
 525  0
             setRelation(relation);
 526  0
             setUrl(url);
 527  0
         }
 528  
 
 529  
         /**
 530  
          * Gets the content type of the style sheet
 531  
          *
 532  
          * @return content type
 533  
          */
 534  
         public String getType()
 535  
         {
 536  0
             return (StringUtils.isEmpty(type) ? "" : type);
 537  
         }
 538  
 
 539  
         /**
 540  
          * Sets the content type of the style sheet
 541  
          *
 542  
          * @param type content type
 543  
          */
 544  
         public void setType(String type)
 545  
         {
 546  0
             this.type = type;
 547  0
         }
 548  
 
 549  
         /**
 550  
          * @return String representation of the URL
 551  
          */
 552  
         public String getUrl()
 553  
         {
 554  0
             return url;
 555  
         }
 556  
 
 557  
         /**
 558  
          * Sets the URL of the external style sheet
 559  
          *
 560  
          * @param url The URL of the stylesheet
 561  
          */
 562  
         private void setUrl(String url)
 563  
         {
 564  0
             this.url = url;
 565  0
         }
 566  
 
 567  
         /**
 568  
          * Gets the title of the style sheet
 569  
          *
 570  
          * @return title
 571  
          */
 572  
         public String getTitle()
 573  
         {
 574  0
             return (StringUtils.isEmpty(title) ? "" : title);
 575  
         }
 576  
 
 577  
         /**
 578  
          * Sets the title of the stylesheet
 579  
          *
 580  
          * @param title of the stylesheet
 581  
          */
 582  
         public void setTitle(String title)
 583  
         {
 584  0
             this.title = title;
 585  0
         }
 586  
 
 587  
         /**
 588  
          * Gets the media for which the stylesheet should be applied.
 589  
          *
 590  
          * @return name of the media
 591  
          */
 592  
         public String getMedia()
 593  
         {
 594  0
             return (StringUtils.isEmpty(media) ? "" : media);
 595  
         }
 596  
 
 597  
         /**
 598  
          * Sets the media for which the stylesheet should be applied.
 599  
          *
 600  
          * @param media name of the media
 601  
          */
 602  
         public void setMedia(String media)
 603  
         {
 604  0
             this.media = media;
 605  0
         }
 606  
 
 607  
         /**
 608  
          * Gets the relation type of the tag.
 609  
          *
 610  
          * @return name of the relation
 611  
          */
 612  
         public String getRelation()
 613  
         {
 614  0
             return (StringUtils.isEmpty(relation) ? "" : relation);
 615  
         }
 616  
 
 617  
         /**
 618  
          * Sets the relation type of the tag.
 619  
          *
 620  
          * @param relation name of the relation
 621  
          */
 622  
         public void setRelation(String relation)
 623  
         {
 624  0
             this.relation = relation;
 625  0
         }
 626  
     }
 627  
 
 628  
     /**
 629  
      * Retrieve the default Doctype as configured by the
 630  
      * TurbineResources.peoperties
 631  
      * default.doctype.root.element, default.doctype.identifier and
 632  
      * default.doctype.url properties (defaults are "HTML",
 633  
      * "-//W3C//DTD HTML 4.01 Transitional//EN" and
 634  
      * "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd" respectively).
 635  
      *
 636  
      * @return the DOCTYPE tag constructed from the properties in
 637  
      * TurbineResources.properties.
 638  
      */
 639  
     public String getDefaultDoctype()
 640  
     {
 641  3
         if (doctype == null)
 642  
         {
 643  3
             String tag = defaultHtmlDoctypeRootElement;
 644  
 
 645  3
             if (StringUtils.isEmpty(tag))
 646  
             {
 647  0
                 doctype = "";
 648  
             }
 649  
             else
 650  
             {
 651  3
                 doctype = getDoctype(tag, defaultHtmlDoctypeIdentifier, defaultHtmlDoctypeUri);
 652  
             }
 653  
         }
 654  
 
 655  3
         return doctype;
 656  
     }
 657  
 
 658  
     /**
 659  
      * Build the doctype element.
 660  
      *
 661  
      * @param tag the tag whose DTD is being declared.
 662  
      * @param identifier the identifier for the doctype declaration.
 663  
      * @param uri the uri for the doctype declaration.
 664  
      * @return the doctype.
 665  
      */
 666  
     public String getDoctype(String tag, String identifier, String uri)
 667  
     {
 668  15
         StringBuilder doctypeBuf = new StringBuilder("<!DOCTYPE ");
 669  15
         doctypeBuf.append(tag);
 670  
 
 671  15
         if (StringUtils.isNotEmpty(identifier))
 672  
         {
 673  3
             doctypeBuf.append(" PUBLIC \"");
 674  3
             doctypeBuf.append(identifier);
 675  3
             doctypeBuf.append("\" \"");
 676  3
             doctypeBuf.append(uri);
 677  3
             doctypeBuf.append('"');
 678  
         }
 679  12
         else if (StringUtils.isNotEmpty(uri))
 680  
         {
 681  3
             doctypeBuf.append(" SYSTEM \"");
 682  3
             doctypeBuf.append(uri);
 683  3
             doctypeBuf.append('"');
 684  
         }
 685  
 
 686  15
         doctypeBuf.append('>');
 687  
 
 688  15
         return doctypeBuf.toString();
 689  
     }
 690  
 }