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.ArrayList;
23 import java.util.List;
24
25 import org.apache.velocity.app.event.InvalidReferenceEventHandler;
26 import org.apache.velocity.context.Context;
27 import org.apache.velocity.exception.ParseErrorException;
28 import org.apache.velocity.runtime.RuntimeServices;
29 import org.apache.velocity.util.RuntimeServicesAware;
30 import org.apache.velocity.util.introspection.Info;
31
32 /**
33 * Use this event handler to flag invalid references. Since this
34 * is intended to be used for a specific request, this should be
35 * used as a local event handler attached to a specific context
36 * instead of being globally defined in the Velocity properties file.
37 *
38 * <p>
39 * Note that InvalidReferenceHandler can be used
40 * in two modes. If the Velocity properties file contains the following:
41 * <pre>
42 * eventhandler.invalidreference.exception = true
43 * </pre>
44 * then the event handler will throw a ParseErrorRuntimeException upon
45 * hitting the first invalid reference. This stops processing and is
46 * passed through to the application code. The ParseErrorRuntimeException
47 * contain information about the template name, line number, column number,
48 * and invalid reference.
49 *
50 * <p>
51 * If this configuration setting is false or omitted then the page
52 * will be processed as normal, but all invalid references will be collected
53 * in a List of InvalidReferenceInfo objects.
54 *
55 * <p>This feature should be regarded as experimental.
56 *
57 * @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
58 * @version $Id: ReportInvalidReferences.java 685685 2008-08-13 21:43:27Z nbubna $
59 * @since 1.5
60 */
61 public class ReportInvalidReferences implements
62 InvalidReferenceEventHandler, RuntimeServicesAware
63 {
64
65 public static final String EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "eventhandler.invalidreference.exception";
66
67 /**
68 * List of InvalidReferenceInfo objects
69 */
70 List invalidReferences = new ArrayList();
71
72 /**
73 * If true, stop at the first invalid reference and throw an exception.
74 */
75 private boolean stopOnFirstInvalidReference = false;
76
77
78 /**
79 * Collect the error and/or throw an exception, depending on configuration.
80 *
81 * @param context the context when the reference was found invalid
82 * @param reference string with complete invalid reference
83 * @param object the object referred to, or null if not found
84 * @param property the property name from the reference
85 * @param info contains template, line, column details
86 * @return always returns null
87 * @throws ParseErrorException
88 */
89 public Object invalidGetMethod(Context context, String reference, Object object,
90 String property, Info info)
91 {
92 reportInvalidReference(reference, info);
93 return null;
94 }
95
96 /**
97 * Collect the error and/or throw an exception, depending on configuration.
98 *
99 * @param context the context when the reference was found invalid
100 * @param reference complete invalid reference
101 * @param object the object referred to, or null if not found
102 * @param method the property name from the reference
103 * @param info contains template, line, column details
104 * @return always returns null
105 * @throws ParseErrorException
106 */
107 public Object invalidMethod(Context context, String reference, Object object,
108 String method, Info info)
109 {
110 if (reference == null)
111 {
112 reportInvalidReference(object.getClass().getName() + "." + method, info);
113 }
114 else
115 {
116 reportInvalidReference(reference, info);
117 }
118 return null;
119 }
120
121 /**
122 * Collect the error and/or throw an exception, depending on configuration.
123 *
124 * @param context the context when the reference was found invalid
125 * @param leftreference left reference being assigned to
126 * @param rightreference invalid reference on the right
127 * @param info contains info on template, line, col
128 * @return loop to end -- always returns false
129 */
130 public boolean invalidSetMethod(Context context, String leftreference, String rightreference, Info info)
131 {
132 reportInvalidReference(leftreference, info);
133 return false;
134 }
135
136
137 /**
138 * Check for an invalid reference and collect the error or throw an exception
139 * (depending on configuration).
140 *
141 * @param reference the invalid reference
142 * @param info line, column, template name
143 */
144 private void reportInvalidReference(String reference, Info info)
145 {
146 InvalidReferenceInfo invalidReferenceInfo = new InvalidReferenceInfo(reference, info);
147 invalidReferences.add(invalidReferenceInfo);
148
149 if (stopOnFirstInvalidReference)
150 {
151 throw new ParseErrorException(
152 "Error in page - invalid reference. ",
153 info,
154 invalidReferenceInfo.getInvalidReference());
155 }
156 }
157
158
159 /**
160 * All invalid references during the processing of this page.
161 * @return a List of InvalidReferenceInfo objects
162 */
163 public List getInvalidReferences()
164 {
165 return invalidReferences;
166 }
167
168
169 /**
170 * Called automatically when event cartridge is initialized.
171 * @param rs RuntimeServices object assigned during initialization
172 */
173 public void setRuntimeServices(RuntimeServices rs)
174 {
175 stopOnFirstInvalidReference = rs.getConfiguration().getBoolean(
176 EVENTHANDLER_INVALIDREFERENCE_EXCEPTION,
177 false);
178 }
179
180 }