Velocity
  1. Velocity
  2. VELOCITY-818

Case-insensitive matching ${object.methodName} == ${object.methodname} == ${object.methodName}

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.7
    • Fix Version/s: None
    • Component/s: Engine
    • Labels:

      Description

      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 –

        Activity

        Mark S created issue -

          People

          • Assignee:
            Unassigned
            Reporter:
            Mark S
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:

              Time Tracking

              Estimated:
              Original Estimate - 4h
              4h
              Remaining:
              Remaining Estimate - 4h
              4h
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development