/* * Copyright 2014 the original author or authors. * * Licensed 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. */ package org.springframework.data.hadoop.store.expression; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.junit.Test; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.MethodResolver; import org.springframework.expression.spel.SpelCompilerMode; import org.springframework.expression.spel.SpelParserConfiguration; import org.springframework.expression.spel.standard.SpelCompiler; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; /** * Various coverage tests for spel compiled expressions. * * @author Janne Valkealahti * */ public class SpelCompileCoverageTests { @Test public void testCompilables() throws Exception { Message<String> rootObject = MessageBuilder.withPayload("jee-juu").setHeader("region", "us").build(); Message<Object> wrappedRootObject = new MessageExpressionMethods.MessageWrappedMessage(rootObject); Long timestamp = rootObject.getHeaders().getTimestamp(); assertExpression("path('dummy','partition')", "dummy/partition", true); assertExpression("path('dummy',range(1,{3,5,10}))", "dummy/3_range", true); assertExpression("'dummy'", "dummy", true); assertExpression("1 + 1", "2", true); assertExpression("'dummy' + '/' + 'partition'", "dummy/partition", true); assertExpression("'dummy' + 'partition'", "dummypartition", true); assertExpression("'dummy/' + range(1,{3,5,10})", "dummy/3_range", true); assertExpression("payload.split('-')[0]", "jee", true); assertExpression("path(payload.split('-')[0])", "jee", true); String nowYYYYMMdd = new SimpleDateFormat("yyyy/MM/dd").format(new Date()); String expression = "path(dateFormat('yyyy/MM/dd'),list(payload.split('-')[0],{{'JEE','jee'},{'JUU','juu'}}))"; assertExpression(wrappedRootObject, expression, nowYYYYMMdd+"/JEE_list", true); expression = "path(dateFormat('yyyy/MM/dd'),list(payload.split('-')[0],{{'1TO5','APP1','APP2','APP3','APP4','jee'},{'6TO10','APP6','APP7','APP8','APP9','APP10'}}))"; assertExpression(wrappedRootObject, expression, nowYYYYMMdd+"/1TO5_list", true); assertExpression("path(T(org.springframework.util.StringUtils).split(payload,'-')[0])", "jee", true); assertExpression("list('APP1',{{'1TO5','APP1'}})", "1TO5_list", true); assertExpression(wrappedRootObject, "region", "us", true); assertExpression(wrappedRootObject, "headers[region]", "us", true); String nowYYYY = new SimpleDateFormat("yyyy").format(new Date(timestamp)); assertExpression(wrappedRootObject, "headers[region].toString() + '/' + dateFormat('yyyy', headers[timestamp])", "us/" + nowYYYY, true); } @Test public void testNonCompilables() throws Exception { } private static void assertExpression(String expression, String result, boolean compilable) throws Exception { Message<String> message = MessageBuilder.withPayload("jee-juu").build(); assertExpression(message, expression, result, compilable); } private static void assertExpression(Object rootObject, String expression, String result, boolean compilable) throws Exception { SpelParserConfiguration spelParserConfiguration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null); ExpressionParser parser = new SpelExpressionParser(spelParserConfiguration); StandardEvaluationContext context = new StandardEvaluationContext(); MessagePartitionKeyMethodResolver resolver = new MessagePartitionKeyMethodResolver(); List<MethodResolver> methodResolvers = new ArrayList<MethodResolver>(); methodResolvers.add(resolver); context.setMethodResolvers(methodResolvers); context.addPropertyAccessor(new MessagePartitionKeyPropertyAccessor()); Expression exp = parser.parseExpression(expression); // looks like we need to call three times before // expression is compiled and we can check it assertThat(exp.getValue(context, rootObject, String.class), is(result)); assertThat(exp.getValue(context, rootObject, String.class), is(result)); assertThat(exp.getValue(context, rootObject, String.class), is(result)); if (compilable) { assertCanCompile(exp); } else { assertCantCompile(exp); } } private static void assertCanCompile(Expression expression) { assertTrue("Expression \"" + expression.getExpressionString() + "\" not compilable", SpelCompiler.compile(expression)); } private static void assertCantCompile(Expression expression) { assertFalse("Expression \"" + expression.getExpressionString() + "\" is compilable", SpelCompiler.compile(expression)); } }