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.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 470265 2006-11-02 07:45:02Z wglass $
59   */
60  public class ReportInvalidReferences implements 
61  InvalidReferenceEventHandler, RuntimeServicesAware
62  {
63  
64      public static final String EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "eventhandler.invalidreference.exception";
65      
66      /** 
67       * List of InvalidReferenceInfo objects
68       */
69      List invalidReferences = new ArrayList();
70  
71      /**
72       * If true, stop at the first invalid reference and throw an exception.
73       */
74      private boolean stopOnFirstInvalidReference = false;
75      
76         
77      /**
78       * Collect the error and/or throw an exception, depending on configuration.
79       *
80       * @param context the context when the reference was found invalid
81       * @param reference string with complete invalid reference
82       * @param object the object referred to, or null if not found
83       * @param property the property name from the reference
84       * @param info contains template, line, column details
85       * @return always returns null
86       * @throws ParseErrorException
87       */
88      public Object invalidGetMethod(Context context, String reference, Object object, 
89              String property, Info info)
90      {
91          reportInvalidReference(reference, info);
92          return null;
93      }
94  
95      /**
96       * Collect the error and/or throw an exception, depending on configuration.
97       *
98       * @param context the context when the reference was found invalid
99       * @param reference complete invalid reference
100      * @param object the object referred to, or null if not found
101      * @param method the property name from the reference
102      * @param info contains template, line, column details
103      * @return always returns null
104      * @throws ParseErrorException
105      */
106     public Object invalidMethod(Context context, String reference, Object object, 
107             String method, Info info)
108     {
109         if (reference == null)
110         {
111             reportInvalidReference(object.getClass().getName() + "." + method, info);
112         }
113         else
114         {
115             reportInvalidReference(reference, info);
116         }
117         return null;
118     }
119 
120     /**
121      * Collect the error and/or throw an exception, depending on configuration.
122      *
123      * @param context the context when the reference was found invalid
124      * @param leftreference left reference being assigned to
125      * @param rightreference invalid reference on the right
126      * @param info contains info on template, line, col
127      * @return loop to end -- always returns false
128      */
129     public boolean invalidSetMethod(Context context, String leftreference, String rightreference, Info info)
130     {
131         reportInvalidReference(leftreference, info);
132         return false;
133     }
134 
135 
136     /**
137      * Check for an invalid reference and collect the error or throw an exception 
138      * (depending on configuration).
139      * 
140      * @param reference the invalid reference
141      * @param info line, column, template name
142      */
143     private void reportInvalidReference(String reference, Info info)
144     {
145         InvalidReferenceInfo invalidReferenceInfo = new InvalidReferenceInfo(reference, info);
146         invalidReferences.add(invalidReferenceInfo);
147         
148         if (stopOnFirstInvalidReference)
149         {
150             throw new ParseErrorException(
151                     "Error in page - invalid reference.  ",
152                     info,
153                     invalidReferenceInfo.getInvalidReference());
154         }
155     }
156 
157 
158     /**
159      * All invalid references during the processing of this page.
160      * @return a List of InvalidReferenceInfo objects
161      */
162     public List getInvalidReferences()
163     {
164         return invalidReferences;
165     }
166     
167 
168     /**
169      * Called automatically when event cartridge is initialized.
170      * @param rs RuntimeServices object assigned during initialization
171      */
172     public void setRuntimeServices(RuntimeServices rs)
173     {
174         stopOnFirstInvalidReference = rs.getConfiguration().getBoolean(
175                 EVENTHANDLER_INVALIDREFERENCE_EXCEPTION,
176                 false);        
177     }
178     
179 }