Package au.net.causal.projo.prefs.transform

Source Code of au.net.causal.projo.prefs.transform.EnumToStringTransformer

package au.net.causal.projo.prefs.transform;

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;

/**
* Converts between enum values and strings.
* <p>
*
* {@link Enum#name()} is used as the string representation of enum values. 
*
* @author prunge
*/
public class EnumToStringTransformer implements PreferenceTransformer
{
  @Override
  public <T> TransformResult<T> applyGet(String key, PreferenceKeyMetadata<T> keyMetadata, TransformGetChain chain)
  throws PreferencesException
  {
    if (!isSupported(keyMetadata, chain))
      return(null);
   
    //Safe because enum types aren't parameterized
    Class<T> enumType = (Class<T>)keyMetadata.getDataType().getRawType();
   
    //Read as string from underlying store, convert to integer and pass up
    String storeValue = chain.getValue(key, keyMetadata.withDataType(String.class));
   
    T enumValue;
    if (storeValue == null)
      enumValue = null;
    else
    {
      //Safe because we know isSupported would only return true if enumType was an actual enum
      try
      {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        T theValue = (T)Enum.valueOf((Class)enumType, storeValue);
        enumValue = theValue;
      }
      catch (IllegalArgumentException e)
      {
        throw new PreferencesException("Invalid store value for enum type " + enumType.getCanonicalName() + ": " + storeValue);
      }
    }
   
    TransformResult<T> result = new TransformResult<>(enumValue);
   
    return(result);
  }
 
  @Override
  public <T> boolean applyPut(String key, T value, PreferenceKeyMetadata<T> keyMetadata, TransformPutChain chain)
  throws PreferencesException
  {
    if (!isSupported(keyMetadata, chain))
      return(false);
   
    Enum<?> enumValue = (Enum<?>)value;
   
    //Convert to string
    String storeValue;
    if (enumValue == null)
      storeValue = null;
    else
      storeValue = enumValue.name();
   
    chain.putValue(key, storeValue, keyMetadata.withDataType(String.class));
   
    return(true);
  }
 
  @Override
  public <T> boolean applyRemove(String key, PreferenceKeyMetadata<T> keyMetadata, TransformRemoveChain chain)
  throws PreferencesException
  {
    if (!isSupported(keyMetadata, chain))
      return(false);
   
    chain.removeValue(key, keyMetadata.withDataType(String.class));
   
    return(true);
  }
 
  @Override
  public DataTypeSupport applyDataTypeSupport(PreferenceKeyMetadata<?> keyMetadata, TransformDataTypeSupportChain chain)
  throws PreferencesException
  {
    //Only for enum keys
    if (!Enum.class.isAssignableFrom(keyMetadata.getDataType().getRawType()))
      return(null);
   
    //If underlying store supports strings then add support, otherwise we can't touch it
    if (!chain.isDataTypeSupported(keyMetadata.withDataType(String.class)))
      return(null);
   
    //If we get here the transform will work
    return(DataTypeSupport.ADD_SUPPORT);
  }

  /**
   * Only use this transformer if:
   *
   * <ul>
   *   <li>Store does not support the enum data type natively</li>
   *   <li>Store supports String data type</li>
   *   <li>Key is an enum data type</li>
   * </ul>
   *
   * @throws PreferencesException if the underlying store fails to retrieve data type support information.
   */
  private boolean isSupported(PreferenceKeyMetadata<?> keyMetadata, TransformDataTypeSupportChain chain)
  throws PreferencesException
  {
    if (!Enum.class.isAssignableFrom(keyMetadata.getDataType().getRawType()))
      return(false);
    if (chain.isDataTypeSupportedNatively(keyMetadata))
      return(false);
    if (!chain.isDataTypeSupported(keyMetadata.withDataType(String.class)))
      return(false);
   
    return(true);
  }
}
TOP

Related Classes of au.net.causal.projo.prefs.transform.EnumToStringTransformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.