/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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 com.alibaba.citrus.turbine.dataresolver.impl; import static com.alibaba.citrus.test.TestUtil.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static org.junit.Assert.*; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collection; import java.util.List; import com.alibaba.citrus.service.dataresolver.DataResolverContext; import com.alibaba.citrus.service.dataresolver.DataResolverException; import com.alibaba.citrus.turbine.dataresolver.FormGroup; import com.alibaba.citrus.turbine.dataresolver.Param; import com.alibaba.citrus.turbine.dataresolver.Params; import net.sf.cglib.reflect.FastConstructor; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class DataResolverUtilTests { private final Class<Annotation> annotationType; private final int index; private final boolean hasOptionalArgs; private final Object result; private DataResolverContext context; @SuppressWarnings("unchecked") public DataResolverUtilTests(Class<? extends Annotation> annotationType, int index, boolean hasOptionalArgs, Object result) { this.annotationType = (Class<Annotation>) annotationType; this.index = index; this.hasOptionalArgs = hasOptionalArgs; this.result = result; } @Parameters public static Collection<Object[]> data() { List<Object[]> data = createArrayList(); // no name() method add(data, Params.class, 0, false, new IllegalArgumentException("could not get value: @Params.name()")); // no name add(data, Param.class, 0, false, new IllegalArgumentException("missing @Param's name: DataResolverContext")); add(data, FormGroup.class, 0, false, new IllegalArgumentException( "missing @FormGroup's name: DataResolverContext")); // noOptionalArgs add(data, Param.class, 1, false, "myname"); add(data, Param.class, 2, false, "myname"); add(data, Param.class, 3, false, "myname"); add(data, FormGroup.class, 1, false, "mygroupname"); add(data, FormGroup.class, 2, false, "mygroupname"); add(data, FormGroup.class, 3, false, "mygroupname"); // hasOptionalArgs add(data, Param.class, 1, true, new IllegalArgumentException( "use @Param(name=\"myname\") instead of @Param(value=\"myname\"): DataResolverContext")); add(data, Param.class, 2, true, new IllegalArgumentException( "use @Param(name=\"myname\") instead of @Param(value=\"myname\"): DataResolverContext")); add(data, Param.class, 3, true, "myname"); add(data, FormGroup.class, 1, true, new IllegalArgumentException( "use @FormGroup(name=\"mygroupname\") instead of @FormGroup(value=\"mygroupname\"): " + "DataResolverContext")); add(data, FormGroup.class, 2, true, new IllegalArgumentException( "use @FormGroup(name=\"mygroupname\") instead of @FormGroup(value=\"mygroupname\"): " + "DataResolverContext")); add(data, FormGroup.class, 3, true, "mygroupname"); return data; } private static void add(List<Object[]> data, Object... values) { data.add(values); } @Before public void init() throws Exception { context = new DataResolverContext(DataResolverUtilTests.class, null, null); } @Test public void getAnnotationNameOrValue() { Annotation a = getAnnotation(annotationType, index); if (result instanceof Exception) { try { DataResolverUtil.getAnnotationNameOrValue(annotationType, a, context, hasOptionalArgs); fail(); } catch (Exception e) { assertThat(e, exception(((Exception) result).getClass(), ((Exception) result).getMessage())); } } else { assertEquals(result, DataResolverUtil.getAnnotationNameOrValue(annotationType, a, context, hasOptionalArgs)); } } private <A extends Annotation> A getAnnotation(Class<A> annotationType, int index) { String methodName = annotationType.getSimpleName().toLowerCase(); Method method = null; for (Method m : DataResolverUtilTests.class.getDeclaredMethods()) { if (m.getName().equals(methodName)) { method = m; } } return annotationType.cast(method.getParameterAnnotations()[index][0]); } @SuppressWarnings("unused") private static void param(@Param String s1, @Param("myname") String s2, @Param(value = "myname") String s3, @Param(name = "myname") String s4) { } @SuppressWarnings("unused") private static void params(@Params String s1) { } @SuppressWarnings("unused") private static void formgroup(@FormGroup String s1, @FormGroup("mygroupname") String s2, @FormGroup(value = "mygroupname") String s3, @FormGroup(name = "mygroupname") String s4) { } @Test public void getFastConstructor_and_newInstance() throws Exception { FastConstructor fc = DataResolverUtil.getFastConstructor(MyData.class); assertTrue(DataResolverUtil.newInstance(fc) instanceof MyData); } @Test public void getFastConstructor_abstract() throws Exception { try { DataResolverUtil.getFastConstructor(MyDataAbstract.class); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("Class to set properties should be public and concrete: ")); } } @Test public void getFastConstructor_private() throws Exception { try { DataResolverUtil.getFastConstructor(MyDataPrivate.class); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("Class to set properties should be public and concrete: ")); } } @Test public void getFastConstructor_noDefaultConstructor() throws Exception { try { DataResolverUtil.getFastConstructor(MyDataNoDefaultConstructor.class); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("Class to set properties has no default constructor:")); } } @Test public void newInstance_null() throws Exception { try { DataResolverUtil.newInstance(null); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("fastConstructor==null")); } } @Test public void newInstance_failed() throws Exception { try { DataResolverUtil.newInstance(DataResolverUtil.getFastConstructor(MyDataFailedConstructor.class)); fail(); } catch (DataResolverException e) { assertThat( e, exception(IOException.class, "Failed to create instance of class " + MyDataFailedConstructor.class.getName())); } } public static class MyData { } public static class MyDataFailedConstructor { public MyDataFailedConstructor() throws Exception { throw new IOException(); } } public static abstract class MyDataAbstract { } public static class MyDataNoDefaultConstructor { MyDataNoDefaultConstructor(String name) { } } private static class MyDataPrivate { } }