package gov.nasa.arc.mct.plot.settings; import gov.nasa.arc.mct.components.ExtendedProperties; import gov.nasa.arc.mct.gui.View; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class GenericSettings { private static final List<Serializer<?>> SERIALIZERS = Arrays.<Serializer<?>>asList( new PrimitiveSerializer<Double>(Double.class) { @Override public Double deserialize(String s) throws Exception { return Double.parseDouble(s); } }, new PrimitiveSerializer<String>(String.class) { @Override public String deserialize(String s) throws Exception { return s; } }, new PrimitiveSerializer<Boolean>(Boolean.class) { @Override public Boolean deserialize(String s) throws Exception { return Boolean.parseBoolean(s); } }, new PrimitiveSerializer<Long>(Long.class) { @Override public Long deserialize(String s) throws Exception { return Long.parseLong(s); } } ); private Map<String, Setting<?>> settingMap = new HashMap<String, Setting<?>>(); protected <T> void create (String name, T defaultValue, Class<T> cls) { @SuppressWarnings({ "unchecked", "rawtypes" }) Serializer<T> serializer = (cls.isEnum()) ? new EnumSerializer(cls) : findSerializer(cls); if (serializer != null) { create(name, defaultValue, serializer); } } protected <T> void create (String name, T defaultValue, Serializer<T> serializer) { if (serializer != null) { settingMap.put(name, new Setting<T>(name, defaultValue, serializer)); } } protected boolean allowCreation() { // Don't allow arbitrary settings to be created return false; } @SuppressWarnings("unchecked") public <T> boolean set(String name, T value) { if (value == null) { return false; } if (value.getClass().isEnum()) { return set(name, value, (Class<T>) ((Enum<?>) value).getDeclaringClass()); } else { return set(name, value, (Class<T>) value.getClass()); } } public <T> boolean set(String name, T value, Class<T> cls) { if (allowCreation()) { if (!settingMap.containsKey(name)) { create(name, null, cls); } } Setting<?> rawSetting = settingMap.get(name); if (rawSetting != null && rawSetting.getSettingClass().isAssignableFrom(cls)) { @SuppressWarnings("unchecked") Setting<T> setting = (Setting<T>) rawSetting; setting.setValue(value); return true; } else { return false; } } public <T> T get(String name, Class<T> settingClass) { Setting<?> rawSetting = settingMap.get(name); if (rawSetting != null && rawSetting.getSettingClass().isAssignableFrom(settingClass)) { @SuppressWarnings("unchecked") Setting<T> setting = (Setting<T>) rawSetting; return setting.getValue(); } return null; } public Map<String, String> getPersistableSettings() { Map<String, String> persistable = new HashMap<String, String>(); for (Entry<String, Setting<?>> entry : settingMap.entrySet()) { persistable.put(entry.getKey(), entry.getValue().getSerializedValue()); } return persistable; } public void setPersistableSettings(Map<String, String> persisted) { for (Entry<String, String> entry : persisted.entrySet()) { String name = entry.getKey(); if (settingMap.containsKey(name)) { settingMap.get(name).setSerializedValue(entry.getValue()); } } } public void persist(View view) { ExtendedProperties properties = view.getViewProperties(); for (Entry<String, String> setting : this.getPersistableSettings().entrySet()) { properties.setProperty(setting.getKey(), setting.getValue()); } if (view.getManifestedComponent() != null) { view.getManifestedComponent().save(); } } public void loadFrom(View view) { ExtendedProperties properties = view.getViewProperties(); for (Setting<?> setting : settingMap.values()) { String property = properties.getProperty(setting.name, String.class); if (property != null) { setting.setSerializedValue(property); } } } @SuppressWarnings("unchecked") private <T> Serializer<T> findSerializer(Class<T> cls) { for (Serializer<?> serializer : SERIALIZERS) { if (serializer.getSerializedClass().isAssignableFrom(cls)) { return (Serializer<T>) serializer; } } return null; } private interface Serializer<T> { public T deserialize(String s) throws Exception; public String serialize(T object); public Class<T> getSerializedClass(); } private class Setting<T> { private Class<T> cls; private String name; private T value; private T defaultValue; private Serializer<T> serializer; public Setting(String name, T defaultValue, Serializer<T> serializer) { super(); this.cls = serializer.getSerializedClass(); this.name = name; this.value = defaultValue; this.defaultValue = defaultValue; this.serializer = serializer; } public T getValue() { return value; } public String getSerializedValue() { if (serializer != null) { return serializer.serialize(value); } else { return null; } } public void setValue(T value) { this.value = value; } public void setSerializedValue(String value) { if (value == null) { setValue(null); } else if (serializer != null) { try { setValue( serializer.deserialize(value) ); } catch (Exception pe) { // TODO: Log? Reset to default? } } else { } } public Class<T> getSettingClass() { return cls; } } private static abstract class PrimitiveSerializer<T> implements Serializer<T> { private Class<T> serializedClass; private PrimitiveSerializer(Class<T> serializedClass) { this.serializedClass = serializedClass; } @Override public String serialize(T object) { return object.toString(); } /* (non-Javadoc) * @see gov.nasa.arc.mct.fastplot.settings.GenericSettings.Serializer#getSerializedClass() */ @Override public Class<T> getSerializedClass() { return serializedClass; } } private class EnumSerializer<T extends Enum<T>> extends PrimitiveSerializer<T> { private EnumSerializer (Class<T> enumClass) { super(enumClass); } @Override public T deserialize(String s) throws Exception { return Enum.valueOf(getSerializedClass(), s); } /* (non-Javadoc) * @see gov.nasa.arc.mct.fastplot.settings.GenericSettings.PrimitiveSerializer#serialize(java.lang.Object) */ @Override public String serialize(T object) { return object.name(); } } }