    001    /*
    002     * Copyright (c) 2007-2014 Concurrent, Inc. All Rights Reserved.
    003     *
    004     * Project and contact information: http://www.cascading.org/
    005     *
    006     * This file is part of the Cascading project.
    007     *
    008     * Licensed under the Apache License, Version 2.0 (the "License");
    009     * you may not use this file except in compliance with the License.
    010     * You may obtain a copy of the License at
    011     *
    012     *     http://www.apache.org/licenses/LICENSE-2.0
    013     *
    014     * Unless required by applicable law or agreed to in writing, software
    015     * distributed under the License is distributed on an "AS IS" BASIS,
    016     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    017     * See the License for the specific language governing permissions and
    018     * limitations under the License.
    019     */
    020
    021    package cascading.operation.expression;
    022
    023    import java.beans.ConstructorProperties;
    024    import java.io.IOException;
    025    import java.io.StringReader;
    026
    027    import cascading.operation.OperationException;
    028    import cascading.tuple.Fields;
    029    import org.codehaus.commons.compiler.CompileException;
    030    import org.codehaus.janino.ExpressionEvaluator;
    031    import org.codehaus.janino.Scanner;
    032    import org.codehaus.janino.ScriptEvaluator;
    033
    034    import static cascading.tuple.coerce.Coercions.asClass;
    035
    036    /**
    037     * Class ExpressionOperation is the base class for {@link ExpressionFunction}, {@link ExpressionFilter},
    038     * {@link cascading.operation.assertion.AssertExpression}.
    039     */
    040    public class ExpressionOperation extends ScriptOperation
    041      {
    042      @ConstructorProperties( {"expression"} )
    043      protected ExpressionOperation( String expression )
    044        {
    045        super( ANY, expression, Boolean.class );
    046        }
    047
    048      @ConstructorProperties({"fieldDeclaration", "expression"})
    049      protected ExpressionOperation( Fields fieldDeclaration, String expression )
    050        {
    051        super( ANY, fieldDeclaration, expression, asClass( fieldDeclaration.getType( 0 ) ) );
    052        }
    053
    054      @ConstructorProperties({"fieldDeclaration", "expression", "parameterType"})
    055      protected ExpressionOperation( Fields fieldDeclaration, String expression, Class parameterType )
    056        {
    057        super( 1, fieldDeclaration, expression, asClass( fieldDeclaration.getType( 0 ) ), null,
    058          new Class[]{parameterType} );
    059        }
    060
    061      @ConstructorProperties({"fieldDeclaration", "expression", "parameterNames", "parameterTypes"})
    062      protected ExpressionOperation( Fields fieldDeclaration, String expression, String[] parameterNames, Class[] parameterTypes )
    063        {
    064        super( parameterTypes.length, fieldDeclaration, expression, asClass( fieldDeclaration.getType( 0 ) ), parameterNames, parameterTypes );
    065        }
    066
    067      @ConstructorProperties({"expression", "parameterType"})
    068      protected ExpressionOperation( String expression, Class parameterType )
    069        {
    070        super( 1, expression, Object.class, null, new Class[]{parameterType} );
    071        }
    072
    073      @ConstructorProperties({"expression", "parameterNames", "parameterTypes"})
    074      protected ExpressionOperation( String expression, String[] parameterNames, Class[] parameterTypes )
    075        {
    076        super( parameterTypes.length, expression, Object.class, parameterNames, parameterTypes );
    077        }
    078
    079      public String getExpression()
    080        {
    081        return getBlock();
    082        }
    083
    084      protected String[] guessParameterNames() throws CompileException, IOException
    085        {
    086        return ExpressionEvaluator.guessParameterNames( new Scanner( "expressionEval", new StringReader( block ) ) );
    087        }
    088
    089      @Override
    090      protected ScriptEvaluator getEvaluator( Class returnType, String[] parameterNames, Class[] parameterTypes )
    091        {
    092        try
    093          {
    094          return new ExpressionEvaluator( block, getReturnType(), parameterNames, parameterTypes );
    095          }
    096        catch( CompileException exception )
    097          {
    098          throw new OperationException( "could not compile expression: " + block, exception );
    099          }
    100        }
    101      }