KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > transformers > CodeSampleFactory


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util.transformers;
11
12 import java.util.regex.Pattern JavaDoc;
13 import java.util.regex.Matcher JavaDoc;
14
15 import org.mmbase.util.transformers.*;
16 import org.mmbase.util.functions.Parameter;
17 import org.mmbase.util.functions.Parameters;
18 import org.mmbase.util.logging.Logger;
19 import org.mmbase.util.logging.Logging;
20
21 /**
22  * This TransformerFactory enables the use of two different escapers in one piece
23  * of text. I started it to simplify the inclusion of a code snippet in html.
24  * You can specify the tags between which you wish to escape your text, the
25  * escaper to use and you can set an escaper for the rest of the text.<br />
26  * The tags default to &lt;pre&gt; and &lt;/pre&gt;, the first escaper defaults to
27  * 'text/html' (which escapes &amp;, &lt;, &gt;, &quot; and leaves the linebreakes
28  * untouched). The last escaper does by default nothing. But of course you can set
29  * your own with the parameters 'starttag', 'closetag', 'escapecode' and 'escaperest'.
30  *
31  * @author Andr&eacute; van Toly
32  * @since MMBase 1.8.0
33  * @version $Id: CodeSampleFactory.java,v 1.2 2006/04/14 11:25:29 andre Exp $
34  */

35
36 public class CodeSampleFactory implements ParameterizedTransformerFactory {
37
38     private final static Logger log = Logging.getLoggerInstance(CodeSampleFactory.class);
39     
40     private final static Parameter[] PARAMS = new Parameter[] {
41         new Parameter("starttag", String JavaDoc.class, "<pre>"),
42         new Parameter("closetag", String JavaDoc.class, ""),
43         new Parameter("escapecode", String JavaDoc.class, "text/html"), // like attr. escaper of mm:content
44
new Parameter("escaperest", String JavaDoc.class, ""), // do nothing by default
45

46     };
47     
48     public Parameters createParameters() {
49         return new Parameters(PARAMS);
50     }
51
52     public Transformer createTransformer(Parameters parameters) {
53         parameters.checkRequiredParameters();
54         
55         return new CodeSample( (String JavaDoc) parameters.get("starttag"),
56                                (String JavaDoc) parameters.get("closetag"),
57                                (String JavaDoc) parameters.get("escapecode"),
58                                (String JavaDoc) parameters.get("escaperest") );
59     }
60
61     protected class CodeSample extends StringTransformer {
62         private String JavaDoc starttag = "<pre>"; // default?
63
private String JavaDoc closetag = "";
64         private String JavaDoc escapecode = "text/html";
65         private String JavaDoc escaperest = ""; // do nothing
66

67         /**
68          * Constructor
69          *
70          */

71         public CodeSample(String JavaDoc st, String JavaDoc ct, String JavaDoc ec, String JavaDoc er) {
72             starttag = st;
73             closetag = ct;
74             escapecode = ec;
75             escaperest = er;
76         }
77     
78         /**
79          * Default transform method with no (other) parameters then the string
80          * to transform while using &lt;pre&gt; as the tag between which to escape
81          * the text while using the default escaper 'text/html'.
82          *
83          * @param str The original string
84          * @return The transformed string
85          */

86         public String JavaDoc transform(String JavaDoc str) {
87             return transform(str, starttag, closetag, escapecode, escaperest);
88         }
89         
90         /**
91          * Transforms the characters of a code example between two tags,
92          * &lt;pre&gt;-tags and &lt;/pre&gt; f.e., within a string and can use a
93          * different escaper for the rest of the text.
94          *
95          * @param str The original string
96          * @param starttag The opentag of the pair of tags between which code needs to be escaped
97          * @param closetag The closetag of the pair of tags between which code needs to be escaped
98          * @param escapecode The escaper to use on the piece of text between the tags
99          * @param escaperest The escaper to use on the rest of the text
100          * @return The transformed string
101          */

102         public String JavaDoc transform(String JavaDoc str, String JavaDoc starttag, String JavaDoc closetag, String JavaDoc escapecode, String JavaDoc escaperest) {
103             StringBuffer JavaDoc result = new StringBuffer JavaDoc();
104             
105             String JavaDoc stag = starttag;
106             String JavaDoc ctag = closetag;
107             if (ctag.equals("")) { // create closetag based on starttag, only usefull on an html tag
108
ctag = "</" + starttag.substring(1, starttag.length());
109             }
110             
111             Pattern JavaDoc sp = Pattern.compile("\\Q" + stag + "\\E", Pattern.DOTALL);
112             Pattern JavaDoc cp = Pattern.compile("\\Q" + ctag + "\\E", Pattern.DOTALL);
113             Matcher JavaDoc stm = sp.matcher(str); // starttag Matcher
114
Matcher JavaDoc ctm = cp.matcher(str); // closetag Matcher
115

116             int s = 0; // startposition 'rest' of the text
117
while (stm.find() && ctm.find()) {
118                 // stm.start(0) = position of starttag
119
// stm.end(0) = where starttag ends
120
// ctm.start(0) = position of closetag
121
// etc.
122
String JavaDoc normalStr = ""; // for the 'normal' text (not between the tags)
123
normalStr = str.substring(s, stm.start(0) );
124                 if (log.isDebugEnabled()) log.debug("Found rest str: " + normalStr);
125                 normalStr = transformPart(normalStr, escaperest);
126                 result.append(normalStr).append(stag); // the transformed str and the tag
127

128                 s = ctm.end(0); // here starts the rest of the text to be worked on
129

130                 String JavaDoc codeStr = str.substring(stm.end(0), ctm.start(0)); // the 'code'
131
if (log.isDebugEnabled()) log.debug("Found code str: " + codeStr);
132                 codeStr = transformPart(codeStr, escapecode);
133
134                 result.append(codeStr).append(ctag);
135             }
136             
137             // use escaperest upond the remaining piece of text and append it
138
// plus we always use escaperest, even when there is not match
139
String JavaDoc rest = str.substring(s, str.length());
140             result.append( transformPart(rest, escaperest) );
141             if (s == 0) {
142                 if (log.isDebugEnabled()) log.debug("No match with the tags '" + stag + "' and '" + ctag + "'");
143             }
144             return result.toString();
145         }
146         
147         
148        /**
149          * Transforms parts of the string. Calls the transform methods in
150          * {@link org.mmbase.util.transformers.XmlField} and {@link org.mmbase.util.transformers.Xml}.
151          * This method needs to be rewritten to support all escapers/transformers. It only
152          * supports p, pp, p-ommit-surrounding, pp-ommit-surrounding, inline, text/html and text/xml.
153          *
154          * @param str String to transform
155          * @param escaper The transformer or escaper to use (see escaper attr of &lt;mm:content /&gt;)
156          * @return The transformed string
157          */

158         public String JavaDoc transformPart(String JavaDoc str, String JavaDoc escaper) {
159             if (escaper.equals("p")) {
160                 str = XmlField.richToHTMLBlock(str, true, true);
161             } else if (escaper.equals("pp")) {
162                 str = XmlField.richToHTMLBlock(str);
163             } else if (escaper.equals("p-ommit-surrounding")) {
164                 str = XmlField.richToHTMLBlock(str, true, false);
165             } else if (escaper.equals("pp-ommit-surrounding")) {
166                 str = XmlField.richToHTMLBlock(str, false, false);
167             } else if (escaper.equals("inline")) {
168                 str = XmlField.poorToHTMLInline(str);
169             } else if (escaper.equals("text/html") || escaper.equals("text/xml")) {
170                 str = Xml.XMLEscape(str);
171             } else { // at least return something
172
str = str;
173                 //throw new UnsupportedOperationException("Cannot transform");
174
}
175             if (log.isDebugEnabled()) log.debug("Returning: " + str);
176             return str;
177         }
178         
179     }
180 }
181
Popular Tags