View Javadoc

1   package org.apache.velocity.app.event.implement;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import org.apache.oro.text.perl.MalformedPerl5PatternException;
23  import org.apache.oro.text.perl.Perl5Util;
24  import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
25  import org.apache.velocity.runtime.RuntimeServices;
26  import org.apache.velocity.util.RuntimeServicesAware;
27  import org.apache.velocity.util.StringUtils;
28  
29  /**
30   * Base class for escaping references.  To use it, override the following methods:
31   * <DL>
32   * <DT><code>String escape(String text)</code></DT>
33   * <DD>escape the provided text</DD>
34   * <DT><code>String getMatchAttribute()</code></DT>
35   * <DD>retrieve the configuration attribute used to match references (see below)</DD>
36   * </DL>
37   *
38   * <P>By default, all references are escaped.  However, by setting the match attribute
39   * in the configuration file to a regular expression, users can specify which references
40   * to escape.  For example the following configuration property tells the EscapeSqlReference
41   * event handler to only escape references that start with "sql".
42   * (e.g. <code>$sql</code>, <code>$sql.toString(),</code>, etc).
43   *
44   * <PRE>
45   * <CODE>eventhandler.escape.sql.match = /sql.*<!-- -->/
46   * </CODE>
47   * </PRE>
48   * <!-- note: ignore empty HTML comment above - breaks up star slash avoiding javadoc end -->
49   *
50   * Regular expressions should follow the "Perl5" format used by the ORO regular expression
51   * library.  More info is at
52   * <a href="http://jakarta.apache.org/oro/api/org/apache/oro/text/perl/package-summary.html">http://jakarta.apache.org/oro/api/org/apache/oro/text/perl/package-summary.html</a>.
53   *
54   * @author <a href="mailto:wglass@forio.com">Will Glass-Husain </a>
55   * @version $Id: EscapeReference.java 685685 2008-08-13 21:43:27Z nbubna $
56   * @since 1.5
57   */
58  public abstract class EscapeReference implements ReferenceInsertionEventHandler,RuntimeServicesAware {
59  
60  
61      private Perl5Util perl = new Perl5Util();
62  
63      private RuntimeServices rs;
64  
65      private String matchRegExp = null;
66  
67      /**
68       * Escape the given text.  Override this in a subclass to do the actual
69       * escaping.
70       *
71       * @param text the text to escape
72       * @return the escaped text
73       */
74      protected abstract String escape(Object text);
75  
76      /**
77       * Specify the configuration attribute that specifies the
78       * regular expression.  Ideally should be in a form
79       * <pre><code>eventhandler.escape.XYZ.match</code></pre>
80       *
81       * <p>where <code>XYZ</code> is the type of escaping being done.
82       * @return configuration attribute
83       */
84      protected abstract String getMatchAttribute();
85  
86      /**
87       * Escape the provided text if it matches the configured regular expression.
88       * 
89       * @param reference
90       * @param value
91       * @return Escaped text.
92       */
93      public Object referenceInsert(String reference, Object value)
94      {
95          if(value == null)
96          {
97              return value;
98          }
99  
100         if (matchRegExp == null)
101         {
102             return escape(value);
103         }
104 
105         else if (perl.match(matchRegExp,reference))
106         {
107             return escape(value);
108         }
109 
110         else
111         {
112             return value;
113         }
114     }
115 
116     /**
117      * Called automatically when event cartridge is initialized.
118      * 
119      * @param rs instance of RuntimeServices
120      */
121     public void setRuntimeServices(RuntimeServices rs)
122     {
123         this.rs = rs;
124 
125         /**
126          * Get the regular expression pattern.
127          */
128         matchRegExp = StringUtils.nullTrim(rs.getConfiguration().getString(getMatchAttribute()));
129         if ((matchRegExp != null) && (matchRegExp.length() == 0))
130         {
131             matchRegExp = null;
132         }
133 
134         /**
135          * Test the regular expression for a well formed pattern
136          */
137         if (matchRegExp != null)
138         {
139             try
140             {
141                 perl.match(matchRegExp,"");
142             }
143             catch (MalformedPerl5PatternException E)
144             {
145                 rs.getLog().error("Invalid regular expression '" + matchRegExp
146                                   + "'.  No escaping will be performed.", E);
147                 matchRegExp = null;
148             }
149         }
150 
151     }
152 
153     /**
154      * Retrieve a reference to RuntimeServices.  Use this for checking additional
155      * configuration properties.
156      * 
157      * @return The current runtime services object.
158      */
159     protected RuntimeServices getRuntimeServices()
160     {
161         return rs;
162     }
163 
164 }