pre-compile delete forbidden tag rexexp as well as add deleteTableTags method.. get...
[mir.git] / source / mir / misc / StringUtil.java
1 /*
2  * Copyright (C) 2001, 2002  The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package  mir.misc;
33
34 import  java.io.*;
35 import  java.lang.*;
36 import  java.util.*;
37 import  java.text.NumberFormat;
38 import  gnu.regexp.*;
39
40 /**
41  * Statische Hilfsmethoden zur Stringbehandlung
42  *
43  * @version $Id: StringUtil.java,v 1.31 2002/12/23 03:15:32 mh Exp $
44  * @author mir-coders group
45  *
46  */
47 public final class StringUtil {
48
49   private static RE   re_newline2br, re_brbr2p, re_mail, re_url, re_tags,
50                       re_tables, re_forbiddenTags;
51
52   private StringUtil() { }  // this avoids contruction
53
54   static {
55     try {
56       //precompile regex
57       re_newline2br = new RE("(\r?\n){1}");
58       re_brbr2p     = new RE("(<br>\r?\n<br>){1,}");
59       re_mail       = new RE("([a-zA-Z0-9_.-]+)@([a-zA-Z0-9_-]+)\\.([a-zA-Z0-9_.-]+)");
60       re_url        = new RE("((https://)|(http://)|(ftp://)){1}([a-zA-Z0-9_-]+).([a-zA-Z0-9_.:-]+)/?([^ \t\r\n<>\\)\\]]+[^ \t\r\n.,<>\\)\\]])");
61       re_tags       = new RE("<[^>]*>",RE.REG_ICASE);
62                         re_tables = new RE("<[ \t\r\n/]*(table|td|tr)[ \t\r\n]*>",RE.REG_ICASE);
63                         re_forbiddenTags = new RE("<[ \t\r\n/]*(body|head|script)[ \t\r\n]*>",RE.REG_ICASE);
64     }
65     catch (REException e){
66       System.err.println("FATAL: StringUtil: could not precompile REGEX: "+e.toString());
67     }
68   }
69
70   /**
71    * Formats a number with the specified minimum and maximum number of digits.
72    **/
73   public static synchronized String zeroPaddingNumber(long value, int minDigits,
74       int maxDigits)
75   {
76     NumberFormat numberFormat = NumberFormat.getInstance();
77     numberFormat.setMinimumIntegerDigits(minDigits);
78     numberFormat.setMaximumIntegerDigits(maxDigits);
79     return numberFormat.format(value);
80   }
81
82   /**
83    * Wandelt Datum in einen 8-ziffrigen String um (yyyymmdd)
84    * @param theDate
85    * @return 8-ziffriger String (yyyymmdd)
86    */
87
88   public static final String date2webdbDate (GregorianCalendar theDate) {
89     StringBuffer webdbDate = new StringBuffer();
90     webdbDate.append(String.valueOf(theDate.get(Calendar.YEAR)));
91     webdbDate.append(pad2(theDate.get(Calendar.MONTH) + 1));
92     webdbDate.append(pad2(theDate.get(Calendar.DATE)));
93     return  webdbDate.toString();
94   }
95
96   /**
97    * Wandelt Calendar in einen 12-ziffrigen String um (yyyymmddhhmm)
98    * @param theDate
99    * @return 12-ziffriger String (yyyymmdd)
100    */
101
102   public static final String date2webdbDateTime (GregorianCalendar theDate) {
103     StringBuffer webdbDate = new StringBuffer();
104     webdbDate.append(String.valueOf(theDate.get(Calendar.YEAR)));
105     webdbDate.append(pad2(theDate.get(Calendar.MONTH) + 1));
106     webdbDate.append(pad2(theDate.get(Calendar.DATE)));
107     webdbDate.append(pad2(theDate.get(Calendar.HOUR)));
108     webdbDate.append(pad2(theDate.get(Calendar.MINUTE)));
109     return  webdbDate.toString();
110   }
111
112   /**
113    * Return a http://www.w3.org/TR/NOTE-datetime formatted date (yyyy-mm-ddThh:mm:ssTZ)
114    * @param theDate
115    * @return w3approved datetime
116    */
117
118   public static final String date2w3DateTime (GregorianCalendar theDate) {
119     StringBuffer webdbDate = new StringBuffer();
120     webdbDate.append(String.valueOf(theDate.get(Calendar.YEAR)));
121     webdbDate.append("-");
122     webdbDate.append(pad2(theDate.get(Calendar.MONTH) + 1));
123     webdbDate.append("-");
124     webdbDate.append(pad2(theDate.get(Calendar.DATE)));
125     webdbDate.append("T");
126     webdbDate.append(pad2(theDate.get(Calendar.HOUR)));
127     webdbDate.append(":");
128     webdbDate.append(pad2(theDate.get(Calendar.MINUTE)));
129     webdbDate.append(":");
130     webdbDate.append(pad2(theDate.get(Calendar.SECOND)));
131     //assumes you are an hour-multiple away from UTC....
132     int offset=(theDate.get(Calendar.ZONE_OFFSET)/(60*60*1000));
133     if (offset < 0){
134       webdbDate.append("-");
135     }
136     else{
137       webdbDate.append("+");
138     }
139     webdbDate.append(pad2(Math.abs(offset)));
140     webdbDate.append(":00");
141     return  webdbDate.toString();
142   }
143
144   /**
145    * wandelt Calendar in dd.mm.yyyy / hh.mm um
146    * @param theDate
147    * @return String mit (dd.mm.yyyy / hh.mm um)
148    */
149   public static String date2readableDateTime (GregorianCalendar theDate) {
150     String readable = "";
151     int hour;
152     readable += pad2(theDate.get(Calendar.DATE));
153     readable += "." + pad2(theDate.get(Calendar.MONTH) + 1);
154     readable += "." + String.valueOf(theDate.get(Calendar.YEAR));
155     hour = theDate.get(Calendar.HOUR);
156     if (theDate.get(Calendar.AM_PM) == Calendar.PM)
157       hour += 12;
158     readable += " / " + pad2(hour);
159     readable += ":" + pad2(theDate.get(Calendar.MINUTE));
160     return  readable;
161   }
162
163   /**
164   *  deleteForbiddenTags
165   *  this method deletes all <script>, <body> and <head>-tags
166   */
167   public static final String deleteForbiddenTags(String haystack) {
168     return re_forbiddenTags.substituteAll(haystack,"");
169   }
170
171         /**
172          *  deleteHTMLTableTags
173          *  this method deletes all <table>, <tr> and <td>-tags
174          */
175   public static final String deleteHTMLTableTags(String haystack) {
176     return re_tables.substituteAll(haystack,"");
177   }
178
179   /**
180    * wandelt eine Datum in einen 8-buchstabigen String, der durch <code>/</code>
181    * getrennt ist.
182    *
183    * @param webdbDate
184    * @return String mit <code>/yyyy/mm/dd</code>
185    */
186   public static final String webdbDate2path (String webdbDate) {
187     StringBuffer path = new StringBuffer();
188     path.append("/").append(webdbDate.substring(0, 4));
189     path.append("/").append(webdbDate.substring(4, 6));
190     path.append("/");
191     //who did this?
192     //path.append("/").append(webdbDate.substring(6, 8));
193     return  path.toString();
194   }
195
196   /**
197    * converts string from format: yyyy-mm-dd__hh:mm:ss.d
198    * to dd.mm.yyyy hh:mm
199    */
200   public static String dateToReadableDate(String date) {
201     StringBuffer returnDate = new StringBuffer();
202     if (date!=null) {
203
204       returnDate.append(date.substring(8,10)).append('.');
205       returnDate.append(date.substring(5,7)).append('.');
206       returnDate.append(date.substring(0,4)).append(' ');
207       returnDate.append(date.substring(11,16));
208     }
209     return returnDate.toString();
210   }
211
212   /**
213    * converts string from format: yyyy-mm-dd__hh:mm:ss.d
214    * to yyyy
215    */
216   public static String dateToYear (String date) {
217     StringBuffer returnDate = new StringBuffer();
218     if (date!=null) {
219
220       returnDate.append(date.substring(0,4));
221     }
222     return returnDate.toString();
223   }
224
225   /**
226    * converts string from format: yyyy-mm-dd__hh:mm:ss.d
227    * to [m]m
228    */
229   public static String dateToMonth (String date) {
230     StringBuffer returnDate = new StringBuffer();
231     if (date!=null) {
232       if (!date.substring(5,6).equalsIgnoreCase("0")) returnDate.append(date.substring(5,7));
233       else returnDate.append(date.substring(6,7));
234     }
235     return returnDate.toString();
236   }
237
238   /**
239    * converts string from format: yyyy-mm-dd__hh:mm:ss.d
240    * to [d]d
241    */
242   public static String dateToDayOfMonth (String date) {
243     StringBuffer returnDate = new StringBuffer();
244     if (date!=null) {
245       if (!date.substring(8,9).equalsIgnoreCase("0")) returnDate.append(date.substring(8,10));
246       else returnDate.append(date.substring(9,10));
247     }
248     return returnDate.toString();
249   }
250
251   /**
252    * converts string from format: yyyy-mm-dd__hh:mm:ss.d
253    * to hh:mm
254    */
255   public static String dateToTime (String date) {
256     StringBuffer returnDate = new StringBuffer();
257     if (date!=null) {
258       returnDate.append(date.substring(11,16));
259     }
260     return returnDate.toString();
261   }
262
263   /**
264    * Splits the provided CSV text into a list. stolen wholesale from
265    * from Jakarta Turbine StrinUtils.java -mh
266    *
267    * @param text      The CSV list of values to split apart.
268    * @param separator The separator character.
269    * @return          The list of values.
270    */
271   public static String[] split(String text, String separator)
272   {
273     StringTokenizer st = new StringTokenizer(text, separator);
274     String[] values = new String[st.countTokens()];
275     int pos = 0;
276     while (st.hasMoreTokens())
277     {
278       values[pos++] = st.nextToken();
279     }
280     return values;
281   }
282
283   /**
284    * Joins the elements of the provided array into a single string
285    * containing a list of CSV elements. Stolen wholesale from Jakarta
286    * Turbine StringUtils.java. -mh
287    *
288    * @param list      The list of values to join together.
289    * @param separator The separator character.
290    * @return          The CSV text.
291    */
292   public static String join(String[] list, String separator)
293   {
294     StringBuffer csv = new StringBuffer();
295     for (int i = 0; i < list.length; i++)
296     {
297       if (i > 0)
298       {
299       csv.append(separator);
300     }
301     csv.append(list[i]);
302     }
303     return csv.toString();
304   }
305
306   /**
307    * Wandelet String in byte[] um.
308    * @param s
309    * @return byte[] des String
310    */
311
312   public static byte[] stringToBytes(String s) {
313     String crlf = System.getProperty("line.separator");
314     if (!crlf.equals("\n"))
315       s = replace(s, "\n", crlf);
316     // byte[] buf = new byte[s.length()];
317     byte[] buf = s.getBytes();
318     return buf;
319   }
320
321   /**
322    * Ersetzt in String <code>s</code> das <code>pattern</code> durch <code>substitute</code>
323    * @param s
324    * @param pattern
325    * @param substitute
326    * @return String mit den Ersetzungen
327    */
328   public static String replace(String s, String pattern, String substitute) {
329     int i = 0, pLen = pattern.length(), sLen = substitute.length();
330     StringBuffer buf = new StringBuffer(s.length());
331     while (true) {
332       int j = s.indexOf(pattern, i);
333       if (j < 0) {
334         buf.append(s.substring(i));
335         break;
336       } else {
337         buf.append(s.substring(i, j));
338         buf.append(substitute);
339         i = j+pLen;
340       }
341     }
342     return buf.toString();
343   }
344
345   /**
346    * Ersetzt in String <code>s</code> das Regexp <code>pattern</code> durch <code>substitute</code>
347    * @param s
348    * @param pattern
349    * @param substitute
350    * @return String mit den Ersetzungen
351    */
352   public static String regexpReplace(String haystack, String pattern, String substitute) {
353     try {
354       RE regex = new RE(pattern);
355       return regex.substituteAll(haystack,substitute);
356     } catch(REException ex){
357       return null;
358     }
359   }
360
361
362
363
364   /**
365    * Fügt einen Separator an den Pfad an
366    * @param path
367    * @return Pfad mit Separator am Ende
368    */
369   public static final String addSeparator (String path) {
370     return  path.length() == 0 || path.endsWith(File.separator) ? path : path
371                           + File.separatorChar;
372   }
373
374   /**
375    * Fügt ein <code>/</code> ans ende des Strings and
376    * @param path
377    * @return Pfad mit <code>/</code> am Ende
378    */
379   public static final String addSlash (String path) {
380     return  path.length() == 0 || path.endsWith("/") ? path : path + '/';
381   }
382
383   /**
384    * Löscht <code>/</code> am Ende des Strings, falls vorhanden
385    * @param path
386    * @return String ohne <code>/</code> am Ende
387    */
388   public static final String removeSlash (String path) {
389     return  path.length() > 1 && path.endsWith("/") ? path.substring(0, path.length()
390         - 1) : path;
391   }
392
393   /**
394    * Checks to see if the path is absolute by looking for a leading file
395    * separater
396    * @param path
397    * @return
398    */
399   public static boolean isAbsolutePath (String path) {
400     return  path.startsWith(File.separator);
401   }
402
403   /**
404    * Löscht Slash am Anfang des Strings
405    * @param path
406    * @return
407    */
408   public static String removeFirstSlash (String path) {
409     return  path.startsWith("/") ? path.substring(1) : path;
410   }
411
412   /**
413    * formatiert eine Zahl (0-99) zweistellig (z.B. 5 -> 05)
414    * @return zwistellige Zahl
415    */
416   public static String pad2 (int number) {
417     return  number < 10 ? "0" + number : String.valueOf(number);
418   }
419
420   /**
421    * formatiert eine Zahl (0-999) dreistellig (z.B. 7 -> 007)
422    *
423    * @return 3-stellige Zahl
424    */
425   public static String pad3 (int number) {
426     return  number < 10 ? "00" + number : number < 100 ? "0" + number : String.valueOf(number);
427   }
428
429   /**
430    * Konvertiert Unix-Linefeeds in Win-Linefeeds
431    * @param s
432    * @return Konvertierter String
433    */
434   public static String unixLineFeedsToWin(String s) {
435     int i = -1;
436     while (true) {
437       i = s.indexOf('\n', i+1);
438       if (i < 0) break;
439       if ((i == 0 || s.charAt(i-1) != '\r') &&
440           (i == s.length()-1 || s.charAt(i+1) != '\r')) {
441         s = s.substring(0, i)+'\r'+s.substring(i);
442         i++;
443       }
444     }
445     return s;
446   }
447
448  /**
449   * schnellere Variante der String.toLowerCase()-Routine
450   *
451   * @return String in Kleinbuchsten
452   */
453   public static String toLowerCase(String s) {
454     int l = s.length();
455     char[] a = new char[l];
456     for (int i = 0; i < l; i++)
457       a[i] = Character.toLowerCase(s.charAt(i));
458     return new String(a);
459   }
460
461   /**
462    * Findet <code>element</code> im String-Array <code>array</code>
463    * @param array
464    * @param element
465    * @return Fundstelle als int oder -1
466    */
467   public static int indexOf(String[] array, String element) {
468     if (array != null)
469       for (int i = 0; i < array.length; i++)
470         if (array[i].equals(element))
471           return i;
472     return -1;
473   }
474
475   /**
476    * Testet auf Vorkommen von <code>element</code> in <code>array</code>
477    * @param array String-Array
478    * @param element
479    * @return true wenn <code>element</code> vorkommt, sonst false
480    */
481   public static boolean contains(String[] array, String element) {
482     return indexOf(array, element) >= 0;
483   }
484
485   /**
486    * Ermittelt CRC-Prüfsumme von String <code>s</code>
487    * @param s
488    * @return CRC-Prüfsumme
489    */
490   public static int getCRC(String s) {
491     int h = 0;
492     char val[] = s.toCharArray();
493     int len = val.length;
494
495     for (int i = 0 ; i < len; i++) {
496       h &= 0x7fffffff;
497       h = (((h >> 30) | (h << 1)) ^ (val[i]+i));
498     }
499
500     return (h << 8) | (len & 0xff);
501   }
502
503   /**
504    * Liefert Default-Wert def zurück, wenn String <code>s</code>
505    * kein Integer ist.
506    *
507    * @param s
508    * @param def
509    * @return geparster int aus s oder def
510    */
511   public static int parseInt(String s, int def) {
512     if (s == null) return def;
513     try {
514       return Integer.parseInt(s);
515     } catch (NumberFormatException e) {
516       return def;
517     }
518   }
519
520   /**
521    * Liefert Defaultwert def zurück, wenn s nicht zu einem float geparsed werden kann.
522    * @param s
523    * @param def
524    * @return geparster float oder def
525    */
526   public static float parseFloat(String s, float def) {
527     if (s == null) return def;
528     try {
529       return new Float(s).floatValue();
530     } catch (NumberFormatException e) {
531       return def;
532     }
533   }
534
535   /**
536    * Findet Ende eines Satzes in String <code>text</code>
537    * @param text
538    * @param startIndex
539    * @return index des Satzendes, oder -1
540    */
541   public static int findEndOfSentence(String text, int startIndex) {
542     while (true) {
543       int i = text.indexOf('.', startIndex);
544       if (i < 0) return -1;
545       if (i > 0 && !Character.isDigit(text.charAt(i-1)) &&
546           (i+1 >= text.length()
547           || text.charAt(i+1) == ' '
548           || text.charAt(i+1) == '\n'
549           || text.charAt(i+1) == '\t'))
550         return i+1;
551       startIndex = i+1;
552     }
553   }
554
555   /**
556    * Findet Wortende in String <code>text</code> ab <code>startIndex</code>
557    * @param text
558    * @param startIndex
559    * @return Index des Wortendes, oder -1
560    */
561   public static int findEndOfWord(String text, int startIndex) {
562     int i = text.indexOf(' ', startIndex),
563     j = text.indexOf('\n', startIndex);
564     if (i < 0) i = text.length();
565     if (j < 0) j = text.length();
566     return Math.min(i, j);
567   }
568
569
570   /**
571    *  convertNewline2P ist eine regex-routine zum umwandeln von 2 oder mehr newlines (\n)
572    *  in den html-tag <p>
573    *  nur sinnvoll, wenn text nicht im html-format eingegeben
574    */
575   public static String convertNewline2P(String haystack) {
576     return re_brbr2p.substituteAll(haystack,"\n</p><p>");
577   }
578
579   /**
580    *  convertNewline2Break ist eine regex-routine zum umwandeln von 1 newline (\n)
581    *  in den html-tag <br>
582    *  nur sinnvoll, wenn text nicht im html-format eingegeben
583    */
584   public static String convertNewline2Break(String haystack) {
585     return re_newline2br.substituteAll(haystack,"$0<br />");
586   }
587
588   /**
589    *  createMailLinks wandelt text im email-adressenformat
590    *  in einen klickbaren link um
591    *  nur sinnvoll, wenn text nicht im html-format eingegeben
592    */
593   public static String createMailLinks(String haystack) {
594     return re_mail.substituteAll(haystack,"<a href=\"mailto:$0\">$0</a>");
595   }
596
597
598   /**
599    *  createMailLinks wandelt text im email-adressenformat
600    *  in einen klickbaren link um
601    *  nur sinnvoll, wenn text nicht im html-format eingegeben
602    */
603   public static String createMailLinks(String haystack, String imageRoot, String mailImage) {
604     return re_mail.substituteAll(haystack,"<img src=\""+imageRoot+"/"+mailImage+"\" border=\"0\"/>&#160;<a href=\"mailto:$0\">$0</a>");
605   }
606
607
608   /**
609    *  createURLLinks wandelt text im url-format
610    *  in einen klickbaren link um
611    *  nur sinnvoll, wenn text nicht im html-format eingegeben
612    */
613   public static String createURLLinks(String haystack) {
614     return re_url.substituteAll(haystack,"<a href=\"$0\">$0</a>");
615   }
616
617   /**
618    * this routine takes text in url format and makes
619    * a clickaeble "<href>" link removing any "illegal" html tags
620    * @param haystack, the url
621    * @param title, the href link text
622    * @param imagRoot, the place to find icons
623    * @param extImage, the url of the icon to show next to the link
624    * @return a String containing the url
625    */
626   public static String createURLLinks(String haystack, String title, String imageRoot,String extImage) {
627     if (title == null) {
628       return re_url.substituteAll(haystack,"<img src=\""+imageRoot+"/"+extImage+"\" border=\"0\"/>&#160;<a href=\"$0\">$0</a>");
629     } else {
630       title = removeHTMLTags(title);
631       return re_url.substituteAll(haystack,"<img src=\""+imageRoot+"/"+extImage+"\" border=\"0\"/>&#160;<a href=\"$0\">"+title+"</a>");
632     }
633   }
634
635   /**
636    * this routine takes text in url format and makes
637    * a clickaeble "<href>" link removing any "illegal" html tags
638    * @param haystack, the url
639    * @param imageRoot, the place to find icons
640    * @param extImage, the url of the icon to show next to the link
641    * @param intImage, unused
642    * @return a String containing the url
643    */
644   public static String createURLLinks(String haystack, String title, String imageRoot,String extImage,String intImage) {
645     return createURLLinks(haystack, title, imageRoot, extImage);
646   }
647
648   /**
649    * this method deletes all html tags
650    */
651   public static final String removeHTMLTags(String haystack){
652     return re_tags.substituteAll(haystack,"");
653   }
654
655   /**
656    * this method deletes all but the approved tags html tags
657    * it also deletes approved tags which contain malicious-looking attributes and doesn't work at all
658    */
659   public static String approveHTMLTags(String haystack){
660     try {
661       String approvedTags="a|img|h1|h2|h3|h4|h5|h6|br|b|i|strong|p";
662       String badAttributes="onAbort|onBlur|onChange|onClick|onDblClick|onDragDrop|onError|onFocus|onKeyDown|onKeyPress|onKeyUp|onLoad|onMouseDown|onMouseMove|onMouseOut|onMouseOver|onMouseUp|onMove|onReset|onResize|onSelect|onSubmit|onUnload";
663       String approvedProtocols="rtsp|http|ftp|https|freenet|mailto";
664
665       // kill all the bad tags that have attributes
666       String s = "<\\s*/?\\s*(?!(("+approvedTags+")\\s))\\w+\\s[^>]*>";
667       RE regex = new RE(s,RE.REG_ICASE);
668       haystack = regex.substituteAll(haystack,"");
669
670       // kill all the bad tags that are attributeless
671       regex = new RE("<\\s*/?\\s*(?!(("+approvedTags+")\\s*>))\\w+\\s*>",RE.REG_ICASE);
672       haystack = regex.substituteAll(haystack,"");
673
674       // kill all the tags which have a javascript attribute like onLoad
675       regex = new RE("<[^>]*("+badAttributes+")[^>]*>",RE.REG_ICASE);
676       haystack = regex.substituteAll(haystack,"");
677
678       // kill all the tags which include a url to an unacceptable protocol
679       regex = new RE("<\\s*a\\s+[^>]*href=(?!(\'|\")?("+approvedProtocols+"))[^>]*>",RE.REG_ICASE);
680       haystack = regex.substituteAll(haystack,"");
681
682       return haystack;
683     } catch(REException ex){
684       ex.printStackTrace();
685       return null;
686     }
687   }
688
689
690   /**
691    *  createHTML ruft alle regex-methoden zum unwandeln eines nicht
692    *  htmlcodierten string auf und returnt einen htmlcodierten String
693    */
694   public static String createHTML(String content){
695     content=convertNewline2Break(content);
696     content=convertNewline2P(content);
697     content=createMailLinks(content);
698     content=createURLLinks(content);
699     return content;
700   }
701
702
703   /**
704    *  createHTML ruft alle regex-methoden zum unwandeln eines nicht
705    *  htmlcodierten string auf und returnt einen htmlcodierten String
706    */
707   public static String createHTML(String content,String producerDocRoot,String mailImage,String extImage,String intImage){
708     content=convertNewline2Break(content);
709     content=convertNewline2P(content);
710     content=createMailLinks(content,producerDocRoot,mailImage);
711     content=createURLLinks(content,null,producerDocRoot,extImage,intImage);
712     return content;
713   }
714
715 }
716