View Javadoc

1   package net.sf.statcvs.pages;
2   
3   import java.text.SimpleDateFormat;
4   import java.util.Date;
5   import java.util.Set;
6   import java.util.regex.Matcher;
7   import java.util.regex.Pattern;
8   
9   import net.sf.statcvs.Messages;
10  import net.sf.statcvs.model.Author;
11  import net.sf.statcvs.model.Directory;
12  
13  /**
14   * TODO: Can we turn this into an abstract base class of MarkupHTML and MarkupXDoc?
15   * 
16   * @author Anja Jentzsch
17   * @author Richard Cyganiak (richard@cyganiak.de)
18   * @version $Id: HTML.java,v 1.19 2009/08/05 16:32:10 benoitx Exp $
19   */
20  public final class HTML {
21      public static final SimpleDateFormat OUTPUT_DATE_FORMAT = new SimpleDateFormat(Messages.getString("DATE_FORMAT"));
22      public static final SimpleDateFormat OUTPUT_DATE_TIME_FORMAT = new SimpleDateFormat(Messages.getString("DATE_TIME_FORMAT"));
23      private static final Pattern HTTP_REGEXP2 = Pattern
24              .compile("\\b(http://|https://|www.)(\\w|\\d|\\.)+(\\.|/|\\w|\\d|%|;|&|=)*\\b", Pattern.CASE_INSENSITIVE);
25  
26      //    private final static Logger LOGGER = Logger.getLogger("sf.net.statcvs");
27  
28      /**
29       * Creates a HTML representation of a hyperlink
30       * @param link URL
31       * @param linkName Name of the Link
32       * @return String HTML code of the hyperlink
33       */
34      public static String getLink(final String link, final String linkName) {
35          return getLink(link, linkName, "", "");
36      }
37  
38      /**
39       * Creates a HTML representation of a hyperlink
40       * @param link URL
41       * @param linkName Name of the Link
42       * @param prefix A prefix to be inserted before the link label; no HTML escaping is performed
43       * @param prefix A suffix to be inserted after the link label; no HTML escaping is performed
44       * @return String HTML code of the hyperlink
45       */
46      public static String getLink(final String link, final String linkName, final String prefix, final String suffix) {
47          if (link == null) {
48              return prefix + escape(linkName) + suffix;
49          }
50          return "<a href=\"" + escape(link) + "\">" + prefix + escape(linkName) + suffix + "</a>";
51      }
52  
53      /**
54       * Returns HTML code for a link to an author page
55       * @param author the author
56       * @return HTML code for the link
57       */
58      public static String getAuthorLink(final Author author) {
59          return "<a href=\"" + escape(DeveloperPageMaker.getURL(author)) + "\" class=\"author\">" + escape(author.getRealName()) + "</a>";
60      }
61  
62      /**
63       * Returns HTML code for a link to an author Id page
64       * @param author the author
65       * @return HTML code for the link
66       */
67      public static String getAuthorIdLink(final Author author) {
68          return "<a href=\"" + escape(DeveloperPageMaker.getURL(author)) + "\" class=\"author\">" + escape(author.getName()) + "</a>";
69      }
70  
71      /**
72       * Returns HTML code for a date
73       * @param date the date
74       * @return HTML code for the date
75       */
76      public static String getDate(final Date date) {
77          return "<span class=\"date\">" + OUTPUT_DATE_FORMAT.format(date) + "</span>";
78      }
79  
80      /**
81       * Returns HTML code for number of affected files
82       * @param files affected files    
83       * @return HTML code for number of affected files
84       */
85      public static String getAffectedFilesCount(final Set files) {
86          final StringBuffer sb = new StringBuffer();
87          sb.append("<span class=\"files\">" + files.size());
88          if (files.size() <= 1) {
89              sb.append(" file");
90          } else {
91              sb.append(" files");
92          }
93          sb.append("</span>");
94          return sb.toString();
95      }
96  
97      /**
98       * Returns HTML code for a date, including time
99       * @param date the date
100      * @return HTML code for the date
101      */
102     public static String getDateAndTime(final Date date) {
103         return "<span class=\"date\">" + OUTPUT_DATE_TIME_FORMAT.format(date) + "</span>";
104     }
105 
106     /**
107      * Returns HTML code for a revision number
108      * @param revisionNumber    a revision number
109      * @return  HTML code for a revision number
110      */
111     public static String getRevisionNumber(final String revisionNumber) {
112         return "<span class=\"revisionNumberOuter\">Rev.: <span class=\"revisionNumberInner\">" + revisionNumber + "</span></span>";
113     }
114 
115     /**
116      * Returns HTML code for a directory page link
117      * @param directory a directory
118      * @return HTML code for the link
119      */
120     public static String getDirectoryLink(final Directory directory) {
121         final String caption = directory.isRoot() ? "/" : directory.getPath();
122         return "<a href=\"" + escape(DirectoryPageMaker.getURL(directory)) + "\" class=\"directory\">" + escape(caption) + "</a>";
123     }
124 
125     /**
126      * Generates HTML for an icon
127      * @param iconFilename an icon filename (HTMLOutput.XXXX_ICON constants)
128      * @return HTML string
129      */
130     public static String getIcon(final String iconFilename) {
131         final StringBuffer result = new StringBuffer("<img src=\"");
132         result.append(escape(iconFilename)).append("\" width=\"");
133         result.append(ReportSuiteMaker.ICON_WIDTH).append("\" height=\"");
134         result.append(ReportSuiteMaker.ICON_HEIGHT).append("\" alt=\"\"/>");
135         return result.toString();
136     }
137 
138     /**
139      * Generates HTML for an icon
140      * @param iconFilename an icon filename (HTMLOutput.XXXX_ICON constants)
141      * @param title the title for the icon.
142      * @return HTML string
143      */
144     public static String getIcon(final String iconFilename, final String title) {
145         final StringBuffer result = new StringBuffer("<img src=\"");
146         result.append(escape(iconFilename)).append("\" width=\"");
147         result.append(ReportSuiteMaker.ICON_WIDTH).append("\" height=\"");
148         result.append(ReportSuiteMaker.ICON_HEIGHT).append("\" alt=\"").append(title).append("\"");
149         result.append(" title=\"").append(title).append("\"");
150         result.append("/>");
151         return result.toString();
152     }
153 
154     /**
155      * <p>
156      * Escapes evil characters in author's names. E.g. "#" must be escaped
157      * because for an author "my#name" a page "author_my#name.html" will be
158      * created, and you can't link to that in HTML
159      * </p>
160      *
161      * TODO: Replace everything *but* known good characters, instead of just
162      * evil ones
163      *
164      * @param authorName an author's name
165      * @return a version safe for creation of files and URLs
166      */
167     public static String escapeAuthorName(final String authorName) {
168         return authorName.replaceAll("#", "_").replaceAll("\\\\", "_");
169     }
170 
171     public static String escapeDirectoryName(String directoryName) {
172         if (!directoryName.startsWith("/")) {
173             directoryName = "/" + directoryName;
174         }
175         return directoryName.substring(0, directoryName.length() - 1).replaceAll("/", "_");
176     }
177 
178     /**
179      * Escapes HTML meta characters "&", "<", ">" and turns "\n" line breaks
180      * into HTML line breaks ("<br />");
181      * @param text some string, for example "x > 0 && y < 100"
182      * @return HTML-escaped string, for example "x &gt; 0 &amp;&amp; y &lt; 100"
183      */
184     public static String escape(final String text) {
185         String result = text.replaceAll("&", "&amp;");
186         result = result.replaceAll("<", "&lt;");
187         result = result.replaceAll(">", "&gt;");
188         result = result.replaceAll("\n", "<br />\n");
189         return result;
190     }
191 
192     /**
193      * Escapes HTML as well as " as it is not valid in URL.
194      * @param text some string, for example "x > 0 && y < 100"
195      * @return HTML-escaped string, for example "x &gt; 0 &amp;&amp; y &lt; 100"
196      */
197     public static String escapeUrl(final String text) {
198         String result = escape(text);
199         result = result.replaceAll("\"", "");
200         result = result.replaceAll(" ", "%20");
201         return result;
202     }
203 
204     /**
205      * Escapes HTML as well as " as it is not valid in URL.
206      * @param text some string, for example "x > 0 && y < 100"
207      * @return HTML-escaped string, for example "x &gt; 0 &amp;&amp; y &lt; 100"
208      */
209     public static String escapeUrlParameters(final String text) {
210         String result = escape(text);
211 //        result = result.replaceAll("\"", "");
212         result = result.replaceAll("\\%", "%25");
213         result = result.replaceAll("\\$", "%24");
214         result = result.replaceAll("\\&", "%26");
215         result = result.replaceAll("\\+", "%2B");
216         result = result.replaceAll(",", "%2C");
217         result = result.replaceAll("/", "%2F");
218         result = result.replaceAll(":", "%3A");
219         result = result.replaceAll(";", "%3B");
220         result = result.replaceAll("=", "%3D");
221         result = result.replaceAll("\\?", "%3F");
222         result = result.replaceAll("@", "%40");
223         result = result.replaceAll("\"", "%22");
224 //        result = result.replaceAll("<", "%3C");
225 //        result = result.replaceAll(">", "%3E");
226         result = result.replaceAll("#", "%23");
227         result = result.replaceAll("\\{", "%7B");
228 //        result = result.replaceAll("\\}", "%7C");
229         result = result.replaceAll("\\\\", "%5C");
230         result = result.replaceAll("\\^", "%5E");
231         result = result.replaceAll("~", "%7E");
232         result = result.replaceAll("\\[", "%5B");
233         result = result.replaceAll("\\]", "%5D");
234         result = result.replaceAll("`", "%60");
235         result = result.replaceAll(" ", "%20");
236         return result;
237     }
238 
239     /**
240      * A utility class (only static methods) should be final and have
241      * a private constructor.
242      */
243     private HTML() {
244     }
245 
246     /**
247      * From a plain text comment identify the http: and https links and create a link for them.
248      * @param plainText
249      * @author Benoit Xhenseval
250      */
251     public static String webifyLinksFromPlainText(final String plainText) {
252         final String escapedText = HTML.escape(plainText);
253         final Matcher m = HTTP_REGEXP2.matcher(escapedText);
254 
255         //        System.out.println("escaped : " + escapedText);
256         //        while (m.find()) {
257         //            System.out.println(m.group());
258         //        }
259         String res = m.replaceAll("<a href=\"$0\">$0</a>");
260         res = res.replaceAll("href=\"www.", "href=\"http://www.");
261 
262         //        System.out.println("And now: " + res);
263 
264         return res;
265     }
266 }