/*! ****************************************************************************** * * Pentaho Data Integration * * Copyright (C) 2002-2016 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.trans.steps.loadsave.validator; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.trans.steps.loadsave.getter.Getter; public class DefaultFieldLoadSaveValidatorFactory implements FieldLoadSaveValidatorFactory { private final Map<Getter<?>, FieldLoadSaveValidator<?>> getterMap; private final Map<String, FieldLoadSaveValidator<?>> typeMap; public DefaultFieldLoadSaveValidatorFactory() { this.typeMap = new HashMap<String, FieldLoadSaveValidator<?>>(); this.getterMap = new HashMap<Getter<?>, FieldLoadSaveValidator<?>>(); this.typeMap.put( String.class.getCanonicalName(), new StringLoadSaveValidator() ); this.typeMap.put( boolean.class.getCanonicalName(), new BooleanLoadSaveValidator() ); this.typeMap.put( Boolean.class.getCanonicalName(), new BooleanLoadSaveValidator() ); this.typeMap.put( int.class.getCanonicalName(), new IntLoadSaveValidator() ); this.typeMap.put( long.class.getCanonicalName(), new LongLoadSaveValidator() ); registerValidator( getName( List.class, String.class ), new ListLoadSaveValidator<String>( new StringLoadSaveValidator() ) { } ); registerValidator( String[].class.getCanonicalName(), new ArrayLoadSaveValidator<String>( new StringLoadSaveValidator() ) ); registerValidator( boolean[].class.getCanonicalName(), new PrimitiveBooleanArrayLoadSaveValidator( new BooleanLoadSaveValidator() ) ); registerValidator( Boolean[].class.getCanonicalName(), new ArrayLoadSaveValidator<Boolean>( new BooleanLoadSaveValidator() ) ); registerValidator( int[].class.getCanonicalName(), new PrimitiveIntArrayLoadSaveValidator( new IntLoadSaveValidator() ) ); registerValidator( Locale.class.getCanonicalName(), new LocaleLoadSaveValidator() ); registerValidator( DatabaseMeta.class.getCanonicalName(), new DatabaseMetaLoadSaveValidator() ); registerValidator( DatabaseMeta[].class.getCanonicalName(), new ArrayLoadSaveValidator<DatabaseMeta>( new DatabaseMetaLoadSaveValidator() ) ); registerValidator( Date.class.getCanonicalName(), new DateLoadSaveValidator() ); } @Override public void registerValidator( String typeString, FieldLoadSaveValidator<?> validator ) { this.typeMap.put( typeString, validator ); } public DefaultFieldLoadSaveValidatorFactory( Map<Getter<?>, FieldLoadSaveValidator<?>> map, Map<String, FieldLoadSaveValidator<?>> fieldLoadSaveValidatorTypeMap ) { this(); getterMap.putAll( map ); typeMap.putAll( fieldLoadSaveValidatorTypeMap ); } @SuppressWarnings( "unchecked" ) @Override public <T> FieldLoadSaveValidator<T> createValidator( Getter<T> getter ) { try { FieldLoadSaveValidator<?> validatorClass = getterMap.get( getter ); if ( validatorClass == null ) { Type type = getter.getGenericType(); validatorClass = typeMap.get( getName( type ) ); } if ( validatorClass == null ) { throw new RuntimeException( "Unable to find validator for " + getter.getGenericType() + " or " + getter ); } return (FieldLoadSaveValidator<T>) validatorClass; } catch ( Exception e ) { if ( e instanceof RuntimeException ) { throw (RuntimeException) e; } throw new RuntimeException( e ); } } @Override public String getName( Type type ) { if ( type instanceof Class<?> ) { return ( (Class<?>) type ).getCanonicalName(); } else { ParameterizedType type2 = (ParameterizedType) type; return getName( type2.getRawType() ) + getName( type2.getActualTypeArguments() ); } } private Object getName( Type[] actualTypeArguments ) { StringBuilder sb = new StringBuilder(); if ( actualTypeArguments.length > 0 ) { sb.append( "<" ); for ( Type parameter : actualTypeArguments ) { sb.append( getName( parameter ) ); sb.append( "," ); } sb.setLength( sb.length() - 1 ); sb.append( ">" ); } return sb.toString(); } @Override public String getName( Class<?> type, Class<?>... parameters ) { StringBuilder sb = new StringBuilder( type.getCanonicalName() ); if ( parameters.length > 0 ) { sb.append( "<" ); for ( Class<?> parameter : parameters ) { sb.append( parameter.getCanonicalName() ); sb.append( "," ); } sb.setLength( sb.length() - 1 ); sb.append( ">" ); } return sb.toString(); } }