001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.lib.collab.util;
043:
044: import org.netbeans.lib.collab.util.*;
045: import java.awt.*;
046: import java.io.*;
047: import java.net.*;
048: import java.util.*;
049: import javax.swing.*;
050: import javax.swing.text.*;
051: import javax.swing.text.html.*;
052: import javax.swing.event.*;
053: import java.awt.event.*;
054: import java.util.regex.*;
055:
056: /**
057: *
058: */
059: public class HtmlUtility {
060: public static final String HTML_BEGIN = "<html><body>";
061: public static final String HTML_END = "</body></html>";
062:
063: private static final String ID_HTTP = "http://";
064: private static final String ID_WWW = "www.";
065: private static final char ID_TAGSTART = '<';
066: private static final char ID_TAGEND = '>';
067:
068: public static final String BODY_BEGIN = "<body";
069:
070: public static final String ID_COLOR_BLACK = "color=\"#000000\"";
071: public static final String ID_COLOR_BLUE = "color=\"#0000ff\"";
072: public static final String ID_COLOR_GREEN = "color=\"#00ff00\"";
073: public static final String ID_COLOR_RED = "color=\"#ff0000\"";
074: public static final String ID_COLOR_WHITE = "color=\"#ffffff\"";
075: public static final String ID_COLOR_PINK = "color=\"#ff00ff\"";
076:
077: public static final int FONT_COLOR_BLACK = 0;
078: public static final int FONT_COLOR_BLUE = 1;
079: public static final int FONT_COLOR_RED = 2;
080: public static final int FONT_COLOR_WHITE = 3;
081: public static final int FONT_COLOR_GREEN = 4;
082: public static final int FONT_COLOR_PINK = 5;
083:
084: private static final Pattern PATTERN_MIDDLE_SPACE = Pattern
085: .compile("([^\u0020])[\u0020][\u0020]+([^\u0020])");
086: private static final Pattern PATTERN_START_SPACE = Pattern
087: .compile("\\A[\u0020]+");
088: private static final Pattern PATTERN_END_SPACE = Pattern
089: .compile("[\u0020]+\\z");
090:
091: //given font type and size returns font tag in format of
092: //"<font color=\"#0000ff\" size=2> ";
093: //if size = null no size is entered
094: final static public String getFontColor(int color, String size) {
095: StringBuffer buf = new StringBuffer("<font ");
096:
097: switch (color) {
098: case FONT_COLOR_BLACK:
099: buf.append(ID_COLOR_BLACK);
100: break;
101: case FONT_COLOR_BLUE:
102: buf.append(ID_COLOR_BLUE);
103: break;
104: case FONT_COLOR_RED:
105: buf.append(ID_COLOR_RED);
106: break;
107: case FONT_COLOR_WHITE:
108: buf.append(ID_COLOR_WHITE);
109: break;
110: case FONT_COLOR_GREEN:
111: buf.append(ID_COLOR_GREEN);
112: break;
113: case FONT_COLOR_PINK:
114: buf.append(ID_COLOR_PINK);
115: break;
116: default:
117: buf.append(ID_COLOR_BLACK);
118: break;
119: }
120: if (size != null) {
121: buf.append(" size=");
122: buf.append(size);
123: }
124: buf.append(">");
125: return buf.toString();
126: }
127:
128: /**
129: *
130: *
131: * @param
132: */
133: //Convert a path to an Html Image Tag
134: final static public String createImageTag(String src, String alt) {
135: //<IMG SRC="http://"
136: //WIDTH=450 HEIGHT=284 VSPACE=2 BORDER=0 ALT="Asheville, NC">
137: String s = "<IMG SRC=\"" + src + "\"" + " ALT=\"" + alt + "\">";
138: return s;
139: }
140:
141: /*
142: * Returns the content of the first encountered HTML tag received as a parameter
143: * @param s The source string to extract the result from
144: * @param tag The HTML tag
145: * @return the content of the first encountered <I>tag</I>, the original string if an error occured
146: */
147: final static public String getTagContent(String s, HTML.Tag tag) {
148: //System.out.println("HTMLUtility.getTagContent(): s: "+s);
149: //System.out.println("HTMLUtility.getTagContent(): tag: "+tag);
150: String tmpStr = s.toLowerCase();
151: int startOpeningTag = tmpStr.indexOf("<" + tag);
152: if (startOpeningTag < 0)
153: return s;
154:
155: int endOpeningTag = startOpeningTag
156: + tmpStr.substring(startOpeningTag).indexOf(">");
157:
158: int startClosingTag = endOpeningTag
159: + tmpStr.substring(endOpeningTag + 1).lastIndexOf(
160: "</" + tag);
161: if (startClosingTag < 0)
162: return s;
163:
164: //System.out.println("HTMLUtility.getTagContent(): returning: "+s.substring(endOpeningTag+1, startClosingTag));
165: return s.substring(endOpeningTag + 1, startClosingTag + 1)
166: .trim();
167: }
168:
169: /*
170: * Returns the s string after removing the content of the encountered tag and the tags itself
171: * @param s The source string to extract the result from
172: * @param tag The HTML tag
173: */
174: final static private String removeTagAndContent(String s,
175: HTML.Tag tag) {
176: String tmpStr = s.toLowerCase();
177: StringBuffer buf = new StringBuffer();
178: int startOpeningTag = tmpStr.indexOf("<" + tag);
179: if (startOpeningTag < 0)
180: return s;
181:
182: buf.append(s.substring(0, startOpeningTag + 1));
183:
184: int endOpeningTag = startOpeningTag
185: + tmpStr.substring(startOpeningTag).indexOf(">");
186: int startClosingTag = endOpeningTag
187: + tmpStr.substring(endOpeningTag + 1).lastIndexOf(
188: "</" + tag);
189: int endClosingTag = startClosingTag
190: + tmpStr.substring(startClosingTag).indexOf(">");
191: if (endClosingTag < 0)
192: return s;
193: buf.append(s.substring(endClosingTag + 1));
194:
195: //System.out.println("HTMLUtility.getTagContent(): returning: "+s.substring(endOpeningTag+1, startClosingTag));
196: return buf.toString().trim();
197: }
198:
199: /**
200: * This method removes the tag argument passed to the method from the string
201: * It keeps the content of the tag intact.
202: *
203: */
204: final static private String removeFirstTagOnly(String s,
205: HTML.Tag tag) {
206: //Thread.dumpStack();
207: String tmpStr = s.toLowerCase();
208: StringBuffer buf = new StringBuffer();
209: int startOpeningTag = tmpStr.indexOf("<" + tag);
210: if (startOpeningTag < 0)
211: return s;
212:
213: buf.append(s.substring(0, startOpeningTag));
214:
215: int endOpeningTag = startOpeningTag
216: + tmpStr.substring(startOpeningTag).indexOf(">");
217: int startClosingTag = endOpeningTag
218: + tmpStr.substring(endOpeningTag + 1).indexOf(
219: "</" + tag);
220: if (startClosingTag < 0)
221: return s;
222:
223: buf.append(s.substring(endOpeningTag + 1, startClosingTag - 1));
224: int endClosingTag = startClosingTag
225: + tmpStr.substring(startClosingTag).indexOf(">");
226: if (endClosingTag < 0)
227: return s;
228:
229: buf.append(s.substring(endClosingTag + 1));
230:
231: //System.out.println("HTMLUtility.getTagContent(): returning: "+s.substring(endOpeningTag+1, startClosingTag));
232: return buf.toString().trim();
233: }
234:
235: /*
236: * Returns the s string after having removed the unsupported tags and their content
237: * @param s The source string to extract the result from
238: * @param tag The HTML tag
239: */
240: final static private String stripUnsupportedTags(String s) {
241: HTML.Tag[] unsupportedTags = { HTML.Tag.SCRIPT };
242: String tmpStr = s;
243: for (int i = 0; i < unsupportedTags.length; i++) {
244: while (tmpStr.toLowerCase().indexOf(
245: unsupportedTags[i].toString()) > -1) {
246: tmpStr = removeTagAndContent(tmpStr, unsupportedTags[i]);
247: }
248: }
249: return tmpStr;
250: }
251:
252: /*
253: * returns the content of an HTML document get rid of the head part, body tags and if there first p tag
254: * @param String s
255: */
256: final static public String getContent(String s) {
257: //System.out.println("HTMLUtility.getContent: s: \n"+s);
258: String content = getTagContent(s, HTML.Tag.BODY);
259: //System.out.println("HTMLUtility.getContent: content: \n"+content);
260: return stripUnsupportedTags(content);
261: }
262:
263: /*
264: * Removes the first tag <I>tag</I> encountered and i
265: */
266: final static public String[] splitFirstParagraph(String s,
267: HTML.Tag tag) {
268: //if the string does not begin by the specified tag then exit
269: if (s != null) {
270: int tagLen = tag.toString().length();
271: if (s.length() > tagLen) {
272: if (s.substring(0, tagLen + 1).equalsIgnoreCase(
273: "<" + tag)) {
274: String[] parts = new String[2];
275: parts[0] = getTagContent(s, tag);
276: parts[1] = removeTagAndContent(s, tag);
277: return parts;
278: }
279: }
280: }
281: return null;
282: }
283:
284: /**
285: * returns just the body portion of html text between P tags
286: * leaves out <body> and <p> tags
287: * @param String s
288: */
289: final static public String getPBody(String s) {
290: return getTagContent(s, HTML.Tag.P);
291: }
292:
293: /**
294: * returns just the body portion of html text
295: * leaves out <body> tags
296: * @param String s
297: */
298: protected static Pattern popen = Pattern.compile(
299: "\\A<(\\w)[^>]*>(.*)</p>(.*)\\Z", Pattern.DOTALL
300: | Pattern.CASE_INSENSITIVE);
301: protected static Pattern pclose = Pattern.compile(".*</p>.*",
302: Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
303:
304: final static public String getBody(String s) {
305: // fix bug id 6176277
306: // just strip the first paragraph.
307: String body = getTagContent(s, HTML.Tag.BODY);
308: Matcher m = popen.matcher(body);
309: String cnt;
310: if (m.matches() && m.group(1).equalsIgnoreCase("p")
311: && m.group(3).length() == 0) {
312: cnt = m.group(2);
313: Matcher mclose = pclose.matcher(cnt);
314: if (!mclose.matches()) {
315: return cnt;
316: }
317: }
318: return body;
319:
320: }
321:
322: /**
323: *
324: *
325: * @param
326: */
327: //TODO make sure that the http:// is not already a html link tag
328: //if there is already a formated <href> tag, this will not skip over it
329: //converts any instance of a url to a html link
330: final static public String convertLinks(String body) {
331: final String originalBody = body;
332: StringBuffer buf = new StringBuffer();
333: String tmpStr = null;
334: int a = 0;
335: int b = 0;
336:
337: while (a < body.length()) {
338: tmpStr = body.substring(a);
339: if (tmpStr.charAt(0) == ID_TAGSTART) {
340: //If we're entering an HTML tag
341: //Then jump to the end of the tag
342: if ((b = tmpStr.indexOf(ID_TAGEND)) == -1) { //Illegal HTML: tag not closed
343: return originalBody;
344: } else {
345: b += (a + 1);
346: buf.append(body.substring(a, b));
347: }
348: } else {
349: if (tmpStr.startsWith(ID_HTTP)) {
350: if ((b = getEndOfURL(tmpStr)) == -1) { //Unknown error
351: return originalBody;
352: } else {
353: b += a;
354: buf.append(createLink(body.substring(a, b),
355: body.substring(a, b)));
356: }
357: } else if (tmpStr.startsWith(ID_WWW)) {
358: if ((b = getEndOfURL(tmpStr)) == -1) { //Unknown error
359: return originalBody;
360: } else {
361: b += a;
362: buf.append(createLink(ID_HTTP
363: + body.substring(a, b), body.substring(
364: a, b)));
365: }
366: } else {
367: b++; //Move pointer b to b+1
368: buf.append(body.substring(a, b));
369: }
370: }
371: a = b; //Move pointer a to b
372: }
373: return buf.toString();
374: }
375:
376: private static int getEndOfURL(String str) {
377: //End of URL is either a space or the beginning of a tag
378: int i = str.indexOf(ID_TAGSTART);
379: int j = str.indexOf(' ');
380: if ((i == -1) && (j > -1)) {
381: return j;
382: } else if ((i > -1) && (j == -1)) {
383: return i;
384: } else if ((i > -1) && (j > -1)) {
385: return Math.min(i, j);
386: } else {
387: return -1;
388: }
389: }
390:
391: /**
392: *
393: *
394: * @param
395: */
396: //TODO make sure that the http:// is not already a html link tag
397: //if there is already a formated <href> tag, this will not skip over it
398: //converts any instance of a url to a html link
399: final static public String convertLinks2(String body) {
400: int tmp = 0;
401:
402: while (true) {
403: tmp = body.indexOf("http://", tmp);//7
404: if (tmp < 0)
405: break;
406: int tmp2 = body.indexOf(" ", tmp);
407: String link = body.substring(tmp, tmp2);
408: tmp2 = link.indexOf("<");
409: if (!(tmp2 < 0))
410: link = link.substring(0, tmp2);
411: body = StringUtility.replaceString(link, createLink(link,
412: link), body);
413: tmp += (2 * link.length()) + 8;//size of link + html tags
414: }
415: return body;
416: }
417:
418: /**
419: *
420: *
421: * @param
422: */
423: final static public String convertFont(String s) {
424: //s = StringUtility.replaceString("size=\"8\"", "size=\"0\"", s);
425: //s = StringUtility.replaceString("size=\"10\"", "size=\"1\"", s);
426: //s = StringUtility.replaceString("size=\"12\"", "size=\"2\"", s);
427: //s = StringUtility.replaceString("size=\"14\"", "size=\"3\"", s);
428: //s = StringUtility.replaceString("size=\"18\"", "size=\"4\"", s);
429: //s = StringUtility.replaceString("size=\"24\"", "size=\"5\"", s);
430: //s = StringUtility.replaceString("size=\"32\"", "size=\"6\"", s);
431: //if(s.equals("8")) return "0\" ";
432: //else if(s.equals("10")) return "1\"";
433: if (s.equals("12"))
434: return "2\"";
435: else if (s.equals("14"))
436: return "3\"";
437: else if (s.equals("18"))
438: return "4\"";
439: else if (s.equals("24"))
440: return "5\"";
441: else if (s.equals("32"))
442: return "6\"";
443: else
444: return "3\"";
445: }
446:
447: /**
448: *
449: *
450: * @param
451: */
452: final static public String convertFontSize(boolean[] list, String s) {
453: //for(int n = 0; n< list.length; n++){
454: // if(list[n])
455: //}
456: //if(list[0])
457: // s = StringUtility.replaceString("size=\"8\"", "size=\"0\"", s);
458: //if(list[1])
459: // s = StringUtility.replaceString("size=\"10\"", "size=\"1\"", s);
460: if (list[0])
461: s = StringUtility.replaceString("size=\"12\"",
462: "size=\"2\"", s);
463: if (list[1])
464: s = StringUtility.replaceString("size=\"14\"",
465: "size=\"3\"", s);
466: if (list[2])
467: s = StringUtility.replaceString("size=\"18\"",
468: "size=\"4\"", s);
469: if (list[3])
470: s = StringUtility.replaceString("size=\"24\"",
471: "size=\"5\"", s);
472: if (list[4])
473: s = StringUtility.replaceString("size=\"32\"",
474: "size=\"6\"", s);
475: return s;
476: }
477:
478: /**
479: * //Inserts image tag into a given Document at cursor pos
480: *
481: * @param
482: */
483: final static public void insertImage(Document d, int pos,
484: String src, String alt, int width, int height, int vspace,
485: int border) {
486: MutableAttributeSet a = new SimpleAttributeSet();
487: a.addAttribute(StyleConstants.NameAttribute, HTML.Tag.IMG);
488: a.addAttribute(HTML.Attribute.SRC, src);
489: a.addAttribute(HTML.Attribute.ALT, alt);
490: try {
491: d.insertString(pos, "i", a);
492: } catch (Exception e) {
493: System.out.println(e);
494: }
495: }
496:
497: final static public void insertImage(Document d, int pos,
498: String src, String alt) {
499: insertImage(d, pos, src, alt, 0, 0, 0, 0);
500: }
501:
502: /**
503: * Create a html link from a given url and display string
504: * @param String link, String name
505: */
506: final static public String createLink(String link, String name) {
507: StringBuffer buf = new StringBuffer("<a href=");
508: buf.append("\"");
509: buf.append(link);
510: buf.append("\"");
511: buf.append(">");
512: buf.append(name.trim());
513: buf.append("</a>");
514: return buf.toString();
515: //String text = " <a href=" +link+ " target=install> ";
516: //return text +name+ " </a>";
517: }
518:
519: /**
520: * Used in cases where a real link can't be inserted
521: * because 1.2.2 has problems inserting tags, may want to create fake looking link
522: * I think most problems have been fixed but I'll leave for now
523: * @param String lnk
524: */
525: final static public String createFakeLink(String lnk) {
526: return "<u><font color=\""
527: + HtmlUtility.getFontColor(FONT_COLOR_BLUE, null)
528: + "\">" + lnk + "</font></u>";
529: }
530:
531: /**
532: * takes a url string and adds http:// on end if needed
533: * @param String url
534: */
535: final static public String formatUrl(String url) {
536: if (url.equals(""))
537: return "";
538: else if (url.startsWith("http://"))
539: return url;
540: else if (url.startsWith("file:///"))
541: return url;
542: else
543: return "http://" + url;
544: //else
545: // return url;
546: }
547:
548: final static public int getPosAfterBody(String s) {
549: int startPos = s.indexOf(BODY_BEGIN);
550: if (startPos == -1)
551: return -1;
552: int endPos = s.substring(startPos).indexOf(">");
553: if (endPos == -1)
554: return -1;
555: return startPos + endPos + 1;
556: }
557:
558: //Ampersand has to be the last, because it's treated separatly from the others
559: private static final char[] unescapedChars = { '&', '<', '>', '\"' };
560: private static final String[] escapedStrings = { "&", "<",
561: ">", """ };
562:
563: public static String escape(String s) {
564: for (int i = 0; i < unescapedChars.length; i++) {
565: s = StringUtility.substitute(s, unescapedChars[i],
566: escapedStrings[i]);
567: }
568: return s;
569: }
570:
571: /**
572: * Html unescape a string
573: */
574: public static String unescape(String s) {
575: if (s == null || s.length() <= 0)
576: return s;
577: for (int i = 0; i < escapedStrings.length - 1; i++) {
578: s = StringUtility.substitute(s, escapedStrings[i],
579: unescapedChars[i]);
580: }
581: return s;
582: }
583:
584: /**
585: * Substitutes all instances of a pattern within a HTML String, by another
586: * String but only outside of HTML tags.
587: * It recognizes escaped characters as one character to be replaced.
588: * @param to input HTML string
589: * @param from pattern to replace must not contains escaped characters
590: * @param to String to replace instances of the pattern with
591: * @return new String in which all instances of swapOut have been replaced
592: * substituted with swapIn
593: */
594: final public static String substitute(final String s,
595: final String from, final String to) {
596: if (s == null || s.length() <= 0)
597: return s;
598: if (from == null || from.length() <= 0)
599: return s;
600: if (to == null)
601: return s;
602: if (from == to)
603: return s;
604:
605: int a = 0; //points to the beginning of the chunck to process
606: int b = 0; //points to the end of the chunck to process
607: int c = 0; //temporary pointer
608: final int maxA = s.length() - 1;
609: StringBuffer buf = new StringBuffer();
610: String strToProcess = s.trim();
611: String unescapedStr = null;
612: //System.out.println("HtmlUtility.substitute(): s: "+s);
613: while (strToProcess.length() > 0) {
614: //System.out.println("HtmlUtility.substitute(): strToProcess: "+strToProcess);
615: if ((b = strToProcess.indexOf('<')) >= 0) { //if there is HTML tag(s) in the original string
616: unescapedStr = unescape(strToProcess.substring(0, b));
617: while ((c = unescapedStr.indexOf(from)) >= 0) {
618: //System.out.println("HtmlUtility.substitute(): unescapedStr.substring(0,c): "+ unescapedStr.substring(0,c));
619: //if the string to replace is present then put what's before in the buffer
620: //put the replacement string in the buffer and loop on the next part of the string
621: buf.append(escape(unescapedStr.substring(0, c)));
622: buf.append(to);
623: unescapedStr = unescapedStr.substring(c
624: + from.length());
625: }
626: buf.append(escape(unescapedStr));
627: //append the html tag to the buffer
628: a = b;
629: //indexOf from b since becuase you can have
630: //unescaped '>' in content
631: b = strToProcess.indexOf('>', a);
632:
633: if (b < 0) {
634: //System.err.println("HtmlUtility.substitute(): Malformed HTML");
635: return s;
636: }
637: buf.append(strToProcess.substring(a, b + 1));
638: } else { //if there is no HTML tag(s) in the original string
639: unescapedStr = unescape(strToProcess);
640: while ((c = unescapedStr.indexOf(from)) >= 0) {
641: //System.out.println("HtmlUtility.substitute(): unescapedStr.substring(0,c): "+ unescapedStr.substring(0,c));
642: buf.append(escape(unescapedStr.substring(0, c)));
643: buf.append(to);
644: unescapedStr = unescapedStr.substring(c
645: + from.length());
646: }
647: buf.append(escape(unescapedStr));
648: b = strToProcess.length() - 1;
649: }
650: strToProcess = strToProcess.substring(b + 1);
651: a = b = 0;
652: }
653: //System.out.println("HtmlUtility.substitute(): returning: "+buf.toString());
654: return buf.toString();
655: }
656:
657: private static String replaceSpace(String s) {
658: Pattern p = PATTERN_MIDDLE_SPACE;
659: Matcher m = p.matcher(s);
660: StringBuffer out = new StringBuffer();
661: int prev = 0;
662: while (m.find(prev)) {
663: out.append(s.substring(prev, m.start()));
664: int len = m.end() - m.start();
665: StringBuffer temp = new StringBuffer();
666: for (int i = 1; i < len - 2; i++) {
667: temp.append(" ");
668: }
669: temp.append(" ");
670: out.append(m.group(1));
671: out.append(temp);
672: //out.append(m.group(2));
673: prev = m.end() - 1;
674: }
675: out.append(s.substring(prev));
676: p = PATTERN_START_SPACE;
677: m = p.matcher(out.toString());
678: if (m.find()) {
679: int len = m.end() - m.start();
680: StringBuffer temp = new StringBuffer();
681: for (int i = 0; i < len; i++) {
682: temp.append(" ");
683: }
684: out.replace(m.start(), m.end(), temp.toString());
685: }
686:
687: p = PATTERN_END_SPACE;
688: m = p.matcher(out.toString());
689: if (m.find()) {
690: int len = m.end() - m.start();
691: StringBuffer temp = new StringBuffer();
692: for (int i = 0; i < len; i++) {
693: temp.append(" ");
694: }
695: out.replace(m.start(), m.end(), temp.toString());
696: }
697: return out.toString();
698:
699: }
700:
701: final public static String substituteSpace(final String s) {
702: if (s == null || s.length() <= 0)
703: return s;
704:
705: int a = 0; //points to the beginning of the chunck to process
706: int b = 0; //points to the end of the chunck to process
707: int c = 0; //temporary pointer
708: final int maxA = s.length() - 1;
709: StringBuffer buf = new StringBuffer();
710: String strToProcess = s.trim();
711: String unescapedStr = null;
712: //System.out.println("HtmlUtility.substitute(): s: "+s);
713: while (strToProcess.length() > 0) {
714: //System.out.println("HtmlUtility.substitute(): strToProcess: "+strToProcess);
715: if ((b = strToProcess.indexOf('<')) >= 0) { //if there is HTML tag(s) in the original string
716: unescapedStr = unescape(strToProcess.substring(0, b));
717: /*while ((c = unescapedStr.indexOf(from)) >= 0) {
718: //System.out.println("HtmlUtility.substitute(): unescapedStr.substring(0,c): "+ unescapedStr.substring(0,c));
719: //if the string to replace is present then put what's before in the buffer
720: //put the replacement string in the buffer and loop on the next part of the string
721: buf.append(escape(unescapedStr.substring(0,c)));
722: buf.append(to);
723: unescapedStr = unescapedStr.substring(c+from.length());
724: }*/
725: buf.append(escape(replaceSpace(unescapedStr)));
726: //append the html tag to the buffer
727: a = b;
728: //indexOf from b since becuase you can have
729: //unescaped '>' in content
730: b = strToProcess.indexOf('>', a);
731:
732: if (b < 0) {
733: //System.err.println("HtmlUtility.substitute(): Malformed HTML");
734: return s;
735: }
736: buf.append(strToProcess.substring(a, b + 1));
737: } else { //if there is no HTML tag(s) in the original string
738: unescapedStr = unescape(strToProcess);
739: /*while ((c = unescapedStr.indexOf(from)) >= 0) {
740: //System.out.println("HtmlUtility.substitute(): unescapedStr.substring(0,c): "+ unescapedStr.substring(0,c));
741: buf.append(escape(unescapedStr.substring(0,c)));
742: buf.append(to);
743: unescapedStr = unescapedStr.substring(c+from.length());
744: }*/
745: buf.append(escape(replaceSpace(unescapedStr)));
746: b = strToProcess.length() - 1;
747: }
748: strToProcess = strToProcess.substring(b + 1);
749: a = b = 0;
750: }
751: //System.out.println("HtmlUtility.substitute(): returning: "+buf.toString());
752: return buf.toString();
753: }
754:
755: /*
756: public static void main(String[] arg)
757: {
758: try {
759: BufferedReader reader = new BufferedReader(new FileReader(arg[0]));
760: String s = null;
761: while ((s = reader.readLine()) != null) {
762: s = substitute(s, ":))", "<img src=\"lol.gif\">");
763: s = substitute(s, ":-)", "<img src=\"smile.gif\">");
764: s = substitute(s, ";-)", "<img src=\"wink.gif\">");
765: s = substitute(s, ":)", "<img src=\"smile.gif\">");
766: s = substitute(s, ";)", "<img src=\"wink.gif\">");
767:
768: System.out.println(s);
769: }
770: } catch (Exception e) {
771: e.printStackTrace();
772: }
773: }
774: */
775:
776: public static boolean containsPre(String body) {
777: return body.contains("</pre>");
778: }
779: }
|