/******************************************************************************** * * 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.core.row.value; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.pentaho.di.core.exception.KettlePluginException; import org.pentaho.di.core.plugins.PluginInterface; import org.pentaho.di.core.plugins.PluginRegistry; import org.pentaho.di.core.row.ValueMetaInterface; /** * This class will hand out value meta objects from the plugin registry. * * @author matt * */ public class ValueMetaFactory { public static PluginRegistry pluginRegistry = PluginRegistry.getInstance(); public static ValueMetaInterface createValueMeta( String name, int type, int length, int precision ) throws KettlePluginException { PluginInterface stringPlugin = pluginRegistry.getPlugin( ValueMetaPluginType.class, String.valueOf( type ) ); if ( stringPlugin == null ) { throw new KettlePluginException( "Unable to locate value meta plugin of type (id) " + type ); } ValueMetaInterface valueMeta = pluginRegistry.loadClass( stringPlugin, ValueMetaInterface.class ); valueMeta.setName( name ); valueMeta.setLength( length, precision ); return valueMeta; } public static ValueMetaInterface createValueMeta( String name, int type ) throws KettlePluginException { return createValueMeta( name, type, -1, -1 ); } public static ValueMetaInterface createValueMeta( int type ) throws KettlePluginException { return createValueMeta( null, type, -1, -1 ); } public static ValueMetaInterface cloneValueMeta( ValueMetaInterface source ) throws KettlePluginException { return cloneValueMeta( source, source.getType() ); } public static ValueMetaInterface cloneValueMeta( ValueMetaInterface source, int targetType ) throws KettlePluginException { ValueMetaInterface target = null; // If we're Cloneable and not changing types, call clone() if ( source.getType() == targetType ) { target = source.clone(); } else { target = createValueMeta( source.getName(), targetType, source.getLength(), source.getPrecision() ); } target.setConversionMask( source.getConversionMask() ); target.setDecimalSymbol( source.getDecimalSymbol() ); target.setGroupingSymbol( source.getGroupingSymbol() ); target.setStorageType( source.getStorageType() ); if ( source.getStorageMetadata() != null ) { target.setStorageMetadata( cloneValueMeta( source.getStorageMetadata(), source .getStorageMetadata().getType() ) ); } target.setStringEncoding( source.getStringEncoding() ); target.setTrimType( source.getTrimType() ); target.setDateFormatLenient( source.isDateFormatLenient() ); target.setDateFormatLocale( source.getDateFormatLocale() ); target.setDateFormatTimeZone( source.getDateFormatTimeZone() ); target.setLenientStringToNumber( source.isLenientStringToNumber() ); target.setLargeTextField( source.isLargeTextField() ); target.setComments( source.getComments() ); target.setCaseInsensitive( source.isCaseInsensitive() ); target.setCollatorDisabled( source.isCollatorDisabled() ); target.setCollatorStrength( source.getCollatorStrength() ); target.setIndex( source.getIndex() ); target.setOrigin( source.getOrigin() ); target.setOriginalAutoIncrement( source.isOriginalAutoIncrement() ); target.setOriginalColumnType( source.getOriginalColumnType() ); target.setOriginalColumnTypeName( source.getOriginalColumnTypeName() ); target.setOriginalNullable( source.isOriginalNullable() ); target.setOriginalPrecision( source.getOriginalPrecision() ); target.setOriginalScale( source.getOriginalScale() ); target.setOriginalSigned( source.isOriginalSigned() ); return target; } public static String[] getValueMetaNames() { List<String> strings = new ArrayList<String>(); List<PluginInterface> plugins = pluginRegistry.getPlugins( ValueMetaPluginType.class ); for ( PluginInterface plugin : plugins ) { int id = Integer.valueOf( plugin.getIds()[0] ); if ( id > 0 && id != ValueMetaInterface.TYPE_SERIALIZABLE ) { strings.add( plugin.getName() ); } } return strings.toArray( new String[strings.size()] ); } public static String[] getAllValueMetaNames() { List<String> strings = new ArrayList<String>(); List<PluginInterface> plugins = pluginRegistry.getPlugins( ValueMetaPluginType.class ); for ( PluginInterface plugin : plugins ) { String id = plugin.getIds()[0]; if ( !( "0".equals( id ) ) ) { strings.add( plugin.getName() ); } } return strings.toArray( new String[strings.size()] ); } public static String getValueMetaName( int type ) { for ( PluginInterface plugin : pluginRegistry.getPlugins( ValueMetaPluginType.class ) ) { if ( Integer.toString( type ).equals( plugin.getIds()[0] ) ) { return plugin.getName(); } } return "-"; } public static int getIdForValueMeta( String valueMetaName ) { for ( PluginInterface plugin : pluginRegistry.getPlugins( ValueMetaPluginType.class ) ) { if ( valueMetaName != null && valueMetaName.equalsIgnoreCase( plugin.getName() ) ) { return Integer.valueOf( plugin.getIds()[0] ); } } return ValueMetaInterface.TYPE_NONE; } public static List<ValueMetaInterface> getValueMetaPluginClasses() throws KettlePluginException { List<ValueMetaInterface> list = new ArrayList<ValueMetaInterface>(); List<PluginInterface> plugins = pluginRegistry.getPlugins( ValueMetaPluginType.class ); for ( PluginInterface plugin : plugins ) { ValueMetaInterface valueMetaInterface = (ValueMetaInterface) pluginRegistry.loadClass( plugin ); list.add( valueMetaInterface ); } return list; } /** * <p>This method makes attempt to guess kettle value meta interface based on Object class. * This may be the case when we somehow obtain an Object as a result of any calculation, * and we are trying to assign some ValueMeta for it.</p> * * <p>As an example - we have target value meta Number (which is java Double under the hood) * and value as a BigDecimal.<br /> * This BigDecimal can be converted to a Double value.<br /> * we have {@link ValueMetaInterface#convertData(ValueMetaInterface, Object)} call for this * where is ValueMetaInterface object is our target value meta, Object is a BigDecimal - so * we need to pass ValueMetaBigNumber as a first parameter, value Object as a second and * as the result we will have target Double (ValueMetaNumber) value so we can safely * put it into output rowset.</p> * * <p>Something similar we had for ValueMetaBase.getValueFromSQLType(...) to guess value meta * for java sql type.</p> * * <p>Currently this method does not have support for plugin value meta. Hope if this approach * will be found usable this may be implemented later.</p> * * @param object object to guess applicable ValueMetaInterface. * @return * @see ValueMetaInterface if the kettle value meta is recognized, null otherwise. */ public static ValueMetaInterface guessValueMetaInterface( Object object ) { if ( object instanceof Number ) { // this is numeric object if ( object instanceof BigDecimal ) { return new ValueMetaBigNumber(); } else if ( object instanceof Double ) { return new ValueMetaNumber(); } else if ( object instanceof Long ) { return new ValueMetaInteger(); } } else if ( object instanceof String ) { return new ValueMetaString(); } else if ( object instanceof Date ) { return new ValueMetaDate(); } else if ( object instanceof Boolean ) { return new ValueMetaBoolean(); } else if ( object instanceof byte[] ) { return new ValueMetaBinary(); } // ask someone else return null; } }