001: package org.apache.velocity.app.event.implement;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import org.apache.oro.text.perl.MalformedPerl5PatternException;
023: import org.apache.oro.text.perl.Perl5Util;
024: import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
025: import org.apache.velocity.runtime.RuntimeServices;
026: import org.apache.velocity.util.RuntimeServicesAware;
027: import org.apache.velocity.util.StringUtils;
028:
029: /**
030: * Base class for escaping references. To use it, override the following methods:
031: * <DL>
032: * <DT><code>String escape(String text)</code></DT>
033: * <DD>escape the provided text</DD>
034: * <DT><code>String getMatchAttribute()</code></DT>
035: * <DD>retrieve the configuration attribute used to match references (see below)</DD>
036: * </DL>
037: *
038: * <P>By default, all references are escaped. However, by setting the match attribute
039: * in the configuration file to a regular expression, users can specify which references
040: * to escape. For example the following configuration property tells the EscapeSqlReference
041: * event handler to only escape references that start with "sql".
042: * (e.g. <code>$sql</code>, <code>$sql.toString(),</code>, etc).
043: *
044: * <PRE>
045: * <CODE>eventhandler.escape.sql.match = /sql.*<!-- -->/
046: * </CODE>
047: * </PRE>
048: * <!-- note: ignore empty HTML comment above - breaks up star slash avoiding javadoc end -->
049: *
050: * Regular expressions should follow the "Perl5" format used by the ORO regular expression
051: * library. More info is at
052: * <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>.
053: *
054: * @author <a href="mailto:wglass@forio.com">Will Glass-Husain </a>
055: * @version $Id: EscapeReference.java 470256 2006-11-02 07:20:36Z wglass $
056: */
057: public abstract class EscapeReference implements
058: ReferenceInsertionEventHandler, RuntimeServicesAware {
059:
060: private Perl5Util perl = new Perl5Util();
061:
062: private RuntimeServices rs;
063:
064: private String matchRegExp = null;
065:
066: /**
067: * Escape the given text. Override this in a subclass to do the actual
068: * escaping.
069: *
070: * @param text the text to escape
071: * @return the escaped text
072: */
073: protected abstract String escape(Object text);
074:
075: /**
076: * Specify the configuration attribute that specifies the
077: * regular expression. Ideally should be in a form
078: * <pre><code>eventhandler.escape.XYZ.match</code></pre>
079: *
080: * <p>where <code>XYZ</code> is the type of escaping being done.
081: * @return configuration attribute
082: */
083: protected abstract String getMatchAttribute();
084:
085: /**
086: * Escape the provided text if it matches the configured regular expression.
087: *
088: * @param reference
089: * @param value
090: * @return Escaped text.
091: */
092: public Object referenceInsert(String reference, Object value) {
093: if (value == null) {
094: return value;
095: }
096:
097: if (matchRegExp == null) {
098: return escape(value);
099: }
100:
101: else if (perl.match(matchRegExp, reference)) {
102: return escape(value);
103: }
104:
105: else {
106: return value;
107: }
108: }
109:
110: /**
111: * Called automatically when event cartridge is initialized.
112: *
113: * @param rs instance of RuntimeServices
114: */
115: public void setRuntimeServices(RuntimeServices rs) {
116: this .rs = rs;
117:
118: /**
119: * Get the regular expression pattern.
120: */
121: matchRegExp = StringUtils.nullTrim(rs.getConfiguration()
122: .getString(getMatchAttribute()));
123: if ((matchRegExp != null) && (matchRegExp.length() == 0)) {
124: matchRegExp = null;
125: }
126:
127: /**
128: * Test the regular expression for a well formed pattern
129: */
130: if (matchRegExp != null) {
131: try {
132: perl.match(matchRegExp, "");
133: } catch (MalformedPerl5PatternException E) {
134: rs.getLog().error(
135: "Invalid regular expression '" + matchRegExp
136: + "'. No escaping will be performed.",
137: E);
138: matchRegExp = null;
139: }
140: }
141:
142: }
143:
144: /**
145: * Retrieve a reference to RuntimeServices. Use this for checking additional
146: * configuration properties.
147: *
148: * @return The current runtime services object.
149: */
150: protected RuntimeServices getRuntimeServices() {
151: return rs;
152: }
153:
154: }
|