    001/*
    002 * Copyright (c) 2007-2017 Xplenty, 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
    021package cascading.operation.expression;
    022
    023import java.beans.ConstructorProperties;
    024import java.io.IOException;
    025import java.io.StringReader;
    026
    027import cascading.operation.OperationException;
    028import cascading.tuple.Fields;
    029import org.codehaus.commons.compiler.CompileException;
    030import org.codehaus.janino.ExpressionEvaluator;
    031import org.codehaus.janino.Scanner;
    032import org.codehaus.janino.ScriptEvaluator;
    033
    034import 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 */
    040public 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  }