/* * Scriptographer * * This file is part of Scriptographer, a Scripting Plugin for Adobe Illustrator * http://scriptographer.org/ * * Copyright (c) 2002-2010, Juerg Lehni * http://scratchdisk.com/ * * All rights reserved. See LICENSE file for details. * * File created on May 6, 2007. */ package com.scriptographer.sg; import java.util.prefs.BackingStoreException; import org.mozilla.javascript.Context; import org.mozilla.javascript.NativeJSON; import org.mozilla.javascript.Scriptable; import com.scratchdisk.script.ScriptEngine; import com.scratchdisk.script.rhino.RhinoScope; import com.scratchdisk.util.AbstractMap; /** * Preferences wraps a java.util.prefs.Preferences instance in a * Map interface. * * @author lehni * * @jshide */ public class Preferences extends AbstractMap { java.util.prefs.Preferences prefs; public Preferences(java.util.prefs.Preferences prefs) { this.prefs = prefs; } protected Object[] keys() { try { return prefs.keys(); } catch (BackingStoreException e) { throw new RuntimeException(e); } } public void clear() { try { prefs.clear(); } catch (BackingStoreException e) { throw new RuntimeException(e); } } public Object get(Object key) { String value = prefs.get(key.toString(), null); if (value != null) { // Try conversion to numbers first, if it is not obiously Json data if (!value.startsWith("{") && !value.startsWith("\"")) { // Try converting to a long, if there is no decimal point try { if (value.indexOf('.') == -1) return new Long(value); } catch (NumberFormatException e) { } // Now try double try { return new Double(value); } catch (NumberFormatException e) { } } if (value.equals("true")) { return Boolean.TRUE; } else if (value.equals("false")) { return Boolean.FALSE; } else if (value.equals("null")) { return null; } else { // Now try Json. // TODO: Note that this only makes sense for Rhino engine! Is // there ever another engine, this won't work. This is also the // reason why the above code is kept although all code be handled // by Json... // Another solution could be to force conversion to one of the Java // types and pass the result to a Java Json engine. The conversion // could be enforced through various conversion methods with different // argument types. But this will do for now, at least as long as there // are no other engines. try { ScriptEngine engine = ScriptEngine.getEngineByName("JavaScript"); Context cx = Context.getCurrentContext(); Object json = NativeJSON.parse(cx, ((RhinoScope) engine.getGlobalScope()).getScope(), value.toString()); if (json != null) return json; } catch (Exception e) { } } } // If nothing of that works, return string return value; } public boolean containsKey(Object key) { return prefs.get(key.toString(), null) != null; } public Object put(Object key, Object value) { Object prev = get(key); String keyStr = key.toString(); if (value instanceof Boolean) { prefs.putBoolean(keyStr, ((Boolean) value).booleanValue()); } else if (value instanceof Double || value instanceof Float) { prefs.putDouble(keyStr, ((Number) value).doubleValue()); } else if (value instanceof Number) { prefs.putLong(keyStr, ((Number) value).longValue()); } else if (value instanceof Scriptable) { ScriptEngine engine = ScriptEngine.getEngineByName("JavaScript"); Context cx = Context.getCurrentContext(); Object json = NativeJSON.stringify(cx, ((RhinoScope) engine.getGlobalScope()).getScope(), value, null, null); prefs.put(keyStr, json != null ? json.toString() : "null"); } else if (value instanceof String) { prefs.put(keyStr, value.toString()); } return prev; } public Object remove(Object key) { Object pre = get(key); prefs.remove(key.toString()); return pre; } }