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