diff --git a/calculatorpp-core/pom.xml b/calculatorpp-core/pom.xml index 7f59b53d..22f023e6 100644 --- a/calculatorpp-core/pom.xml +++ b/calculatorpp-core/pom.xml @@ -30,6 +30,11 @@ annotations + + org.solovyev + jscl + + diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java similarity index 94% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java index 6de56347..43e2614d 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java @@ -1,19 +1,19 @@ -/* - * 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; - -/** - * User: serso - * Date: 10/24/11 - * Time: 9:55 PM - */ -public interface CalculatorEngineControl { - - void evaluate(); - - void simplify(); -} +/* + * 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; + +/** + * User: serso + * Date: 10/24/11 + * Time: 9:55 PM + */ +public interface CalculatorEngineControl { + + void evaluate(); + + void simplify(); +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java new file mode 100644 index 00000000..5b74bde7 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java @@ -0,0 +1,16 @@ +package org.solovyev.android.calculator; + +import org.jetbrains.annotations.NotNull; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 12:45 + */ +public interface CalculatorLocator { + + @NotNull + JCalculatorEngine getCalculatorEngine(); + + void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine); +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java new file mode 100644 index 00000000..6cee9b7c --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java @@ -0,0 +1,36 @@ +package org.solovyev.android.calculator; + +import org.jetbrains.annotations.NotNull; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 12:45 + */ +public class CalculatorLocatorImpl implements CalculatorLocator { + + @NotNull + private JCalculatorEngine calculatorEngine; + + @NotNull + private static final CalculatorLocator instance = new CalculatorLocatorImpl(); + + private CalculatorLocatorImpl() { + } + + @NotNull + public static CalculatorLocator getInstance() { + return instance; + } + + @NotNull + @Override + public JCalculatorEngine getCalculatorEngine() { + return calculatorEngine; + } + + @Override + public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) { + this.calculatorEngine = calculatorEngine; + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/Editor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Editor.java similarity index 86% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/history/Editor.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/Editor.java index c60aa66e..e2f53a0b 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/Editor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Editor.java @@ -1,27 +1,27 @@ -/* - * 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.history; - -import org.jetbrains.annotations.Nullable; - -/** - * User: serso - * Date: 12/17/11 - * Time: 9:37 PM - */ -public interface Editor { - - @Nullable - CharSequence getText(); - - void setText(@Nullable CharSequence text); - - int getSelection(); - - void setSelection(int selection); - -} +/* + * 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.Nullable; + +/** + * User: serso + * Date: 12/17/11 + * Time: 9:37 PM + */ +public interface Editor { + + @Nullable + CharSequence getText(); + + void setText(@Nullable CharSequence text); + + int getSelection(); + + void setSelection(int selection); + +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java similarity index 90% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java index 1c0b892f..96a61018 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ICalculatorDisplay.java @@ -1,40 +1,40 @@ -/* - * 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 jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.history.Editor; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 12/17/11 - * Time: 9:45 PM - */ -public interface ICalculatorDisplay extends Editor{ - - boolean isValid(); - - void setValid(boolean valid); - - @Nullable - String getErrorMessage(); - - void setErrorMessage(@Nullable String errorMessage); - - void setJsclOperation(@NotNull JsclOperation jsclOperation); - - @NotNull - JsclOperation getJsclOperation(); - - void setGenericResult(@Nullable Generic genericResult); - - @Nullable - Generic getGenericResult(); -} +/* + * 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 jscl.math.Generic; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.Editor; +import org.solovyev.android.calculator.jscl.JsclOperation; + +/** + * User: serso + * Date: 12/17/11 + * Time: 9:45 PM + */ +public interface ICalculatorDisplay extends Editor{ + + boolean isValid(); + + void setValid(boolean valid); + + @Nullable + String getErrorMessage(); + + void setErrorMessage(@Nullable String errorMessage); + + void setJsclOperation(@NotNull JsclOperation jsclOperation); + + @NotNull + JsclOperation getJsclOperation(); + + void setGenericResult(@Nullable Generic genericResult); + + @Nullable + Generic getGenericResult(); +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java new file mode 100644 index 00000000..c069e378 --- /dev/null +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java @@ -0,0 +1,34 @@ +package org.solovyev.android.calculator; + +import jscl.MathEngine; +import jscl.math.function.Function; +import jscl.math.function.IConstant; +import jscl.math.operator.Operator; +import org.jetbrains.annotations.NotNull; +import org.solovyev.common.math.MathRegistry; + +/** + * User: Solovyev_S + * Date: 20.09.12 + * Time: 12:43 + */ +public interface JCalculatorEngine { + + @NotNull + String getMultiplicationSign(); + + @NotNull + MathRegistry getVarsRegistry(); + + @NotNull + MathRegistry getFunctionsRegistry(); + + @NotNull + MathRegistry getOperatorsRegistry(); + + @NotNull + MathRegistry getPostfixFunctionsRegistry(); + + @NotNull + MathEngine getEngine(); +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java similarity index 96% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java index 6d8a1340..b664c9ff 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java @@ -1,28 +1,28 @@ -/* - * 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.jscl; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.model.CalculatorParseException; -import org.solovyev.android.calculator.model.TextProcessor; - -/** - * User: serso - * Date: 10/6/11 - * Time: 9:48 PM - */ -class FromJsclNumericTextProcessor implements TextProcessor { - - public static final FromJsclNumericTextProcessor instance = new FromJsclNumericTextProcessor(); - - @NotNull - @Override - public String process(@NotNull Generic numeric) throws CalculatorParseException { - return numeric.toString().replace("*", ""); - } -} +/* + * 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.jscl; + +import jscl.math.Generic; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.android.calculator.model.TextProcessor; + +/** + * User: serso + * Date: 10/6/11 + * Time: 9:48 PM + */ +class FromJsclNumericTextProcessor implements TextProcessor { + + public static final FromJsclNumericTextProcessor instance = new FromJsclNumericTextProcessor(); + + @NotNull + @Override + public String process(@NotNull Generic numeric) throws CalculatorParseException { + return numeric.toString().replace("*", ""); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java similarity index 64% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java index 65b72281..f3a21199 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java @@ -1,70 +1,70 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.jscl; - - -import jscl.math.Generic; -import jscl.text.ParseException; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.model.DummyTextProcessor; -import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor; -import org.solovyev.android.calculator.model.TextProcessor; - -public enum JsclOperation { - - simplify, - elementary, - numeric; - - JsclOperation() { - } - - - @NotNull - public TextProcessor getFromProcessor() { - switch (this) { - case simplify: - return FromJsclSimplifyTextProcessor.instance; - case elementary: - return DummyTextProcessor.instance; - case numeric: - return FromJsclNumericTextProcessor.instance; - default: - throw new UnsupportedOperationException(); - } - } - - @NotNull - public final String evaluate(@NotNull String expression) throws ParseException { - switch (this) { - case simplify: - return CalculatorEngine.instance.getEngine().simplify(expression); - case elementary: - return CalculatorEngine.instance.getEngine().elementary(expression); - case numeric: - return CalculatorEngine.instance.getEngine().evaluate(expression); - default: - throw new UnsupportedOperationException(); - } - } - - @NotNull - public final Generic evaluateGeneric(@NotNull String expression) throws ParseException { - switch (this) { - case simplify: - return CalculatorEngine.instance.getEngine().simplifyGeneric(expression); - case elementary: - return CalculatorEngine.instance.getEngine().elementaryGeneric(expression); - case numeric: - return CalculatorEngine.instance.getEngine().evaluateGeneric(expression); - default: - throw new UnsupportedOperationException(); - } - } - - -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.jscl; + + +import jscl.math.Generic; +import jscl.text.ParseException; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.model.DummyTextProcessor; +import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor; +import org.solovyev.android.calculator.model.TextProcessor; + +public enum JsclOperation { + + simplify, + elementary, + numeric; + + JsclOperation() { + } + + + @NotNull + public TextProcessor getFromProcessor() { + switch (this) { + case simplify: + return FromJsclSimplifyTextProcessor.instance; + case elementary: + return DummyTextProcessor.instance; + case numeric: + return FromJsclNumericTextProcessor.instance; + default: + throw new UnsupportedOperationException(); + } + } + + @NotNull + public final String evaluate(@NotNull String expression) throws ParseException { + switch (this) { + case simplify: + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplify(expression); + case elementary: + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementary(expression); + case numeric: + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluate(expression); + default: + throw new UnsupportedOperationException(); + } + } + + @NotNull + public final Generic evaluateGeneric(@NotNull String expression) throws ParseException { + switch (this) { + case simplify: + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplifyGeneric(expression); + case elementary: + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementaryGeneric(expression); + case numeric: + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluateGeneric(expression); + default: + throw new UnsupportedOperationException(); + } + } + + +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/MathType.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java similarity index 92% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/math/MathType.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java index 91e8d451..4aa60280 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/math/MathType.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java @@ -1,448 +1,445 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.math; - -import jscl.JsclMathEngine; -import jscl.NumeralBase; -import jscl.math.function.Constants; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.common.JPredicate; -import org.solovyev.common.StartsWithFinder; -import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.model.CalculatorParseException; -import org.solovyev.common.collections.CollectionsUtils; - -import java.util.*; - - -public enum MathType { - - numeral_base(50, true, false, MathGroupType.number) { - - private final List tokens = new ArrayList(10); - { - for (NumeralBase numeralBase : NumeralBase.values()) { - final String jsclPrefix = numeralBase.getJsclPrefix(); - if (jsclPrefix != null) { - tokens.add(jsclPrefix); - } - } - } - - @NotNull - @Override - public List getTokens() { - return tokens; - } - }, - - dot(200, true, true, MathGroupType.number, ".") { - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit; - } - }, - - grouping_separator(250, false, false, MathGroupType.number, "'", " "){ - @Override - public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { - return i; - } - }, - - power_10(300, false, false, MathGroupType.number, "E"), - - postfix_function(400, false, true, MathGroupType.function) { - @NotNull - @Override - public List getTokens() { - return CalculatorEngine.instance.getPostfixFunctionsRegistry().getNames(); - } - }, - - unary_operation(500, false, false, MathGroupType.operation, "-", "="), - binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "∙", "/", "^") { - @Override - protected String getSubstituteToJscl(@NotNull String match) { - if (match.equals("×") || match.equals("∙")) { - return "*"; - } else { - return null; - } - } - }, - - open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") { - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator; - } - - @Override - protected String getSubstituteToJscl(@NotNull String match) { - return "("; - } - }, - - close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") { - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return false; - } - - @Override - protected String getSubstituteToJscl(@NotNull String match) { - return ")"; - } - }, - - function(1000, true, true, MathGroupType.function) { - @NotNull - @Override - public List getTokens() { - return CalculatorEngine.instance.getFunctionsRegistry().getNames(); - } - }, - - operator(1050, true, true, MathGroupType.function) { - @NotNull - @Override - public List getTokens() { - return CalculatorEngine.instance.getOperatorsRegistry().getNames(); - } - }, - - constant(1100, true, true, MathGroupType.other) { - @NotNull - @Override - public List getTokens() { - return CalculatorEngine.instance.getVarsRegistry().getNames(); - } - - @Override - protected String getSubstituteFromJscl(@NotNull String match) { - return Constants.INF_2.getName().equals(match) ? MathType.INFINITY : super.getSubstituteFromJscl(match); - } - }, - - digit(1125, true, true, MathGroupType.number) { - - private final List tokens = new ArrayList(16); - { - for (Character character : NumeralBase.hex.getAcceptableCharacters()) { - tokens.add(character.toString()); - } - } - @Override - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit && mathTypeBefore != dot /*&& mathTypeBefore != numeral_base*/; - } - - @NotNull - @Override - public List getTokens() { - return tokens; - } - }, - - comma(1150, false, false, MathGroupType.other, ","), - - text(1200, false, false, MathGroupType.other) { - @Override - public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { - if (match.length() > 0) { - result.append(match.charAt(0)); - } - return i; - } - - @Override - public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { - if (match.length() > 0) { - result.append(match.charAt(0)); - } - return i; - } - }; - - public static enum MathGroupType { - function, - number, - operation, - other - } - - @NotNull - private final List tokens; - - @NotNull - private final Integer priority; - - private final boolean needMultiplicationSignBefore; - - private final boolean needMultiplicationSignAfter; - - @NotNull - private final MathGroupType groupType; - - MathType(@NotNull Integer priority, - boolean needMultiplicationSignBefore, - boolean needMultiplicationSignAfter, - @NotNull MathGroupType groupType, - @NotNull String... tokens) { - this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens)); - } - - MathType(@NotNull Integer priority, - boolean needMultiplicationSignBefore, - boolean needMultiplicationSignAfter, - @NotNull MathGroupType groupType, - @NotNull List tokens) { - this.priority = priority; - this.needMultiplicationSignBefore = needMultiplicationSignBefore; - this.needMultiplicationSignAfter = needMultiplicationSignAfter; - this.groupType = groupType; - this.tokens = Collections.unmodifiableList(tokens); - } - - @NotNull - public MathGroupType getGroupType() { - return groupType; - } - - /* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException { - assert s.length() > position; - - int numberOfOpenGroups = 0; - int result = position; - for (; result >= 0; result--) { - - final MathType mathType = getType(s.toString(), result).getMathType(); - - if (CollectionsUtils.contains(mathType, digit, dot, grouping_separator, power_10)) { - // continue - } else if (mathType == close_group_symbol) { - numberOfOpenGroups++; - } else if (mathType == open_group_symbol) { - if (numberOfOpenGroups > 0) { - numberOfOpenGroups--; - } else { - break; - } - } else { - if (stop(s, numberOfOpenGroups, result)) break; - } - } - - if (numberOfOpenGroups != 0){ - throw new ParseException("Could not find start of prefix function!"); - } - - return result; - } - - public static boolean stop(CharSequence s, int numberOfOpenGroups, int i) { - if (numberOfOpenGroups == 0) { - if (i > 0) { - final EndsWithFinder endsWithFinder = new EndsWithFinder(s); - endsWithFinder.setI(i + 1); - if (!CollectionsUtils.contains(function.getTokens(), FilterType.included, endsWithFinder)) { - MathType type = getType(s.toString(), i).getMathType(); - if (type != constant) { - return true; - } - } - } else { - return true; - } - } - - return false; - }*/ - - @NotNull - public List getTokens() { - return tokens; - } - - private boolean isNeedMultiplicationSignBefore() { - return needMultiplicationSignBefore; - } - - private boolean isNeedMultiplicationSignAfter() { - return needMultiplicationSignAfter; - } - - public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { - return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter(); - } - - public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { - final String substitute = getSubstituteToJscl(match); - result.append(substitute == null ? match : substitute); - return returnI(i, match); - } - - protected int returnI(int i, @NotNull String match) { - if (match.length() > 1) { - return i + match.length() - 1; - } else { - return i; - } - } - - public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { - final String substitute = getSubstituteFromJscl(match); - result.append(substitute == null ? match : substitute); - return returnI(i, match); - } - - @Nullable - protected String getSubstituteFromJscl(@NotNull String match) { - return null; - } - - @Nullable - protected String getSubstituteToJscl(@NotNull String match) { - return null; - } - - public static final List openGroupSymbols = Arrays.asList("[]", "()", "{}"); - - public final static Character POWER_10 = 'E'; - - public static final String IMAGINARY_NUMBER = "i"; - public static final String IMAGINARY_NUMBER_JSCL = "√(-1)"; - - public static final String PI = "π"; - public static final String E = "e"; - public static final String C = "c"; - public static final Double C_VALUE = 299792458d; - public static final String G = "G"; - public static final Double G_VALUE = 6.6738480E-11; - public static final String H_REDUCED = "h"; - public static final Double H_REDUCED_VALUE = 6.6260695729E-34 / ( 2 * Math.PI ); - public final static String NAN = "NaN"; - - public final static String INFINITY = "∞"; - public final static String INFINITY_JSCL = "Infinity"; - - - /** - * Method determines mathematical entity type for text substring starting from ith index - * - * - * @param text analyzed text - * @param i index which points to start of substring - * @param hexMode - * @return math entity type of substring starting from ith index of specified text - */ - @NotNull - public static Result getType(@NotNull String text, int i, boolean hexMode) { - if (i < 0) { - throw new IllegalArgumentException("I must be more or equals to 0."); - } else if (i >= text.length() && i != 0) { - throw new IllegalArgumentException("I must be less than size of text."); - } else if (i == 0 && text.length() == 0) { - return new Result(MathType.text, text); - } - - final StartsWithFinder startsWithFinder = new StartsWithFinder(text, i); - - for (MathType mathType : getMathTypesByPriority()) { - final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder); - if (s != null) { - if ( s.length() == 1 ) { - if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { - final Character ch = s.charAt(0); - if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) { - return new Result(MathType.digit, s); - } - } - } - return new Result(mathType, s); - } - } - - return new Result(MathType.text, text.substring(i)); - } - - - private static List mathTypesByPriority; - - @NotNull - private static List getMathTypesByPriority() { - if (mathTypesByPriority == null) { - final List result = CollectionsUtils.asList(MathType.values()); - - Collections.sort(result, new Comparator() { - @Override - public int compare(MathType l, MathType r) { - return l.priority.compareTo(r.priority); - } - }); - - mathTypesByPriority = result; - } - - return mathTypesByPriority; - } - - public static class Result { - - @NotNull - private final MathType mathType; - - @NotNull - private final String match; - - public Result(@NotNull MathType mathType, @NotNull String match) { - this.mathType = mathType; - - this.match = match; - } - - public int processToJscl(@NotNull StringBuilder result, int i) throws CalculatorParseException { - return mathType.processToJscl(result, i, match); - } - - public int processFromJscl(@NotNull StringBuilder result, int i) { - return mathType.processFromJscl(result, i, match); - } - - @NotNull - public String getMatch() { - return match; - } - - @NotNull - public MathType getMathType() { - return mathType; - } - } - - private static class EndsWithFinder implements JPredicate { - - private int i; - - @NotNull - private final CharSequence targetString; - - private EndsWithFinder(@NotNull CharSequence targetString) { - this.targetString = targetString; - } - - @Override - public boolean apply(@Nullable String s) { - return targetString.subSequence(0, i).toString().endsWith(s); - } - - public void setI(int i) { - this.i = i; - } - } -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.math; + +import jscl.JsclMathEngine; +import jscl.NumeralBase; +import jscl.math.function.Constants; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.common.JPredicate; +import org.solovyev.common.StartsWithFinder; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.common.collections.CollectionsUtils; + +import java.util.*; + + +public enum MathType { + + numeral_base(50, true, false, MathGroupType.number) { + + private final List tokens = new ArrayList(10); + { + for (NumeralBase numeralBase : NumeralBase.values()) { + tokens.add(numeralBase.getJsclPrefix()); + } + } + + @NotNull + @Override + public List getTokens() { + return tokens; + } + }, + + dot(200, true, true, MathGroupType.number, ".") { + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit; + } + }, + + grouping_separator(250, false, false, MathGroupType.number, "'", " "){ + @Override + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { + return i; + } + }, + + power_10(300, false, false, MathGroupType.number, "E"), + + postfix_function(400, false, true, MathGroupType.function) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getPostfixFunctionsRegistry().getNames(); + } + }, + + unary_operation(500, false, false, MathGroupType.operation, "-", "="), + binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "∙", "/", "^") { + @Override + protected String getSubstituteToJscl(@NotNull String match) { + if (match.equals("×") || match.equals("∙")) { + return "*"; + } else { + return null; + } + } + }, + + open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") { + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator; + } + + @Override + protected String getSubstituteToJscl(@NotNull String match) { + return "("; + } + }, + + close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") { + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return false; + } + + @Override + protected String getSubstituteToJscl(@NotNull String match) { + return ")"; + } + }, + + function(1000, true, true, MathGroupType.function) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getFunctionsRegistry().getNames(); + } + }, + + operator(1050, true, true, MathGroupType.function) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getOperatorsRegistry().getNames(); + } + }, + + constant(1100, true, true, MathGroupType.other) { + @NotNull + @Override + public List getTokens() { + return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().getNames(); + } + + @Override + protected String getSubstituteFromJscl(@NotNull String match) { + return Constants.INF_2.getName().equals(match) ? MathType.INFINITY : super.getSubstituteFromJscl(match); + } + }, + + digit(1125, true, true, MathGroupType.number) { + + private final List tokens = new ArrayList(16); + { + for (Character character : NumeralBase.hex.getAcceptableCharacters()) { + tokens.add(character.toString()); + } + } + @Override + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit && mathTypeBefore != dot /*&& mathTypeBefore != numeral_base*/; + } + + @NotNull + @Override + public List getTokens() { + return tokens; + } + }, + + comma(1150, false, false, MathGroupType.other, ","), + + text(1200, false, false, MathGroupType.other) { + @Override + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + if (match.length() > 0) { + result.append(match.charAt(0)); + } + return i; + } + + @Override + public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + if (match.length() > 0) { + result.append(match.charAt(0)); + } + return i; + } + }; + + public static enum MathGroupType { + function, + number, + operation, + other + } + + @NotNull + private final List tokens; + + @NotNull + private final Integer priority; + + private final boolean needMultiplicationSignBefore; + + private final boolean needMultiplicationSignAfter; + + @NotNull + private final MathGroupType groupType; + + MathType(@NotNull Integer priority, + boolean needMultiplicationSignBefore, + boolean needMultiplicationSignAfter, + @NotNull MathGroupType groupType, + @NotNull String... tokens) { + this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens)); + } + + MathType(@NotNull Integer priority, + boolean needMultiplicationSignBefore, + boolean needMultiplicationSignAfter, + @NotNull MathGroupType groupType, + @NotNull List tokens) { + this.priority = priority; + this.needMultiplicationSignBefore = needMultiplicationSignBefore; + this.needMultiplicationSignAfter = needMultiplicationSignAfter; + this.groupType = groupType; + this.tokens = Collections.unmodifiableList(tokens); + } + + @NotNull + public MathGroupType getGroupType() { + return groupType; + } + + /* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException { + assert s.length() > position; + + int numberOfOpenGroups = 0; + int result = position; + for (; result >= 0; result--) { + + final MathType mathType = getType(s.toString(), result).getMathType(); + + if (CollectionsUtils.contains(mathType, digit, dot, grouping_separator, power_10)) { + // continue + } else if (mathType == close_group_symbol) { + numberOfOpenGroups++; + } else if (mathType == open_group_symbol) { + if (numberOfOpenGroups > 0) { + numberOfOpenGroups--; + } else { + break; + } + } else { + if (stop(s, numberOfOpenGroups, result)) break; + } + } + + if (numberOfOpenGroups != 0){ + throw new ParseException("Could not find start of prefix function!"); + } + + return result; + } + + public static boolean stop(CharSequence s, int numberOfOpenGroups, int i) { + if (numberOfOpenGroups == 0) { + if (i > 0) { + final EndsWithFinder endsWithFinder = new EndsWithFinder(s); + endsWithFinder.setI(i + 1); + if (!CollectionsUtils.contains(function.getTokens(), FilterType.included, endsWithFinder)) { + MathType type = getType(s.toString(), i).getMathType(); + if (type != constant) { + return true; + } + } + } else { + return true; + } + } + + return false; + }*/ + + @NotNull + public List getTokens() { + return tokens; + } + + private boolean isNeedMultiplicationSignBefore() { + return needMultiplicationSignBefore; + } + + private boolean isNeedMultiplicationSignAfter() { + return needMultiplicationSignAfter; + } + + public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { + return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter(); + } + + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { + final String substitute = getSubstituteToJscl(match); + result.append(substitute == null ? match : substitute); + return returnI(i, match); + } + + protected int returnI(int i, @NotNull String match) { + if (match.length() > 1) { + return i + match.length() - 1; + } else { + return i; + } + } + + public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + final String substitute = getSubstituteFromJscl(match); + result.append(substitute == null ? match : substitute); + return returnI(i, match); + } + + @Nullable + protected String getSubstituteFromJscl(@NotNull String match) { + return null; + } + + @Nullable + protected String getSubstituteToJscl(@NotNull String match) { + return null; + } + + public static final List openGroupSymbols = Arrays.asList("[]", "()", "{}"); + + public final static Character POWER_10 = 'E'; + + public static final String IMAGINARY_NUMBER = "i"; + public static final String IMAGINARY_NUMBER_JSCL = "√(-1)"; + + public static final String PI = "π"; + public static final String E = "e"; + public static final String C = "c"; + public static final Double C_VALUE = 299792458d; + public static final String G = "G"; + public static final Double G_VALUE = 6.6738480E-11; + public static final String H_REDUCED = "h"; + public static final Double H_REDUCED_VALUE = 6.6260695729E-34 / ( 2 * Math.PI ); + public final static String NAN = "NaN"; + + public final static String INFINITY = "∞"; + public final static String INFINITY_JSCL = "Infinity"; + + + /** + * Method determines mathematical entity type for text substring starting from ith index + * + * + * @param text analyzed text + * @param i index which points to start of substring + * @param hexMode + * @return math entity type of substring starting from ith index of specified text + */ + @NotNull + public static Result getType(@NotNull String text, int i, boolean hexMode) { + if (i < 0) { + throw new IllegalArgumentException("I must be more or equals to 0."); + } else if (i >= text.length() && i != 0) { + throw new IllegalArgumentException("I must be less than size of text."); + } else if (i == 0 && text.length() == 0) { + return new Result(MathType.text, text); + } + + final StartsWithFinder startsWithFinder = new StartsWithFinder(text, i); + + for (MathType mathType : getMathTypesByPriority()) { + final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder); + if (s != null) { + if ( s.length() == 1 ) { + if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { + final Character ch = s.charAt(0); + if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) { + return new Result(MathType.digit, s); + } + } + } + return new Result(mathType, s); + } + } + + return new Result(MathType.text, text.substring(i)); + } + + + private static List mathTypesByPriority; + + @NotNull + private static List getMathTypesByPriority() { + if (mathTypesByPriority == null) { + final List result = CollectionsUtils.asList(MathType.values()); + + Collections.sort(result, new Comparator() { + @Override + public int compare(MathType l, MathType r) { + return l.priority.compareTo(r.priority); + } + }); + + mathTypesByPriority = result; + } + + return mathTypesByPriority; + } + + public static class Result { + + @NotNull + private final MathType mathType; + + @NotNull + private final String match; + + public Result(@NotNull MathType mathType, @NotNull String match) { + this.mathType = mathType; + + this.match = match; + } + + public int processToJscl(@NotNull StringBuilder result, int i) throws CalculatorParseException { + return mathType.processToJscl(result, i, match); + } + + public int processFromJscl(@NotNull StringBuilder result, int i) { + return mathType.processFromJscl(result, i, match); + } + + @NotNull + public String getMatch() { + return match; + } + + @NotNull + public MathType getMathType() { + return mathType; + } + } + + private static class EndsWithFinder implements JPredicate { + + private int i; + + @NotNull + private final CharSequence targetString; + + private EndsWithFinder(@NotNull CharSequence targetString) { + this.targetString = targetString; + } + + @Override + public boolean apply(@Nullable String s) { + return targetString.subSequence(0, i).toString().endsWith(s); + } + + public void setI(int i) { + this.i = i; + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java similarity index 73% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java index e164578f..157a6c82 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java @@ -6,10 +6,8 @@ package org.solovyev.android.calculator.model; -import android.app.Application; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.msg.AndroidMessage; import org.solovyev.common.exceptions.SersoException; import org.solovyev.common.msg.Message; import org.solovyev.common.msg.MessageType; @@ -39,14 +37,17 @@ public class CalculatorParseException extends SersoException implements Message this.position = jsclParseException.getPosition(); } - public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @Nullable Integer position, @NotNull String expression, Object... parameters) { - this.message = new AndroidMessage(messageId, MessageType.error, application, parameters); + public CalculatorParseException(@Nullable Integer position, + @NotNull String expression, + @NotNull Message message) { + this.message = message; this.expression = expression; this.position = position; } - public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @NotNull String expression, Object... parameters) { - this(messageId, application, null, expression, parameters); + public CalculatorParseException(@NotNull String expression, + @NotNull Message message) { + this(null, expression, message); } @NotNull diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java similarity index 95% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java index 19cbc293..779a1fe8 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java @@ -1,26 +1,26 @@ -/* - * 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.model; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; - -/** - * User: serso - * Date: 10/18/11 - * Time: 10:39 PM - */ -public enum DummyTextProcessor implements TextProcessor { - - instance; - - @NotNull - @Override - public String process(@NotNull Generic s) throws CalculatorParseException { - return s.toString(); - } -} +/* + * 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.model; + +import jscl.math.Generic; +import org.jetbrains.annotations.NotNull; + +/** + * User: serso + * Date: 10/18/11 + * Time: 10:39 PM + */ +public enum DummyTextProcessor implements TextProcessor { + + instance; + + @NotNull + @Override + public String process(@NotNull Generic s) throws CalculatorParseException { + return s.toString(); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java similarity index 88% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java index d2fb4860..d541edea 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java @@ -1,92 +1,94 @@ -package org.solovyev.android.calculator.model; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.math.MathType; - -import java.util.Arrays; -import java.util.List; - -/** - * User: serso - * Date: 10/20/11 - * Time: 2:59 PM - */ -public class FromJsclSimplifyTextProcessor implements TextProcessor { - - public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor(); - - public FromJsclSimplifyTextProcessor() { - } - - @NotNull - @Override - public String process(@NotNull Generic from) throws CalculatorParseException { - return removeMultiplicationSigns(from.toString()); - } - - public String process(@NotNull String s) { - return removeMultiplicationSigns(s); - } - - @NotNull - private String removeMultiplicationSigns(String s) { - final StringBuilder sb = new StringBuilder(); - - MathType.Result mathTypeBefore; - MathType.Result mathType = null; - MathType.Result mathTypeAfter = null; - - for (int i = 0; i < s.length(); i++) { - mathTypeBefore = mathType; - if (mathTypeAfter == null) { - mathType = MathType.getType(s, i, false); - } else { - mathType = mathTypeAfter; - } - - char ch = s.charAt(i); - if (ch == '*') { - if (i + 1 < s.length()) { - mathTypeAfter = MathType.getType(s, i + 1, false); - } else { - mathTypeAfter = null; - } - - if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.getMathType(), mathTypeAfter == null ? null : mathTypeAfter.getMathType())) { - sb.append(CalculatorEngine.instance.getMultiplicationSign()); - } - - } else { - if (mathType.getMathType() == MathType.constant || mathType.getMathType() == MathType.function || mathType.getMathType() == MathType.operator) { - sb.append(mathType.getMatch()); - i += mathType.getMatch().length() - 1; - } else { - sb.append(ch); - } - mathTypeAfter = null; - } - - } - - return sb.toString(); - } - - private final List mathTypes = Arrays.asList(MathType.function, MathType.constant); - - private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) { - if (mathTypeBefore == null || mathTypeAfter == null) { - return true; - } else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) { - return false; - } else if ( mathTypeBefore == MathType.close_group_symbol ) { - return false; - } else if ( mathTypeAfter == MathType.open_group_symbol ) { - return false; - } - - return true; - } - -} +package org.solovyev.android.calculator.model; + +import jscl.math.Generic; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.CalculatorLocator; +import org.solovyev.android.calculator.CalculatorLocatorImpl; +import org.solovyev.android.calculator.math.MathType; + +import java.util.Arrays; +import java.util.List; + +/** + * User: serso + * Date: 10/20/11 + * Time: 2:59 PM + */ +public class FromJsclSimplifyTextProcessor implements TextProcessor { + + public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor(); + + public FromJsclSimplifyTextProcessor() { + } + + @NotNull + @Override + public String process(@NotNull Generic from) throws CalculatorParseException { + return removeMultiplicationSigns(from.toString()); + } + + public String process(@NotNull String s) { + return removeMultiplicationSigns(s); + } + + @NotNull + private String removeMultiplicationSigns(String s) { + final StringBuilder sb = new StringBuilder(); + + MathType.Result mathTypeBefore; + MathType.Result mathType = null; + MathType.Result mathTypeAfter = null; + + for (int i = 0; i < s.length(); i++) { + mathTypeBefore = mathType; + if (mathTypeAfter == null) { + mathType = MathType.getType(s, i, false); + } else { + mathType = mathTypeAfter; + } + + char ch = s.charAt(i); + if (ch == '*') { + if (i + 1 < s.length()) { + mathTypeAfter = MathType.getType(s, i + 1, false); + } else { + mathTypeAfter = null; + } + + if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.getMathType(), mathTypeAfter == null ? null : mathTypeAfter.getMathType())) { + sb.append(CalculatorLocatorImpl.getInstance().getCalculatorEngine().getMultiplicationSign()); + } + + } else { + if (mathType.getMathType() == MathType.constant || mathType.getMathType() == MathType.function || mathType.getMathType() == MathType.operator) { + sb.append(mathType.getMatch()); + i += mathType.getMatch().length() - 1; + } else { + sb.append(ch); + } + mathTypeAfter = null; + } + + } + + return sb.toString(); + } + + private final List mathTypes = Arrays.asList(MathType.function, MathType.constant); + + private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) { + if (mathTypeBefore == null || mathTypeAfter == null) { + return true; + } else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) { + return false; + } else if ( mathTypeBefore == MathType.close_group_symbol ) { + return false; + } else if ( mathTypeAfter == MathType.open_group_symbol ) { + return false; + } + + return true; + } + +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java similarity index 95% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java rename to calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java index 48b3b1a3..a72672fe 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java +++ b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/model/TextProcessor.java @@ -1,14 +1,14 @@ -package org.solovyev.android.calculator.model; - -import org.jetbrains.annotations.NotNull; - -/** - * User: serso - * Date: 9/26/11 - * Time: 12:12 PM - */ -public interface TextProcessor { - - @NotNull - TO process(@NotNull FROM from) throws CalculatorParseException; -} +package org.solovyev.android.calculator.model; + +import org.jetbrains.annotations.NotNull; + +/** + * User: serso + * Date: 9/26/11 + * Time: 12:12 PM + */ +public interface TextProcessor { + + @NotNull + TO process(@NotNull FROM from) throws CalculatorParseException; +} diff --git a/calculatorpp/pom.xml b/calculatorpp/pom.xml index ea6c981a..a117fa62 100644 --- a/calculatorpp/pom.xml +++ b/calculatorpp/pom.xml @@ -82,13 +82,6 @@ org.solovyev jscl - 0.0.2 - - - xercesImpl - xerces - - diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java index 10e5bc61..73a5cca1 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -1,92 +1,94 @@ -package org.solovyev.android.calculator; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.net.Uri; -import android.preference.PreferenceManager; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.TextView; -import net.robotmedia.billing.BillingController; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.ads.AdsController; -import org.solovyev.android.calculator.model.CalculatorEngine; - -/** - * User: serso - * Date: 12/1/11 - * Time: 1:21 PM - */ -public class CalculatorApplication extends android.app.Application { - - private static final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; - - public static final String AD_FREE_PRODUCT_ID = "ad_free"; - public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_ad_free"; - - public static final String ADMOB_USER_ID = "a14f02cf9c80cbc"; - public static final String REMOTE_STACK_TRACE_URL = "http://calculatorpp.com/crash_reports/upload.php"; - - @NotNull - private static CalculatorApplication instance; - - public CalculatorApplication() { - instance = this; - } - - @NotNull - public static CalculatorApplication getInstance() { - return instance; - } - - @Override - public void onCreate() { - super.onCreate(); - - AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { - - @Override - public byte[] getObfuscationSalt() { - return new byte[]{81, -114, 32, -127, -32, -104, -40, -15, -47, 57, -13, -41, -33, 67, -114, 7, -11, 53, 126, 82}; - } - - @Override - public String getPublicKey() { - return CalculatorSecurity.getPK(); - } - }); - - CalculatorEngine.instance.init(this, PreferenceManager.getDefaultSharedPreferences(this)); - - } - - public static void showDonationDialog(@NotNull final Context context) { - final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE); - final View view = layoutInflater.inflate(R.layout.donate, null); - - final TextView donate = (TextView) view.findViewById(R.id.donateText); - donate.setMovementMethod(LinkMovementMethod.getInstance()); - - final AlertDialog.Builder builder = new AlertDialog.Builder(context) - .setCancelable(true) - .setNegativeButton(R.string.c_cancel, null) - .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(paypalDonateUrl)); - context.startActivity(i); - } - }) - .setView(view); - - builder.create().show(); - } - - public static void registerOnRemoteStackTrace() { - //Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(null, REMOTE_STACK_TRACE_URL)); - } -} +package org.solovyev.android.calculator; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.preference.PreferenceManager; +import android.text.method.LinkMovementMethod; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; +import net.robotmedia.billing.BillingController; +import org.jetbrains.annotations.NotNull; +import org.solovyev.android.ads.AdsController; +import org.solovyev.android.calculator.model.CalculatorEngine; + +/** + * User: serso + * Date: 12/1/11 + * Time: 1:21 PM + */ +public class CalculatorApplication extends android.app.Application { + + private static final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=Android%20Calculator¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; + + public static final String AD_FREE_PRODUCT_ID = "ad_free"; + public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_ad_free"; + + public static final String ADMOB_USER_ID = "a14f02cf9c80cbc"; + public static final String REMOTE_STACK_TRACE_URL = "http://calculatorpp.com/crash_reports/upload.php"; + + @NotNull + private static CalculatorApplication instance; + + public CalculatorApplication() { + instance = this; + } + + @NotNull + public static CalculatorApplication getInstance() { + return instance; + } + + @Override + public void onCreate() { + super.onCreate(); + + CalculatorLocatorImpl.getInstance().setCalculatorEngine(CalculatorEngine.instance); + + AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { + + @Override + public byte[] getObfuscationSalt() { + return new byte[]{81, -114, 32, -127, -32, -104, -40, -15, -47, 57, -13, -41, -33, 67, -114, 7, -11, 53, 126, 82}; + } + + @Override + public String getPublicKey() { + return CalculatorSecurity.getPK(); + } + }); + + CalculatorEngine.instance.init(this, PreferenceManager.getDefaultSharedPreferences(this)); + + } + + public static void showDonationDialog(@NotNull final Context context) { + final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE); + final View view = layoutInflater.inflate(R.layout.donate, null); + + final TextView donate = (TextView) view.findViewById(R.id.donateText); + donate.setMovementMethod(LinkMovementMethod.getInstance()); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setCancelable(true) + .setNegativeButton(R.string.c_cancel, null) + .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(paypalDonateUrl)); + context.startActivity(i); + } + }) + .setView(view); + + builder.create().show(); + } + + public static void registerOnRemoteStackTrace() { + //Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(null, REMOTE_STACK_TRACE_URL)); + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java index e9cb74e2..a90b457a 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java @@ -1,110 +1,111 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.history; - -import org.jetbrains.annotations.NotNull; -import org.simpleframework.xml.Element; -import org.simpleframework.xml.Root; -import org.solovyev.android.calculator.ICalculatorDisplay; - -/** - * User: serso - * Date: 9/11/11 - * Time: 12:16 AM - */ - -@Root -public class CalculatorHistoryState extends AbstractHistoryState { - - @Element - @NotNull - private EditorHistoryState editorState; - - @Element - @NotNull - private CalculatorDisplayHistoryState displayState; - - private CalculatorHistoryState() { - // for xml - } - - private CalculatorHistoryState(@NotNull EditorHistoryState editorState, - @NotNull CalculatorDisplayHistoryState displayState) { - this.editorState = editorState; - this.displayState = displayState; - } - - public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull ICalculatorDisplay display) { - final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor); - final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display); - return new CalculatorHistoryState(editorHistoryState, displayHistoryState); - } - - @NotNull - public EditorHistoryState getEditorState() { - return editorState; - } - - public void setEditorState(@NotNull EditorHistoryState editorState) { - this.editorState = editorState; - } - - @NotNull - public CalculatorDisplayHistoryState getDisplayState() { - return displayState; - } - - public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) { - this.displayState = displayState; - } - - @Override - public String toString() { - return "CalculatorHistoryState{" + - "editorState=" + editorState + - ", displayState=" + displayState + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CalculatorHistoryState that = (CalculatorHistoryState) o; - - if (this.isSaved() != that.isSaved()) return false; - if (this.getId() != that.getId()) return false; - if (!displayState.equals(that.displayState)) return false; - if (!editorState.equals(that.editorState)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = Boolean.valueOf(isSaved()).hashCode(); - result = 31 * result + getId(); - result = 31 * result + editorState.hashCode(); - result = 31 * result + displayState.hashCode(); - return result; - } - - public void setValuesFromHistory(@NotNull Editor editor, @NotNull ICalculatorDisplay display) { - this.getEditorState().setValuesFromHistory(editor); - this.getDisplayState().setValuesFromHistory(display); - } - - @Override - protected CalculatorHistoryState clone() { - final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone(); - - clone.editorState = this.editorState.clone(); - clone.displayState = this.displayState.clone(); - - return clone; - } -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.history; + +import org.jetbrains.annotations.NotNull; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; +import org.solovyev.android.calculator.Editor; +import org.solovyev.android.calculator.ICalculatorDisplay; + +/** + * User: serso + * Date: 9/11/11 + * Time: 12:16 AM + */ + +@Root +public class CalculatorHistoryState extends AbstractHistoryState { + + @Element + @NotNull + private EditorHistoryState editorState; + + @Element + @NotNull + private CalculatorDisplayHistoryState displayState; + + private CalculatorHistoryState() { + // for xml + } + + private CalculatorHistoryState(@NotNull EditorHistoryState editorState, + @NotNull CalculatorDisplayHistoryState displayState) { + this.editorState = editorState; + this.displayState = displayState; + } + + public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull ICalculatorDisplay display) { + final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor); + final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display); + return new CalculatorHistoryState(editorHistoryState, displayHistoryState); + } + + @NotNull + public EditorHistoryState getEditorState() { + return editorState; + } + + public void setEditorState(@NotNull EditorHistoryState editorState) { + this.editorState = editorState; + } + + @NotNull + public CalculatorDisplayHistoryState getDisplayState() { + return displayState; + } + + public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) { + this.displayState = displayState; + } + + @Override + public String toString() { + return "CalculatorHistoryState{" + + "editorState=" + editorState + + ", displayState=" + displayState + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CalculatorHistoryState that = (CalculatorHistoryState) o; + + if (this.isSaved() != that.isSaved()) return false; + if (this.getId() != that.getId()) return false; + if (!displayState.equals(that.displayState)) return false; + if (!editorState.equals(that.editorState)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = Boolean.valueOf(isSaved()).hashCode(); + result = 31 * result + getId(); + result = 31 * result + editorState.hashCode(); + result = 31 * result + displayState.hashCode(); + return result; + } + + public void setValuesFromHistory(@NotNull Editor editor, @NotNull ICalculatorDisplay display) { + this.getEditorState().setValuesFromHistory(editor); + this.getDisplayState().setValuesFromHistory(display); + } + + @Override + protected CalculatorHistoryState clone() { + final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone(); + + clone.editorState = this.editorState.clone(); + clone.displayState = this.displayState.clone(); + + return clone; + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java index f087312b..ea2de8ab 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java @@ -1,87 +1,88 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.history; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.simpleframework.xml.Element; -import org.simpleframework.xml.Root; - -@Root -public class EditorHistoryState implements Cloneable{ - - @Element - private int cursorPosition; - - @Element(required = false) - @Nullable - private String text; - - private EditorHistoryState() { - // for xml - } - - @NotNull - public static EditorHistoryState newInstance(@NotNull Editor editor) { - final EditorHistoryState result = new EditorHistoryState(); - - result.text = String.valueOf(editor.getText()); - result.cursorPosition = editor.getSelection(); - - return result; - } - - public void setValuesFromHistory(@NotNull Editor editor) { - editor.setText(this.getText()); - editor.setSelection(this.getCursorPosition()); - } - - @Nullable - public String getText() { - return text; - } - - public int getCursorPosition() { - return cursorPosition; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof EditorHistoryState)) return false; - - EditorHistoryState that = (EditorHistoryState) o; - - if (cursorPosition != that.cursorPosition) return false; - if (text != null ? !text.equals(that.text) : that.text != null) return false; - - return true; - } - - @Override - public int hashCode() { - int result = cursorPosition; - result = 31 * result + (text != null ? text.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return "EditorHistoryState{" + - "cursorPosition=" + cursorPosition + - ", text='" + text + '\'' + - '}'; - } - - @Override - protected EditorHistoryState clone() { - try { - return (EditorHistoryState)super.clone(); - } catch (CloneNotSupportedException e) { - throw new UnsupportedOperationException(e); - } - } -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.history; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; +import org.solovyev.android.calculator.Editor; + +@Root +public class EditorHistoryState implements Cloneable{ + + @Element + private int cursorPosition; + + @Element(required = false) + @Nullable + private String text; + + private EditorHistoryState() { + // for xml + } + + @NotNull + public static EditorHistoryState newInstance(@NotNull Editor editor) { + final EditorHistoryState result = new EditorHistoryState(); + + result.text = String.valueOf(editor.getText()); + result.cursorPosition = editor.getSelection(); + + return result; + } + + public void setValuesFromHistory(@NotNull Editor editor) { + editor.setText(this.getText()); + editor.setSelection(this.getCursorPosition()); + } + + @Nullable + public String getText() { + return text; + } + + public int getCursorPosition() { + return cursorPosition; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof EditorHistoryState)) return false; + + EditorHistoryState that = (EditorHistoryState) o; + + if (cursorPosition != that.cursorPosition) return false; + if (text != null ? !text.equals(that.text) : that.text != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = cursorPosition; + result = 31 * result + (text != null ? text.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "EditorHistoryState{" + + "cursorPosition=" + cursorPosition + + ", text='" + text + '\'' + + '}'; + } + + @Override + protected EditorHistoryState clone() { + try { + return (EditorHistoryState)super.clone(); + } catch (CloneNotSupportedException e) { + throw new UnsupportedOperationException(e); + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/TextViewEditorAdapter.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/TextViewEditorAdapter.java index b494edd2..35207b07 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/TextViewEditorAdapter.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/TextViewEditorAdapter.java @@ -1,49 +1,50 @@ -/* - * 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.history; - -import android.widget.EditText; -import android.widget.TextView; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: serso - * Date: 12/17/11 - * Time: 9:39 PM - */ -public class TextViewEditorAdapter implements Editor { - - @NotNull - private final TextView textView; - - public TextViewEditorAdapter(@NotNull TextView textView) { - this.textView = textView; - } - - @Override - public CharSequence getText() { - return textView.getText().toString(); - } - - @Override - public void setText(@Nullable CharSequence text) { - textView.setText(text); - } - - @Override - public int getSelection() { - return textView.getSelectionStart(); - } - - @Override - public void setSelection(int selection) { - if ( textView instanceof EditText ) { - ((EditText) textView).setSelection(selection); - } - } -} +/* + * 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.history; + +import android.widget.EditText; +import android.widget.TextView; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.Editor; + +/** + * User: serso + * Date: 12/17/11 + * Time: 9:39 PM + */ +public class TextViewEditorAdapter implements Editor { + + @NotNull + private final TextView textView; + + public TextViewEditorAdapter(@NotNull TextView textView) { + this.textView = textView; + } + + @Override + public CharSequence getText() { + return textView.getText().toString(); + } + + @Override + public void setText(@Nullable CharSequence text) { + textView.setText(text); + } + + @Override + public int getSelection() { + return textView.getSelectionStart(); + } + + @Override + public void setSelection(int selection) { + if ( textView instanceof EditText ) { + ((EditText) textView).setSelection(selection); + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java index 68bcc9b8..3448880e 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java @@ -16,13 +16,16 @@ import jscl.text.ParseInterruptedException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.CalculatorApplication; +import org.solovyev.android.calculator.JCalculatorEngine; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.android.msg.AndroidMessage; import org.solovyev.android.prefs.BooleanPreference; import org.solovyev.android.prefs.Preference; import org.solovyev.android.prefs.StringPreference; import org.solovyev.common.MutableObject; import org.solovyev.common.msg.MessageRegistry; +import org.solovyev.common.msg.MessageType; import org.solovyev.common.text.EnumMapper; import org.solovyev.common.text.NumberMapper; import org.solovyev.common.text.StringUtils; @@ -40,7 +43,7 @@ import java.util.concurrent.TimeUnit; * Time: 11:38 PM */ -public enum CalculatorEngine { +public enum CalculatorEngine implements JCalculatorEngine { instance; @@ -130,7 +133,8 @@ public enum CalculatorEngine { this.engine.setUseGroupingSeparator(true); } - @NotNull + @Override + @NotNull public String getMultiplicationSign() { return multiplicationSign; } @@ -229,10 +233,12 @@ public enum CalculatorEngine { evalException.setObject(new CalculatorEvalException(e, e, jsclExpression)); } catch (ArithmeticException e) { //System.out.println(e.getMessage()); - parseException.setObject(new CalculatorParseException(R.string.msg_1, CalculatorApplication.getInstance(), jsclExpression, e.getMessage())); + final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_1, MessageType.error, CalculatorApplication.getInstance(), e.getMessage()); + parseException.setObject(new CalculatorParseException(jsclExpression, androidMessage)); } catch (StackOverflowError e) { //System.out.println(StringUtils.fromStackTrace(e.getStackTrace())); - parseException.setObject(new CalculatorParseException(R.string.msg_2, CalculatorApplication.getInstance(), jsclExpression)); + final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_2, MessageType.error, CalculatorApplication.getInstance()); + parseException.setObject(new CalculatorParseException(jsclExpression, androidMessage)); } catch (jscl.text.ParseException e) { //System.out.println(e.getMessage()); parseException.setObject(new CalculatorParseException(e)); @@ -278,11 +284,13 @@ public enum CalculatorEngine { } if (calculationResultLocal == null) { - throw new CalculatorParseException(R.string.msg_3, CalculatorApplication.getInstance(), jsclExpression); + final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_3, MessageType.error, CalculatorApplication.getInstance()); + throw new CalculatorParseException(jsclExpression, androidMessage); } } catch (InterruptedException e) { - throw new CalculatorParseException(R.string.msg_4, CalculatorApplication.getInstance(), jsclExpression); + final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_4, MessageType.error, CalculatorApplication.getInstance()); + throw new CalculatorParseException(jsclExpression, androidMessage); } final Generic genericResult = calculationResult.getObject(); @@ -356,27 +364,32 @@ public enum CalculatorEngine { } } - @NotNull + @Override + @NotNull public AndroidMathRegistry getVarsRegistry() { return varsRegistry; } - @NotNull + @Override + @NotNull public AndroidMathRegistry getFunctionsRegistry() { return functionsRegistry; } - @NotNull + @Override + @NotNull public AndroidMathRegistry getOperatorsRegistry() { return operatorsRegistry; } - @NotNull + @Override + @NotNull public AndroidMathRegistry getPostfixFunctionsRegistry() { return postfixFunctionsRegistry; } - @NotNull + @Override + @NotNull public MathEngine getEngine() { return engine; } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java index d12f3ca2..12067da4 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java @@ -10,9 +10,11 @@ import jscl.math.function.IConstant; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.CalculatorApplication; import org.solovyev.android.calculator.R; +import org.solovyev.android.msg.AndroidMessage; import org.solovyev.common.StartsWithFinder; import org.solovyev.android.calculator.math.MathType; import org.solovyev.common.collections.CollectionsUtils; +import org.solovyev.common.msg.MessageType; import java.util.ArrayList; import java.util.List; @@ -75,7 +77,8 @@ public class ToJsclTextProcessor implements TextProcessor undefinedVars) throws CalculatorParseException { if (depth >= MAX_DEPTH) { - throw new CalculatorParseException(R.string.msg_6, CalculatorApplication.getInstance(), s); + final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_6, MessageType.error, CalculatorApplication.getInstance()); + throw new CalculatorParseException(s, androidMessage); } else { depth++; } diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java index a58e72a5..c05f2a32 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/history/HistoryUtilsTest.java @@ -1,320 +1,321 @@ -/* - * 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.history; - -import jscl.math.Generic; -import junit.framework.Assert; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.junit.Test; -import org.solovyev.android.calculator.ICalculatorDisplay; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.equals.CollectionEqualizer; -import org.solovyev.common.equals.EqualsTool; -import org.solovyev.common.history.HistoryHelper; -import org.solovyev.common.history.SimpleHistoryHelper; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * User: serso - * Date: 12/17/11 - * Time: 10:01 PM - */ -public class HistoryUtilsTest { - - @Test - public void testFromXml() throws Exception { - - } - - private static final String emptyHistory = "\n" + - " \n" + - ""; - - private static final String toXml1 = "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 3\n" + - " 1+1\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " Error\n" + - " \n" + - " simplify\n" + - " \n" + - " \n" + - " \n" + - ""; - - private static final String toXml2 = "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 3\n" + - " 1+1\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " Error\n" + - " \n" + - " simplify\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 2\n" + - " 5/6\n" + - " \n" + - " \n" + - " \n" + - " 3\n" + - " 5/6\n" + - " \n" + - " numeric\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " null\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " Error\n" + - " \n" + - " elementary\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 0\n" + - " 4+5/35sin(41)+dfdsfsdfs\n" + - " \n" + - " \n" + - " \n" + - " 1\n" + - " 4+5/35sin(41)+dfdsfsdfs\n" + - " \n" + - " numeric\n" + - " \n" + - " \n" + - " \n" + - ""; - - @Test - public void testToXml() throws Exception { - final Date date = new Date(100000000); - - HistoryHelper history = new SimpleHistoryHelper(); - - ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay(); - calculatorDisplay.setErrorMessage("error_msg1"); - calculatorDisplay.setText("Error"); - calculatorDisplay.setSelection(1); - calculatorDisplay.setJsclOperation(JsclOperation.simplify); - - Editor calculatorEditor = new TestEditor(); - calculatorEditor.setSelection(3); - calculatorEditor.setText("1+1"); - - CalculatorHistoryState state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); - state.setTime(date.getTime()); - history.addState(state); - - Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history.getStates())); - - - state.setSaved(true); - - Assert.assertEquals(toXml1, HistoryUtils.toXml(history.getStates())); - - calculatorDisplay = new TestCalculatorDisplay(); - calculatorDisplay.setErrorMessage(null); - calculatorDisplay.setText("5/6"); - calculatorDisplay.setSelection(3); - calculatorDisplay.setJsclOperation(JsclOperation.numeric); - - calculatorEditor = new TestEditor(); - calculatorEditor.setSelection(2); - calculatorEditor.setText("5/6"); - - state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); - state.setSaved(true); - state.setTime(date.getTime()); - history.addState(state); - - calculatorDisplay = new TestCalculatorDisplay(); - calculatorDisplay.setErrorMessage("error_msg2"); - calculatorDisplay.setText("Error"); - calculatorDisplay.setSelection(1); - calculatorDisplay.setJsclOperation(JsclOperation.elementary); - - calculatorEditor = new TestEditor(); - calculatorEditor.setSelection(1); - calculatorEditor.setText(null); - - state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); - state.setSaved(true); - state.setTime(date.getTime()); - history.addState(state); - - calculatorDisplay = new TestCalculatorDisplay(); - calculatorDisplay.setErrorMessage(null); - calculatorDisplay.setText("4+5/35sin(41)+dfdsfsdfs"); - calculatorDisplay.setSelection(1); - calculatorDisplay.setJsclOperation(JsclOperation.numeric); - - calculatorEditor = new TestEditor(); - calculatorEditor.setSelection(0); - calculatorEditor.setText("4+5/35sin(41)+dfdsfsdfs"); - - state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); - state.setSaved(true); - state.setTime(date.getTime()); - history.addState(state); - - String xml = HistoryUtils.toXml(history.getStates()); - Assert.assertEquals(toXml2, xml); - - final List fromXml = new ArrayList(); - final HistoryHelper historyFromXml = new SimpleHistoryHelper(); - HistoryUtils.fromXml(xml, fromXml); - for (CalculatorHistoryState historyState : fromXml) { - historyFromXml.addState(historyState); - } - - Assert.assertEquals(history.getStates().size(), historyFromXml.getStates().size()); - - for (CalculatorHistoryState historyState : history.getStates()) { - historyState.setId(0); - historyState.setSaved(true); - } - for (CalculatorHistoryState historyState : historyFromXml.getStates()) { - historyState.setId(0); - historyState.setSaved(true); - } - Assert.assertTrue(EqualsTool.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer(null))); - } - - - private static class TestCalculatorDisplay implements ICalculatorDisplay { - - @NotNull - private final TestEditor testEditor = new TestEditor(); - - private boolean valid; - - private String errorMessage; - - private JsclOperation operation; - - private Generic genericResult; - - @Override - public boolean isValid() { - return this.valid; - } - - @Override - public void setValid(boolean valid) { - this.valid = valid; - } - - @Override - public String getErrorMessage() { - return this.errorMessage; - } - - @Override - public void setErrorMessage(@Nullable String errorMessage) { - this.errorMessage = errorMessage; - } - - @Override - public void setJsclOperation(@NotNull JsclOperation jsclOperation) { - this.operation = jsclOperation; - } - - @NotNull - @Override - public JsclOperation getJsclOperation() { - return this.operation; - } - - @Override - public void setGenericResult(@Nullable Generic genericResult) { - this.genericResult = genericResult; - } - - @Override - public Generic getGenericResult() { - return this.genericResult; - } - - @Override - public CharSequence getText() { - return this.testEditor.getText(); - } - - @Override - public void setText(@Nullable CharSequence text) { - this.testEditor.setText(text); - } - - @Override - public int getSelection() { - return this.testEditor.getSelection(); - } - - @Override - public void setSelection(int selection) { - this.testEditor.setSelection(selection); - } - } - - private static class TestEditor implements Editor { - - @Nullable - private CharSequence text; - - private int selection; - - @Nullable - @Override - public CharSequence getText() { - return this.text; - } - - @Override - public void setText(@Nullable CharSequence text) { - this.text = text; - } - - @Override - public int getSelection() { - return this.selection; - } - - @Override - public void setSelection(int selection) { - this.selection = selection; - } - } -} +/* + * 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.history; + +import jscl.math.Generic; +import junit.framework.Assert; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.Test; +import org.solovyev.android.calculator.Editor; +import org.solovyev.android.calculator.ICalculatorDisplay; +import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.common.equals.CollectionEqualizer; +import org.solovyev.common.equals.EqualsTool; +import org.solovyev.common.history.HistoryHelper; +import org.solovyev.common.history.SimpleHistoryHelper; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * User: serso + * Date: 12/17/11 + * Time: 10:01 PM + */ +public class HistoryUtilsTest { + + @Test + public void testFromXml() throws Exception { + + } + + private static final String emptyHistory = "\n" + + " \n" + + ""; + + private static final String toXml1 = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3\n" + + " 1+1\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " Error\n" + + " \n" + + " simplify\n" + + " \n" + + " \n" + + " \n" + + ""; + + private static final String toXml2 = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3\n" + + " 1+1\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " Error\n" + + " \n" + + " simplify\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 2\n" + + " 5/6\n" + + " \n" + + " \n" + + " \n" + + " 3\n" + + " 5/6\n" + + " \n" + + " numeric\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " null\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " Error\n" + + " \n" + + " elementary\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " 4+5/35sin(41)+dfdsfsdfs\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 4+5/35sin(41)+dfdsfsdfs\n" + + " \n" + + " numeric\n" + + " \n" + + " \n" + + " \n" + + ""; + + @Test + public void testToXml() throws Exception { + final Date date = new Date(100000000); + + HistoryHelper history = new SimpleHistoryHelper(); + + ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay(); + calculatorDisplay.setErrorMessage("error_msg1"); + calculatorDisplay.setText("Error"); + calculatorDisplay.setSelection(1); + calculatorDisplay.setJsclOperation(JsclOperation.simplify); + + Editor calculatorEditor = new TestEditor(); + calculatorEditor.setSelection(3); + calculatorEditor.setText("1+1"); + + CalculatorHistoryState state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); + state.setTime(date.getTime()); + history.addState(state); + + Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history.getStates())); + + + state.setSaved(true); + + Assert.assertEquals(toXml1, HistoryUtils.toXml(history.getStates())); + + calculatorDisplay = new TestCalculatorDisplay(); + calculatorDisplay.setErrorMessage(null); + calculatorDisplay.setText("5/6"); + calculatorDisplay.setSelection(3); + calculatorDisplay.setJsclOperation(JsclOperation.numeric); + + calculatorEditor = new TestEditor(); + calculatorEditor.setSelection(2); + calculatorEditor.setText("5/6"); + + state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); + state.setSaved(true); + state.setTime(date.getTime()); + history.addState(state); + + calculatorDisplay = new TestCalculatorDisplay(); + calculatorDisplay.setErrorMessage("error_msg2"); + calculatorDisplay.setText("Error"); + calculatorDisplay.setSelection(1); + calculatorDisplay.setJsclOperation(JsclOperation.elementary); + + calculatorEditor = new TestEditor(); + calculatorEditor.setSelection(1); + calculatorEditor.setText(null); + + state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); + state.setSaved(true); + state.setTime(date.getTime()); + history.addState(state); + + calculatorDisplay = new TestCalculatorDisplay(); + calculatorDisplay.setErrorMessage(null); + calculatorDisplay.setText("4+5/35sin(41)+dfdsfsdfs"); + calculatorDisplay.setSelection(1); + calculatorDisplay.setJsclOperation(JsclOperation.numeric); + + calculatorEditor = new TestEditor(); + calculatorEditor.setSelection(0); + calculatorEditor.setText("4+5/35sin(41)+dfdsfsdfs"); + + state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay); + state.setSaved(true); + state.setTime(date.getTime()); + history.addState(state); + + String xml = HistoryUtils.toXml(history.getStates()); + Assert.assertEquals(toXml2, xml); + + final List fromXml = new ArrayList(); + final HistoryHelper historyFromXml = new SimpleHistoryHelper(); + HistoryUtils.fromXml(xml, fromXml); + for (CalculatorHistoryState historyState : fromXml) { + historyFromXml.addState(historyState); + } + + Assert.assertEquals(history.getStates().size(), historyFromXml.getStates().size()); + + for (CalculatorHistoryState historyState : history.getStates()) { + historyState.setId(0); + historyState.setSaved(true); + } + for (CalculatorHistoryState historyState : historyFromXml.getStates()) { + historyState.setId(0); + historyState.setSaved(true); + } + Assert.assertTrue(EqualsTool.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer(null))); + } + + + private static class TestCalculatorDisplay implements ICalculatorDisplay { + + @NotNull + private final TestEditor testEditor = new TestEditor(); + + private boolean valid; + + private String errorMessage; + + private JsclOperation operation; + + private Generic genericResult; + + @Override + public boolean isValid() { + return this.valid; + } + + @Override + public void setValid(boolean valid) { + this.valid = valid; + } + + @Override + public String getErrorMessage() { + return this.errorMessage; + } + + @Override + public void setErrorMessage(@Nullable String errorMessage) { + this.errorMessage = errorMessage; + } + + @Override + public void setJsclOperation(@NotNull JsclOperation jsclOperation) { + this.operation = jsclOperation; + } + + @NotNull + @Override + public JsclOperation getJsclOperation() { + return this.operation; + } + + @Override + public void setGenericResult(@Nullable Generic genericResult) { + this.genericResult = genericResult; + } + + @Override + public Generic getGenericResult() { + return this.genericResult; + } + + @Override + public CharSequence getText() { + return this.testEditor.getText(); + } + + @Override + public void setText(@Nullable CharSequence text) { + this.testEditor.setText(text); + } + + @Override + public int getSelection() { + return this.testEditor.getSelection(); + } + + @Override + public void setSelection(int selection) { + this.testEditor.setSelection(selection); + } + } + + private static class TestEditor implements Editor { + + @Nullable + private CharSequence text; + + private int selection; + + @Nullable + @Override + public CharSequence getText() { + return this.text; + } + + @Override + public void setText(@Nullable CharSequence text) { + this.text = text; + } + + @Override + public int getSelection() { + return this.selection; + } + + @Override + public void setSelection(int selection) { + this.selection = selection; + } + } +} diff --git a/pom.xml b/pom.xml index 93bf95b9..041abf06 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,18 @@ 1.0.0 + + org.solovyev + jscl + 0.0.2 + + + xercesImpl + xerces + + + + org.solovyev.android android-common-other