/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2017 by Pentaho : http://www.pentaho.com * ******************************************************************************* * * 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.pentaho.di.core.injection; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Before; import org.junit.Test; import org.pentaho.di.core.RowMetaAndData; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.injection.bean.BeanInjectionInfo; import org.pentaho.di.core.injection.bean.BeanInjector; import org.pentaho.di.core.injection.inheritance.MetaBeanChild; import org.pentaho.di.core.logging.KettleLogStore; import org.pentaho.di.core.row.RowMeta; import org.pentaho.di.core.row.value.ValueMetaString; public class MetaAnnotationInjectionTest { private static final String FIELD_ONE = "FIELD_ONE"; private static final String COMPLEX_NAME = "COMPLEX_NAME"; private static final String TEST_NAME = "TEST_NAME"; @Before public void before() { KettleLogStore.init(); } @Test public void testInjectionDescription() throws Exception { BeanInjectionInfo ri = new BeanInjectionInfo( MetaBeanLevel1.class ); assertEquals( 3, ri.getGroups().size() ); assertEquals( "", ri.getGroups().get( 0 ).getName() ); assertEquals( "FILENAME_LINES", ri.getGroups().get( 1 ).getName() ); assertEquals( "FILENAME_LINES2", ri.getGroups().get( 2 ).getName() ); assertTrue( ri.getProperties().containsKey( "SEPARATOR" ) ); assertTrue( ri.getProperties().containsKey( "FILENAME" ) ); assertTrue( ri.getProperties().containsKey( "BASE" ) ); assertTrue( ri.getProperties().containsKey( "FIRST" ) ); assertEquals( "FILENAME_LINES", ri.getProperties().get( "FILENAME" ).getGroupName() ); assertEquals( "!DESCRIPTION!", ri.getDescription( "DESCRIPTION" ) ); } @Test public void testInjectionSets() throws Exception { MetaBeanLevel1 obj = new MetaBeanLevel1(); RowMeta meta = new RowMeta(); meta.addValueMeta( new ValueMetaString( "f1" ) ); meta.addValueMeta( new ValueMetaString( "f2" ) ); meta.addValueMeta( new ValueMetaString( "fstrint" ) ); meta.addValueMeta( new ValueMetaString( "fstrlong" ) ); meta.addValueMeta( new ValueMetaString( "fstrboolean" ) ); // TODO STLOCALE List<RowMetaAndData> rows = new ArrayList<>(); rows.add( new RowMetaAndData( meta, "<sep>", "/tmp/file.txt", "123", "1234567891213", "y" ) ); rows.add( new RowMetaAndData( meta, "<sep>", "/tmp/file2.txt", "123", "1234567891213", "y" ) ); BeanInjector inj = buildBeanInjectorFor( MetaBeanLevel1.class ); inj.setProperty( obj, "SEPARATOR", rows, "f1" ); inj.setProperty( obj, "FILENAME", rows, "f2" ); inj.setProperty( obj, "FILENAME_ARRAY", rows, "f2" ); inj.setProperty( obj, "FBOOLEAN", rows, "fstrboolean" ); inj.setProperty( obj, "FINT", rows, "fstrint" ); inj.setProperty( obj, "FLONG", rows, "fstrlong" ); inj.setProperty( obj, "FIRST", rows, "fstrint" ); assertEquals( "<sep>", obj.getSub().getSeparator() ); assertEquals( "/tmp/file.txt", obj.getSub().getFiles()[0].getName() ); assertTrue( obj.fboolean ); assertEquals( 123, obj.fint ); assertEquals( 1234567891213L, obj.flong ); assertEquals( "123", obj.getSub().first() ); assertArrayEquals( new String[] { "/tmp/file.txt", "/tmp/file2.txt" }, obj.getSub().getFilenames() ); } @Test public void testInjectionConstant() throws Exception { MetaBeanLevel1 obj = new MetaBeanLevel1(); BeanInjector inj = buildBeanInjectorFor( MetaBeanLevel1.class ); inj.setProperty( obj, "SEPARATOR", null, "<sep>" ); inj.setProperty( obj, "FINT", null, "123" ); inj.setProperty( obj, "FLONG", null, "1234567891213" ); inj.setProperty( obj, "FBOOLEAN", null, "true" ); inj.setProperty( obj, "FILENAME", null, "f1" ); inj.setProperty( obj, "FILENAME_ARRAY", null, "f2" ); assertEquals( "<sep>", obj.getSub().getSeparator() ); assertTrue( obj.fboolean ); assertEquals( 123, obj.fint ); assertEquals( 1234567891213L, obj.flong ); assertNull( obj.getSub().getFiles() ); assertNull( obj.getSub().getFilenames() ); obj.getSub().files = new MetaBeanLevel3[] { new MetaBeanLevel3(), new MetaBeanLevel3() }; obj.getSub().filenames = new String[] { "", "", "" }; inj.setProperty( obj, "FILENAME", null, "f1" ); inj.setProperty( obj, "FILENAME_ARRAY", null, "f2" ); assertEquals( 2, obj.getSub().getFiles().length ); assertEquals( "f1", obj.getSub().getFiles()[0].getName() ); assertEquals( "f1", obj.getSub().getFiles()[1].getName() ); assertArrayEquals( new String[] { "f2", "f2", "f2" }, obj.getSub().getFilenames() ); } @Test public void testInjectionForArrayPropertyWithoutDefaultConstructor_class_parameter() throws KettleException { BeanInjector beanInjector = buildBeanInjectorFor( MetadataBean.class ); MetadataBean targetBean = new MetadataBean(); beanInjector.setProperty( targetBean, COMPLEX_NAME, createRowMetaAndData(), FIELD_ONE ); assertNotNull( targetBean.getComplexField() ); assertTrue( targetBean.getComplexField().length == 1 ); assertEquals( TEST_NAME, targetBean.getComplexField()[0].getFieldName() ); } @Test public void testInjectionForArrayPropertyWithoutDefaultConstructor_interface_parameter() throws KettleException { BeanInjector beanInjector = buildBeanInjectorFor( MetadataBeanImplementsInterface.class ); MetadataBeanImplementsInterface targetBean = new MetadataBeanImplementsInterface(); beanInjector.setProperty( targetBean, COMPLEX_NAME, createRowMetaAndData(), FIELD_ONE ); assertNotNull( targetBean.getComplexField() ); assertTrue( targetBean.getComplexField().length == 1 ); assertEquals( TEST_NAME, targetBean.getComplexField()[0].getFieldName() ); } @Test public void testWrongDeclarations() throws Exception { try { new BeanInjectionInfo( MetaBeanWrong1.class ); fail(); } catch ( Exception ex ) { } try { new BeanInjectionInfo( MetaBeanWrong2.class ); fail(); } catch ( Exception ex ) { } try { new BeanInjectionInfo( MetaBeanWrong3.class ); fail(); } catch ( Exception ex ) { } try { new BeanInjectionInfo( MetaBeanWrong4.class ); fail(); } catch ( Exception ex ) { } try { new BeanInjectionInfo( MetaBeanWrong5.class ); fail(); } catch ( Exception ex ) { } try { new BeanInjectionInfo( MetaBeanWrong6.class ); fail(); } catch ( Exception ex ) { } try { new BeanInjectionInfo( MetaBeanWrong7.class ); fail(); } catch ( Exception ex ) { ex.printStackTrace(); } } @Test public void testGenerics() throws Exception { BeanInjectionInfo ri = new BeanInjectionInfo( MetaBeanChild.class ); assertTrue( ri.getProperties().size() == 7 ); assertTrue( ri.getProperties().containsKey( "BASE_ITEM_NAME" ) ); assertTrue( ri.getProperties().containsKey( "ITEM_CHILD_NAME" ) ); assertTrue( ri.getProperties().containsKey( "A" ) ); assertTrue( ri.getProperties().containsKey( "ITEM.BASE_ITEM_NAME" ) ); assertTrue( ri.getProperties().containsKey( "ITEM.ITEM_CHILD_NAME" ) ); assertTrue( ri.getProperties().containsKey( "SUB.BASE_ITEM_NAME" ) ); assertTrue( ri.getProperties().containsKey( "SUB.ITEM_CHILD_NAME" ) ); assertEquals( String.class, ri.getProperties().get( "A" ).getPropertyClass() ); } private static BeanInjector buildBeanInjectorFor( Class<?> clazz ) { BeanInjectionInfo metaBeanInfo = new BeanInjectionInfo( clazz ); return new BeanInjector( metaBeanInfo ); } private static List<RowMetaAndData> createRowMetaAndData() { RowMeta meta = new RowMeta(); meta.addValueMeta( new ValueMetaString( FIELD_ONE ) ); return Collections.singletonList( new RowMetaAndData( meta, TEST_NAME ) ); } private static interface MetadataInterface { } @InjectionSupported( localizationPrefix = "", groups = "COMPLEX" ) public static class MetadataBean { @InjectionDeep private ComplexField[] complexField; public ComplexField[] getComplexField() { return complexField; } public void setComplexField( ComplexField[] complexField ) { this.complexField = complexField; } } public static class ComplexField { @Injection( name = "COMPLEX_NAME", group = "COMPLEX" ) private String fieldName; private final MetadataBean parentMeta; public ComplexField( MetadataBean parentMeta ) { this.parentMeta = parentMeta; } public String getFieldName() { return fieldName; } public void setFieldName( String fieldName ) { this.fieldName = fieldName; } public MetadataBean getParentMeta() { return parentMeta; } } @InjectionSupported( localizationPrefix = "", groups = "COMPLEX" ) public static class MetadataBeanImplementsInterface implements MetadataInterface { @InjectionDeep private ComplexFieldWithInterfaceArg[] complexField; public ComplexFieldWithInterfaceArg[] getComplexField() { return complexField; } public void setComplexField( ComplexFieldWithInterfaceArg[] complexField ) { this.complexField = complexField; } } public static class ComplexFieldWithInterfaceArg { @Injection( name = "COMPLEX_NAME", group = "COMPLEX" ) private String fieldName; private final MetadataInterface parentMeta; public ComplexFieldWithInterfaceArg( MetadataInterface parentMeta ) { this.parentMeta = parentMeta; } public String getFieldName() { return fieldName; } public void setFieldName( String fieldName ) { this.fieldName = fieldName; } public MetadataInterface getParentMeta() { return parentMeta; } } }