From 4306320cc1531a0fd8718524bfeab8490fa40d42 Mon Sep 17 00:00:00 2001 From: serso Date: Thu, 29 Sep 2011 18:33:03 +0400 Subject: [PATCH] vars activity --- pom.xml | 12 +- res/values/default_values.xml | 2 + .../calculator/CalculatorActivity.java | 6 +- .../android/calculator/CalculatorModel.java | 51 +++++++- .../calculator/CalculatorVarsActivity.java | 8 +- .../org/solovyev/android/calculator/Var.java | 89 +++++++++++++ .../android/calculator/VariableContainer.java | 51 -------- .../org/solovyev/android/calculator/Vars.java | 27 ++++ .../android/calculator/VarsRegister.java | 117 ++++++++++++++++++ .../calculator/math/MathEntityType.java | 34 ++++- .../calculator/CalculatorModelTest.java | 12 +- 11 files changed, 335 insertions(+), 74 deletions(-) create mode 100644 src/main/java/org/solovyev/android/calculator/Var.java delete mode 100644 src/main/java/org/solovyev/android/calculator/VariableContainer.java create mode 100644 src/main/java/org/solovyev/android/calculator/Vars.java create mode 100644 src/main/java/org/solovyev/android/calculator/VarsRegister.java diff --git a/pom.xml b/pom.xml index 40d7c787..e7c475ff 100644 --- a/pom.xml +++ b/pom.xml @@ -54,9 +54,15 @@ - de.congrace - exp4j - 0.2.8 + org.simpleframework + simple-xml + 2.6.1 + + + stax-api + stax + + diff --git a/res/values/default_values.xml b/res/values/default_values.xml index 735826ac..ca207e09 100644 --- a/res/values/default_values.xml +++ b/res/values/default_values.xml @@ -18,4 +18,6 @@ org.solovyev.android.calculator.CalculatorModel_color_display true + + org.solovyev.android.calculator.CalculatorModel_vars \ No newline at end of file diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index 7d1b7006..b025ee62 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -57,7 +57,8 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh setContentView(R.layout.main); try { - this.calculatorModel = new CalculatorModel(); + CalculatorModel.init(this); + this.calculatorModel = CalculatorModel.getInstance(); } catch (EvalError evalError) { // todo serso: create serso runtime exception throw new RuntimeException("Could not initialize interpreter!"); @@ -258,8 +259,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String s) { dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(CalculatorActivity.this)); - final NumberMapper integerNumberMapper = new NumberMapper(Integer.class); - this.calculatorModel.setNumberOfFractionDigits(integerNumberMapper.parseValue(sharedPreferences.getString(this.getString(R.string.p_calc_result_precision_key), this.getString(R.string.p_calc_result_precision)))); + this.calculatorModel.load(this); final Boolean colorExpressionsInBracketsDefault = new BooleanMapper().parseValue(this.getString(R.string.p_calc_color_display)); assert colorExpressionsInBracketsDefault != null; diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java index 419c9c3c..bcec4bee 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -5,9 +5,14 @@ package org.solovyev.android.calculator; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; import bsh.EvalError; import bsh.Interpreter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.common.NumberMapper; import org.solovyev.common.exceptions.SersoException; import org.solovyev.common.utils.MathUtils; import org.solovyev.util.math.Complex; @@ -21,16 +26,24 @@ import org.solovyev.util.math.Complex; public class CalculatorModel { @NotNull - private Interpreter interpreter; + private final Interpreter interpreter; private int numberOfFractionDigits = 5; @NotNull - public Preprocessor preprocessor = new ToJsclPreprocessor(); + public final Preprocessor preprocessor = new ToJsclPreprocessor(); + + @NotNull + private final VarsRegister varsRegister = new VarsRegister(); + + private static CalculatorModel instance; + + private CalculatorModel(@Nullable Context context) throws EvalError { + if (context != null) { + load(context); + } - public CalculatorModel() throws EvalError { interpreter = new Interpreter(); - interpreter.eval(ToJsclPreprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands")); } @@ -99,6 +112,15 @@ public class CalculatorModel { return MathUtils.round(dResult, numberOfFractionDigits); } + public synchronized void load(@NotNull Context context) { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + + final NumberMapper integerNumberMapper = new NumberMapper(Integer.class); + this.setNumberOfFractionDigits(integerNumberMapper.parseValue(preferences.getString(context.getString(R.string.p_calc_result_precision_key), context.getString(R.string.p_calc_result_precision)))); + + varsRegister.load(context); + } + public static class ParseException extends SersoException { public ParseException(Throwable cause) { super(cause); @@ -112,4 +134,25 @@ public class CalculatorModel { public void setNumberOfFractionDigits(int numberOfFractionDigits) { this.numberOfFractionDigits = numberOfFractionDigits; } + + public static synchronized void init(@Nullable Context context) throws EvalError { + if ( instance == null ) { + instance = new CalculatorModel(context); + } else { + throw new RuntimeException("Calculator model already instantiated!"); + } + } + + public static CalculatorModel getInstance() { + if ( instance == null ) { + throw new RuntimeException("CalculatorModel must be instantiated!"); + } + + return instance; + } + + @NotNull + public VarsRegister getVarsRegister() { + return varsRegister; + } } diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java index 8b1b2048..225cd54b 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java @@ -30,10 +30,8 @@ public class CalculatorVarsActivity extends ListActivity { setTheme(android.R.style.Theme_Dialog); - final List vars = new ArrayList(); - vars.add(new VariableContainer("e", 2.71, true)); - vars.add(new VariableContainer("π", 3.14, true)); - setListAdapter(new ArrayAdapter(this, R.layout.var, R.id.var_text, vars)); + final List vars = new ArrayList(CalculatorModel.getInstance().getVarsRegister().getVars()); + setListAdapter(new ArrayAdapter(this, R.layout.var, R.id.var_text, vars)); final ListView lv = getListView(); lv.setTextFilterEnabled(true); @@ -42,7 +40,7 @@ public class CalculatorVarsActivity extends ListActivity { public void onItemClick(AdapterView parent, View view, int position, long id) { final Intent intent = new Intent(CalculatorActivity.INSERT_TEXT_INTENT); - intent.putExtra(CalculatorActivity.INSERT_TEXT_INTENT_EXTRA_STRING, vars.get(position).getId()); + intent.putExtra(CalculatorActivity.INSERT_TEXT_INTENT_EXTRA_STRING, vars.get(position).getName()); sendOrderedBroadcast(intent, null); CalculatorVarsActivity.this.finish(); diff --git a/src/main/java/org/solovyev/android/calculator/Var.java b/src/main/java/org/solovyev/android/calculator/Var.java new file mode 100644 index 00000000..2f0d4a7f --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/Var.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + * or visit http://se.solovyev.org + */ + +package org.solovyev.android.calculator; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; + +/** + * User: serso + * Date: 9/28/11 + * Time: 11:22 PM + */ + +@Root +public class Var { + + @Element + @NotNull + private String name; + + @Element + @NotNull + private String value; + + private boolean system; + + @Element(required = false) + @Nullable + private String description; + + public Var() { + } + + public Var(@NotNull String name, @NotNull Double value, boolean system) { + this(name, String.valueOf(value), system); + } + + public Var(@NotNull String name, @NotNull String value, boolean system) { + this.name = name; + this.value = value; + this.system = system; + } + + @NotNull + public String getValue() { + return value; + } + + public void setValue(@NotNull String value) { + this.value = value; + } + + public boolean isSystem() { + return system; + } + + public void setSystem(boolean system) { + this.system = system; + } + + @NotNull + public String getName() { + return name; + } + + public void setName(@NotNull String name) { + this.name = name; + } + + @Nullable + public String getDescription() { + return description; + } + + public void setDescription(@Nullable String description) { + this.description = description; + } + + @Override + public String toString() { + return getName() + " = " + value; + } +} diff --git a/src/main/java/org/solovyev/android/calculator/VariableContainer.java b/src/main/java/org/solovyev/android/calculator/VariableContainer.java deleted file mode 100644 index cbeabdda..00000000 --- a/src/main/java/org/solovyev/android/calculator/VariableContainer.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - * or visit http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.common.definitions.Identity; - -/** - * User: serso - * Date: 9/28/11 - * Time: 11:22 PM - */ -public class VariableContainer extends Identity{ - - @NotNull - private Double value; - - private boolean system; - - public VariableContainer(@NotNull String id, @NotNull Double value, boolean system) { - super(id); - this.value = value; - this.system = system; - } - - @NotNull - public Double getValue() { - return value; - } - - public void setValue(@NotNull Double value) { - this.value = value; - } - - public boolean isSystem() { - return system; - } - - public void setSystem(boolean system) { - this.system = system; - } - - @Override - public String toString() { - return getId() + " = " + value; - } -} diff --git a/src/main/java/org/solovyev/android/calculator/Vars.java b/src/main/java/org/solovyev/android/calculator/Vars.java new file mode 100644 index 00000000..bf90e2b5 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/Vars.java @@ -0,0 +1,27 @@ +package org.solovyev.android.calculator; + +import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Root; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: serso + * Date: 9/29/11 + * Time: 5:19 PM + */ + +@Root +public class Vars { + + @ElementList + private final List vars = new ArrayList(); + + public Vars() { + } + + public List getVars() { + return vars; + } +} diff --git a/src/main/java/org/solovyev/android/calculator/VarsRegister.java b/src/main/java/org/solovyev/android/calculator/VarsRegister.java new file mode 100644 index 00000000..ed7822a6 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/VarsRegister.java @@ -0,0 +1,117 @@ +package org.solovyev.android.calculator; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.simpleframework.xml.Serializer; +import org.simpleframework.xml.core.Persister; +import org.solovyev.android.calculator.math.MathEntityType; +import org.solovyev.android.view.widgets.SimpleOnDragListener; +import org.solovyev.common.utils.CollectionsUtils; +import org.solovyev.common.utils.Finder; + +import java.io.StringWriter; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * User: serso + * Date: 9/29/11 + * Time: 4:57 PM + */ +public class VarsRegister { + + @NotNull + private final Set vars = new HashSet(); + + @NotNull + private final Set systemVars = new HashSet(); + + @NotNull + public Set getVars() { + return Collections.unmodifiableSet(vars); + } + + @NotNull + public Set getSystemVars() { + return Collections.unmodifiableSet(systemVars); + } + + @Nullable + public Var getVar(@NotNull final String name) { + return CollectionsUtils.get(vars, new Finder() { + @Override + public boolean isFound(@Nullable Var var) { + return var != null && name.equals(var.getName()); + } + }); + } + + public void merge(@NotNull final List varsParam) { + final Set result = new HashSet(varsParam); + + for (Var systemVar : systemVars) { + if (!result.contains(systemVar)) { + result.add(systemVar); + } + } + + vars.clear(); + vars.addAll(result); + } + + public synchronized void load(@NotNull Context context) { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + + this.vars.clear(); + this.systemVars.clear(); + + final String value = preferences.getString(context.getString(R.string.p_calc_vars), null); + if (value != null) { + final Serializer serializer = new Persister(); + try { + final Vars vars = serializer.read(Vars.class, value); + this.vars.addAll(vars.getVars()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + for (Var systemVar : MathEntityType.constants) { + + systemVars.add(systemVar); + if (!vars.contains(systemVar)) { + vars.add(systemVar); + } + } + } + + public synchronized void save(@NotNull Context context) { + final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + final SharedPreferences.Editor editor = settings.edit(); + + final Vars vars = new Vars(); + for (Var var : this.vars) { + if (!var.isSystem()) { + vars.getVars().add(var); + } + } + + final StringWriter sw = new StringWriter(); + final Serializer serializer = new Persister(); + try { + serializer.write(vars, sw); + } catch (Exception e) { + throw new RuntimeException(e); + } + + editor.putString(context.getString(R.string.p_calc_vars),sw.toString()); + + editor.commit(); + } +} diff --git a/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java b/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java index b6db3d24..3f81e051 100644 --- a/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java +++ b/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java @@ -5,14 +5,18 @@ package org.solovyev.android.calculator.math; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.Var; +import org.solovyev.common.utils.CollectionsUtils; +import org.solovyev.common.utils.Finder; + +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - public enum MathEntityType { digit, @@ -25,7 +29,14 @@ public enum MathEntityType { group_symbols, group_symbol; - public static final List constants = Arrays.asList('e', 'π', 'i'); + public static final List constants; + static { + final List result = new ArrayList(); + result.add(new Var("e", Math.exp(1), true)); + result.add(new Var("π", Math.PI, true)); + result.add(new Var("i", "√(-1)", true)); + constants = Collections.unmodifiableList(result); + } public static final List dots = Arrays.asList('.'); @@ -72,7 +83,7 @@ public enum MathEntityType { } @Nullable - public static MathEntityType getType(char ch) { + public static MathEntityType getType(final char ch) { MathEntityType result = null; if ( Character.isDigit(ch) ) { @@ -85,11 +96,22 @@ public enum MathEntityType { result = MathEntityType.binary_operation; } else if ( singleGroupSymbols.contains(ch) ) { result = MathEntityType.group_symbol; - } else if ( constants.contains(ch) ) { + } else if (isConstant(ch)) { result = MathEntityType.constant; } else if ( dots.contains(ch) ) { result = MathEntityType.dot; } return result; } + + private static boolean isConstant(final char ch) { + final String name = String.valueOf(ch); + + return CollectionsUtils.get(constants, new Finder() { + @Override + public boolean isFound(@Nullable Var var) { + return var != null && var.getName().equals(name); + } + }) != null; + } } diff --git a/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java b/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java index 1b397501..ff2930bb 100644 --- a/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java +++ b/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java @@ -6,6 +6,8 @@ package org.solovyev.android.calculator; import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; /** @@ -14,9 +16,15 @@ import org.junit.Test; * Time: 9:47 PM */ public class CalculatorModelTest { + + @BeforeClass + public static void setUp() throws Exception { + CalculatorModel.init(null); + } + @Test public void testEvaluate() throws Exception { - final CalculatorModel cm = new CalculatorModel(); + final CalculatorModel cm = CalculatorModel.getInstance(); Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "2+2")); Assert.assertEquals("-0.7568", cm.evaluate(JsclOperation.numeric, "sin(4)")); @@ -43,7 +51,7 @@ public class CalculatorModelTest { @Test public void testComplexNumbers() throws Exception { - final CalculatorModel cm = new CalculatorModel(); + final CalculatorModel cm = CalculatorModel.getInstance(); Assert.assertEquals("1.22133+23123.0i", cm.createResultForComplexNumber("1.22133232+23123*i")); Assert.assertEquals("1.22133+1.2i", cm.createResultForComplexNumber("1.22133232+1.2*i"));