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 java.util.regex.PatternSyntaxException;
23  
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 1040976 2010-12-01 12:15:39Z apetrelli $
56   * @since 1.5
57   */
58  public abstract class EscapeReference implements ReferenceInsertionEventHandler,RuntimeServicesAware {
59  
60      private RuntimeServices rs;
61  
62      private String matchRegExp = null;
63      //private Pattern pattern = null;
64  
65      /**
66       * Escape the given text.  Override this in a subclass to do the actual
67       * escaping.
68       *
69       * @param text the text to escape
70       * @return the escaped text
71       */
72      protected abstract String escape(Object text);
73  
74      /**
75       * Specify the configuration attribute that specifies the
76       * regular expression.  Ideally should be in a form
77       * <pre><code>eventhandler.escape.XYZ.match</code></pre>
78       *
79       * <p>where <code>XYZ</code> is the type of escaping being done.
80       * @return configuration attribute
81       */
82      protected abstract String getMatchAttribute();
83  
84      /**
85       * Escape the provided text if it matches the configured regular expression.
86       *
87       * @param reference
88       * @param value
89       * @return Escaped text.
90       */
91      public Object referenceInsert(String reference, Object value)
92      {
93          if(value == null)
94          {
95              return value;
96          }
97  
98          if (matchRegExp == null)
99          //if (pattern == null)
100         {
101             return escape(value);
102         }
103 
104         else if (reference.matches(matchRegExp))
105         {
106             return escape(value);
107         }
108 
109         else
110         {
111             return value;
112         }
113     }
114 
115     /**
116      * Called automatically when event cartridge is initialized.
117      *
118      * @param rs instance of RuntimeServices
119      */
120     public void setRuntimeServices(RuntimeServices rs)
121     {
122         this.rs = rs;
123 
124         /**
125          * Get the regular expression pattern.
126          */
127         matchRegExp = StringUtils.nullTrim(rs.getConfiguration().getString(getMatchAttribute()));
128         if ((matchRegExp != null) && (matchRegExp.length() == 0))
129         {
130             matchRegExp = null;
131         }
132 
133         /**
134          * Test the regular expression for a well formed pattern
135          */
136         if (matchRegExp != null)
137         {
138             try
139             {
140                 "".matches(matchRegExp);
141             }
142             catch (PatternSyntaxException E)
143             {
144                 rs.getLog().error("Invalid regular expression '" + matchRegExp
145                                   + "'.  No escaping will be performed.", E);
146                 matchRegExp = null;
147             }
148         }
149 
150     }
151 
152     /**
153      * Retrieve a reference to RuntimeServices.  Use this for checking additional
154      * configuration properties.
155      *
156      * @return The current runtime services object.
157      */
158     protected RuntimeServices getRuntimeServices()
159     {
160         return rs;
161     }
162 
163 }