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 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 }