blob: c76aa17b8160ec0949b9a80bd8758f721127e032 [file] [log] [blame]
package org.apache.velocity.app.event.implement;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.velocity.app.event.InvalidReferenceEventHandler;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.util.RuntimeServicesAware;
import org.apache.velocity.util.introspection.Info;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
/**
* Use this event handler to flag invalid references. Since this
* is intended to be used for a specific request, this should be
* used as a local event handler attached to a specific context
* instead of being globally defined in the Velocity properties file.
*
* <p>
* Note that InvalidReferenceHandler can be used
* in two modes. If the Velocity properties file contains the following:
* <pre>
* event_handler.invalid_references.exception = true
* </pre>
* then the event handler will throw a ParseErrorRuntimeException upon
* hitting the first invalid reference. This stops processing and is
* passed through to the application code. The ParseErrorRuntimeException
* contain information about the template name, line number, column number,
* and invalid reference.
*
* <p>
* If this configuration setting is false or omitted then the page
* will be processed as normal, but all invalid references will be collected
* in a List of InvalidReferenceInfo objects.
*
* <p>This feature should be regarded as experimental.
*
* @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
* @version $Id$
* @since 1.5
*/
public class ReportInvalidReferences implements
InvalidReferenceEventHandler, RuntimeServicesAware
{
public static final String EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "event_handler.invalid_references.exception";
@Deprecated
public static final String OLD_EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "eventhandler.invalidreference.exception";
/**
* List of InvalidReferenceInfo objects
*/
List invalidReferences = new ArrayList();
/**
* If true, stop at the first invalid reference and throw an exception.
*/
private boolean stopOnFirstInvalidReference = false;
/**
* Collect the error and/or throw an exception, depending on configuration.
*
* @param context the context when the reference was found invalid
* @param reference string with complete invalid reference
* @param object the object referred to, or null if not found
* @param property the property name from the reference
* @param info contains template, line, column details
* @return always returns null
* @throws ParseErrorException
*/
public Object invalidGetMethod(Context context, String reference, Object object,
String property, Info info)
{
reportInvalidReference(reference, info);
return null;
}
/**
* Collect the error and/or throw an exception, depending on configuration.
*
* @param context the context when the reference was found invalid
* @param reference complete invalid reference
* @param object the object referred to, or null if not found
* @param method the property name from the reference
* @param info contains template, line, column details
* @return always returns null
* @throws ParseErrorException
*/
public Object invalidMethod(Context context, String reference, Object object,
String method, Info info)
{
if (reference == null)
{
reportInvalidReference(object.getClass().getName() + "." + method, info);
}
else
{
reportInvalidReference(reference, info);
}
return null;
}
/**
* Collect the error and/or throw an exception, depending on configuration.
*
* @param context the context when the reference was found invalid
* @param leftreference left reference being assigned to
* @param rightreference invalid reference on the right
* @param info contains info on template, line, col
* @return loop to end -- always returns false
*/
public boolean invalidSetMethod(Context context, String leftreference, String rightreference, Info info)
{
reportInvalidReference(leftreference, info);
return false;
}
/**
* Check for an invalid reference and collect the error or throw an exception
* (depending on configuration).
*
* @param reference the invalid reference
* @param info line, column, template name
*/
private void reportInvalidReference(String reference, Info info)
{
InvalidReferenceInfo invalidReferenceInfo = new InvalidReferenceInfo(reference, info);
invalidReferences.add(invalidReferenceInfo);
if (stopOnFirstInvalidReference)
{
throw new ParseErrorException(
"Error in page - invalid reference. ",
info,
invalidReferenceInfo.getInvalidReference());
}
}
/**
* All invalid references during the processing of this page.
* @return a List of InvalidReferenceInfo objects
*/
public List getInvalidReferences()
{
return invalidReferences;
}
/**
* Called automatically when event cartridge is initialized.
* @param rs RuntimeServices object assigned during initialization
*/
public void setRuntimeServices(RuntimeServices rs)
{
Boolean b = rs.getConfiguration().getBoolean(OLD_EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, null);
if (b == null)
{
b = rs.getConfiguration().getBoolean(EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, false);
}
else
{
rs.getLog().warn("configuration key '{}' has been deprecated in favor of '{}'", OLD_EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, EVENTHANDLER_INVALIDREFERENCE_EXCEPTION);
}
stopOnFirstInvalidReference = b.booleanValue();
}
}