You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by "Sergiu Dumitriu (JIRA)" <ji...@apache.org> on 2015/06/03 05:38:49 UTC

[jira] [Commented] (VELOCITY-818) Case-insensitive matching ${object.methodName} == ${object.methodname} == ${object.methodName}

    [ https://issues.apache.org/jira/browse/VELOCITY-818?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14570219#comment-14570219 ] 

Sergiu Dumitriu commented on VELOCITY-818:
------------------------------------------

I agree that it doesn't make sense as a default language feature, but this could be an optional uberspector that could be enabled in the configuration.

> Case-insensitive matching ${object.methodName} == ${object.methodname} == ${object.methodName}
> ----------------------------------------------------------------------------------------------
>
>                 Key: VELOCITY-818
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-818
>             Project: Velocity
>          Issue Type: New Feature
>          Components: Engine
>    Affects Versions: 1.7
>            Reporter: Mark S
>              Labels: api-change
>   Original Estimate: 4h
>  Remaining Estimate: 4h
>
> I thought I would share the following code with the Apache Velocity community. 
> Currently there is no easy way for Velocity to do a case-insensitive match on a property or method.  Below is my implementation to achieve this.
> VelocityContext velocityContext = new VelocityContext();
> {
>     context.put( "aNumericValue", "1234567890" );
> }
> | If String template =                 | Then String evaluatedTemplate =  |
> | ${aNumericValue}                     | 1234567890                       |
> | ${anumericvalue}                     | 1234567890                       |
> | ${anumericValue}                     | 1234567890                       |
> | ${aNumericvalue}                     | 1234567890                       |
> | ${aNumericValue.toString()}          | 1234567890                       |
> | ${anumericvalue.tostring()}          | 1234567890                       |
> -- Setup Snippet -- 
> Properties p = new Properties();
> p.setProperty( RuntimeConstants.INPUT_ENCODING, DEFAULT_ENCODING );
> p.setProperty( RuntimeConstants.OUTPUT_ENCODING, DEFAULT_ENCODING ); 
> p.setProperty( RuntimeConstants.UBERSPECT_CLASSNAME,
>                "custom.CustomSecureUberspector" ); //$NON-NLS-1$
> 	       
> VelocityEngine engine = new VelocityEngine( p );
> engine.init(); 
> RuntimeInstance ri = new RuntimeInstance();
> ri.init( p );
> uberspector = (CustomSecureUberspector)ri.getUberspect();
> -- Setup Snippet -- 
> -- Call Snippet -- 
> VelocityContext velocityContext = new VelocityContext();
> {
>     context.put( "aNumericValue", "1234567890" );
> }
> EventCartridge eventCartridge = new EventCartridge();
> eventCartridge.addEventHandler( new SloppyNameReferenceEventHandler( uberspector ) );
> eventCartridge.addEventHandler( new NullValueReferenceInsertionEventHandler() );
> eventCartridge.attachToContext( velocityContext );
> String template = "${aNumericvalue}";
> StringWriter velocityWriter = new StringWriter();
> velocityEngine.evaluate( velocityContext, velocityWriter, "LOG", template );
> String evaluatedTemplate = velocityWriter.toString(); 
> -- Call Snippet -- 
> -- Supporting Classes Snippet -- 
> package custom;
> import org.apache.velocity.util.introspection.SecureIntrospectorImpl;
> import org.apache.velocity.util.introspection.SecureUberspector;
> public class CustomSecureUberspector extends SecureUberspector
> {
>     public SecureIntrospectorImpl getSecureIntrospector()
>     {
>         return (SecureIntrospectorImpl)introspector;
>     }
> }
> package custom;
> import java.lang.reflect.Method;
> import java.util.ArrayList;
> import java.util.List;
> import org.apache.velocity.app.event.InvalidReferenceEventHandler;
> import org.apache.velocity.context.Context;
> import org.apache.velocity.util.introspection.Info;
> import org.apache.velocity.util.introspection.SecureIntrospectorImpl;
> import custom.CustomSecureUberspector;
> @SuppressWarnings( { "unused" } )
> public class SloppyNameReferenceEventHandler implements InvalidReferenceEventHandler
> {
>     protected CustomSecureUberspector uberspector;
>     public SloppyNameReferenceEventHandler( CustomSecureUberspector uberspector )
>     {
>         this.uberspector = uberspector;
>     }
>     @Override
>     public Object invalidGetMethod( Context context, String reference, Object object, String property, Info info )
>     {
>         try
>         {
>             return callMethod( object, property );
>         }
>         catch ( Exception e )
>         {
>             return null;
>         }
>     }
>     @Override
>     public boolean invalidSetMethod( Context context, String leftReference, String rightReference, Info info )
>     {
>         // Do nothing
>         return false;
>     }
>     @Override
>     public Object invalidMethod( Context context, String reference, Object object, String method, Info info )
>     {
>         try
>         {
>             return callMethod( object, method );
>         }
>         catch ( Exception e )
>         {
>             return null;
>         }
>     }
>     protected Object callMethod( Object object, String method )
>         throws Exception
>     {
>         if ( null == object || null == method )
>         {
>             return null;
>         }
>         List<String> possibleMethodMatches = findCaseInsensitiveMethodsForObject( object, method, "get" + method ); //$NON-NLS-1$
>         SecureIntrospectorImpl secureIntrospectorImpl = uberspector.getSecureIntrospector();
>         for ( String possibleMethodMatch : possibleMethodMatches )
>         {
>             if ( secureIntrospectorImpl.checkObjectExecutePermission( object.getClass(), possibleMethodMatch ) )
>             {
>                 Method[] objectMethods = object.getClass().getMethods();
>                 for ( int i = 0; i < objectMethods.length; i++ )
>                 {
>                     if ( possibleMethodMatch.equals( objectMethods[i].getName() ) )
>                     {
>                         return objectMethods[i].invoke( object );
>                     }
>                 }
>             }
>         }
>         return null;
>     }
>     @SuppressWarnings( "static-method" )
>     protected List<String> findCaseInsensitiveMethodsForObject( Object object, String ... methodNames )
>     {
>         List<String> methodMatches = new ArrayList<String>();
>         Method[] methods = object.getClass().getMethods();
>         for ( int i = 0; i < methods.length; i++ )
>         {
>             String objectMethodName = methods[i].getName();
>             String objectMethodNameInLowerCase = objectMethodName.toLowerCase();
>             for ( int j = 0; j < methodNames.length; j++ )
>             {
>                 if ( objectMethodNameInLowerCase.equals( methodNames[j].toLowerCase() ) )
>                 {
>                     methodMatches.add( objectMethodName );
>                 }
>             }
>         }
>         return methodMatches;
>     }
> }
>     
> package custom;
> import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
> public class NullValueReferenceInsertionEventHandler implements ReferenceInsertionEventHandler
> {
>     @Override
>     public Object referenceInsert( String reference, Object value )
>     {
>         if ( null == value )
>         {
>         return String.valueOf( reference );
>         }
>         return value;
>     }
> }
> -- Supporting Classes Snippet -- 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
For additional commands, e-mail: dev-help@velocity.apache.org