All Downloads are FREE. Search and download functionalities are using the official Maven repository.

au.net.causal.projo.prefs.transform.FloatingPointCastTransformer Maven / Gradle / Ivy

The newest version!
package au.net.causal.projo.prefs.transform;

import java.math.BigDecimal;
import java.util.List;

import au.net.causal.projo.prefs.DataTypeSupport;
import au.net.causal.projo.prefs.PreferenceKeyMetadata;
import au.net.causal.projo.prefs.PreferencesException;
import au.net.causal.projo.prefs.TransformDataTypeSupportChain;
import au.net.causal.projo.prefs.TransformGetChain;
import au.net.causal.projo.prefs.TransformPutChain;
import au.net.causal.projo.prefs.TransformRemoveChain;
import au.net.causal.projo.prefs.TransformResult;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.primitives.Primitives;

/**
 * Transforms between floating point numeric data types to fit the native store.  This is useful when a store only supports a larger data type but support is needed
 * for the smaller ones.
 * 

* * For example, if the native store supports {@link Double}s, then this transformer will add support for the smaller numeric {@link Float} * performing numeric conversions where appropriate. * * @author prunge */ public class FloatingPointCastTransformer implements PreferenceTransformer { private final List> dataTypes = ImmutableList.>of(BigDecimal.class, Double.class, Float.class); @Override public TransformResult applyGet(String key, PreferenceKeyMetadata keyMetadata, TransformGetChain chain) throws PreferencesException { Class bestMatch = findClosestNativeSupportForDataType(keyMetadata, chain); if (bestMatch == null) return(null); Number nValue = chain.getValue(key, keyMetadata.withDataType(bestMatch)); if (nValue == null) return(new TransformResult<>(null)); Class keyType = Primitives.wrap(keyMetadata.getDataType().getRawType()).asSubclass(Number.class); //Need to convert the native value nValue to key's data type if (BigDecimal.class.equals(keyType)) return(new TransformResult<>((T)BigDecimal.valueOf(nValue.doubleValue()))); else if (Double.class.equals(keyType)) return(new TransformResult<>((T)Double.valueOf(nValue.doubleValue()))); else if (Float.class.equals(keyType)) return(new TransformResult<>((T)Float.valueOf(nValue.floatValue()))); else ///Should never get here throw new Error("Unknokwn bestMatch data type."); } @Override public boolean applyPut(String key, T value, PreferenceKeyMetadata keyMetadata, TransformPutChain chain) throws PreferencesException { Class bestMatch = findClosestNativeSupportForDataType(keyMetadata, chain); if (bestMatch == null) return(false); Number nValue = (Number)value; if (nValue == null) chain.putValue(key, null, keyMetadata.withDataType(bestMatch)); else if (BigDecimal.class.equals(bestMatch)) chain.putValue(key, BigDecimal.valueOf(nValue.doubleValue()), keyMetadata.withDataType(BigDecimal.class)); else if (Double.class.equals(bestMatch)) chain.putValue(key, Double.valueOf(nValue.doubleValue()), keyMetadata.withDataType(Double.class)); else if (Float.class.equals(bestMatch)) chain.putValue(key, Float.valueOf(nValue.floatValue()), keyMetadata.withDataType(Float.class)); else ///Should never get here throw new Error("Unknokwn bestMatch data type."); return(true); } @Override public boolean applyRemove(String key, PreferenceKeyMetadata keyMetadata, TransformRemoveChain chain) throws PreferencesException { Class bestMatch = findClosestNativeSupportForDataType(keyMetadata, chain); if (bestMatch == null) return(false); chain.removeValue(key, keyMetadata.withDataType(bestMatch)); return(true); } @Override public DataTypeSupport applyDataTypeSupport(PreferenceKeyMetadata keyMetadata, TransformDataTypeSupportChain chain) throws PreferencesException { //If not a numeric data type then no support from this transformer Class bestMatch = findClosestNativeSupportForDataType(keyMetadata, chain); if (bestMatch == null) return(null); //If we get here the transform will work return(DataTypeSupport.ADD_SUPPORT); } private Class findClosestNativeSupportForDataType(PreferenceKeyMetadata keyMetadata, TransformDataTypeSupportChain chain) throws PreferencesException { Class keyType = keyMetadata.getDataType().getRawType(); keyType = Primitives.wrap(keyType); int dataTypeIndex = dataTypes.indexOf(keyType); if (dataTypeIndex < 0) return(null); //If there is native support for the key type itself then this transform shouldn't touch it if (chain.isDataTypeSupportedNatively(keyMetadata.withDataType(keyType))) //Normalized data type return(null); //Find the next biggest data type supported natively List> supportForKey = dataTypes.subList(0, dataTypeIndex + 1); supportForKey = Lists.reverse(supportForKey); //Now supportForKey contains all data types that can support the key type, ordered from closest match up to largest data type //Go through and ask for native support until we find one for (Class curDataType : supportForKey) { if (chain.isDataTypeSupportedNatively(keyMetadata.withDataType(curDataType))) return(curDataType); } return(null); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy