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 470256 2006-11-02 07:20:36Z wglass $
56   */
57  public abstract class EscapeReference implements ReferenceInsertionEventHandler,RuntimeServicesAware {
58  
59  
60      private Perl5Util perl = new Perl5Util();
61  
62      private RuntimeServices rs;
63  
64      private String matchRegExp = null;
65  
66      /**
67       * Escape the given text.  Override this in a subclass to do the actual
68       * escaping.
69       *
70       * @param text the text to escape
71       * @return the escaped text
72       */
73      protected abstract String escape(Object text);
74  
75      /**
76       * Specify the configuration attribute that specifies the
77       * regular expression.  Ideally should be in a form
78       * <pre><code>eventhandler.escape.XYZ.match</code></pre>
79       *
80       * <p>where <code>XYZ</code> is the type of escaping being done.
81       * @return configuration attribute
82       */
83      protected abstract String getMatchAttribute();
84  
85      /**
86       * Escape the provided text if it matches the configured regular expression.
87       * 
88       * @param reference
89       * @param value
90       * @return Escaped text.
91       */
92      public Object referenceInsert(String reference, Object value)
93      {
94          if(value == null)
95          {
96              return value;
97          }
98  
99          if (matchRegExp == null)
100         {
101             return escape(value);
102         }
103 
104         else if (perl.match(matchRegExp,reference))
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                 perl.match(matchRegExp,"");
141             }
142             catch (MalformedPerl5PatternException 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 }