Module separation

This commit is contained in:
serso 2012-09-20 12:59:21 +04:00
parent 33db715776
commit 417cf88912
23 changed files with 1567 additions and 1448 deletions

View File

@ -30,6 +30,11 @@
<artifactId>annotations</artifactId> <artifactId>annotations</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -1,19 +1,19 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
/** /**
* User: serso * User: serso
* Date: 10/24/11 * Date: 10/24/11
* Time: 9:55 PM * Time: 9:55 PM
*/ */
public interface CalculatorEngineControl { public interface CalculatorEngineControl {
void evaluate(); void evaluate();
void simplify(); void simplify();
} }

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -1,27 +1,27 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* User: serso * User: serso
* Date: 12/17/11 * Date: 12/17/11
* Time: 9:37 PM * Time: 9:37 PM
*/ */
public interface Editor { public interface Editor {
@Nullable @Nullable
CharSequence getText(); CharSequence getText();
void setText(@Nullable CharSequence text); void setText(@Nullable CharSequence text);
int getSelection(); int getSelection();
void setSelection(int selection); void setSelection(int selection);
} }

View File

@ -1,40 +1,40 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import jscl.math.Generic; import jscl.math.Generic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.history.Editor; import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
/** /**
* User: serso * User: serso
* Date: 12/17/11 * Date: 12/17/11
* Time: 9:45 PM * Time: 9:45 PM
*/ */
public interface ICalculatorDisplay extends Editor{ public interface ICalculatorDisplay extends Editor{
boolean isValid(); boolean isValid();
void setValid(boolean valid); void setValid(boolean valid);
@Nullable @Nullable
String getErrorMessage(); String getErrorMessage();
void setErrorMessage(@Nullable String errorMessage); void setErrorMessage(@Nullable String errorMessage);
void setJsclOperation(@NotNull JsclOperation jsclOperation); void setJsclOperation(@NotNull JsclOperation jsclOperation);
@NotNull @NotNull
JsclOperation getJsclOperation(); JsclOperation getJsclOperation();
void setGenericResult(@Nullable Generic genericResult); void setGenericResult(@Nullable Generic genericResult);
@Nullable @Nullable
Generic getGenericResult(); Generic getGenericResult();
} }

View File

@ -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<IConstant> getVarsRegistry();
@NotNull
MathRegistry<Function> getFunctionsRegistry();
@NotNull
MathRegistry<Operator> getOperatorsRegistry();
@NotNull
MathRegistry<Operator> getPostfixFunctionsRegistry();
@NotNull
MathEngine getEngine();
}

View File

@ -1,28 +1,28 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator.jscl; package org.solovyev.android.calculator.jscl;
import jscl.math.Generic; import jscl.math.Generic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.CalculatorParseException; import org.solovyev.android.calculator.model.CalculatorParseException;
import org.solovyev.android.calculator.model.TextProcessor; import org.solovyev.android.calculator.model.TextProcessor;
/** /**
* User: serso * User: serso
* Date: 10/6/11 * Date: 10/6/11
* Time: 9:48 PM * Time: 9:48 PM
*/ */
class FromJsclNumericTextProcessor implements TextProcessor<String, Generic> { class FromJsclNumericTextProcessor implements TextProcessor<String, Generic> {
public static final FromJsclNumericTextProcessor instance = new FromJsclNumericTextProcessor(); public static final FromJsclNumericTextProcessor instance = new FromJsclNumericTextProcessor();
@NotNull @NotNull
@Override @Override
public String process(@NotNull Generic numeric) throws CalculatorParseException { public String process(@NotNull Generic numeric) throws CalculatorParseException {
return numeric.toString().replace("*", ""); return numeric.toString().replace("*", "");
} }
} }

View File

@ -1,70 +1,70 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
*/ */
package org.solovyev.android.calculator.jscl; package org.solovyev.android.calculator.jscl;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.text.ParseException; import jscl.text.ParseException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.model.DummyTextProcessor; import org.solovyev.android.calculator.model.DummyTextProcessor;
import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor; import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor;
import org.solovyev.android.calculator.model.TextProcessor; import org.solovyev.android.calculator.model.TextProcessor;
public enum JsclOperation { public enum JsclOperation {
simplify, simplify,
elementary, elementary,
numeric; numeric;
JsclOperation() { JsclOperation() {
} }
@NotNull @NotNull
public TextProcessor<String, Generic> getFromProcessor() { public TextProcessor<String, Generic> getFromProcessor() {
switch (this) { switch (this) {
case simplify: case simplify:
return FromJsclSimplifyTextProcessor.instance; return FromJsclSimplifyTextProcessor.instance;
case elementary: case elementary:
return DummyTextProcessor.instance; return DummyTextProcessor.instance;
case numeric: case numeric:
return FromJsclNumericTextProcessor.instance; return FromJsclNumericTextProcessor.instance;
default: default:
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
@NotNull @NotNull
public final String evaluate(@NotNull String expression) throws ParseException { public final String evaluate(@NotNull String expression) throws ParseException {
switch (this) { switch (this) {
case simplify: case simplify:
return CalculatorEngine.instance.getEngine().simplify(expression); return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplify(expression);
case elementary: case elementary:
return CalculatorEngine.instance.getEngine().elementary(expression); return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementary(expression);
case numeric: case numeric:
return CalculatorEngine.instance.getEngine().evaluate(expression); return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluate(expression);
default: default:
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
@NotNull @NotNull
public final Generic evaluateGeneric(@NotNull String expression) throws ParseException { public final Generic evaluateGeneric(@NotNull String expression) throws ParseException {
switch (this) { switch (this) {
case simplify: case simplify:
return CalculatorEngine.instance.getEngine().simplifyGeneric(expression); return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplifyGeneric(expression);
case elementary: case elementary:
return CalculatorEngine.instance.getEngine().elementaryGeneric(expression); return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementaryGeneric(expression);
case numeric: case numeric:
return CalculatorEngine.instance.getEngine().evaluateGeneric(expression); return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluateGeneric(expression);
default: default:
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
} }

View File

@ -1,448 +1,445 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
*/ */
package org.solovyev.android.calculator.math; package org.solovyev.android.calculator.math;
import jscl.JsclMathEngine; import jscl.JsclMathEngine;
import jscl.NumeralBase; import jscl.NumeralBase;
import jscl.math.function.Constants; import jscl.math.function.Constants;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.common.JPredicate; import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.common.StartsWithFinder; import org.solovyev.common.JPredicate;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.common.StartsWithFinder;
import org.solovyev.android.calculator.model.CalculatorParseException; import org.solovyev.android.calculator.model.CalculatorParseException;
import org.solovyev.common.collections.CollectionsUtils; import org.solovyev.common.collections.CollectionsUtils;
import java.util.*; import java.util.*;
public enum MathType { public enum MathType {
numeral_base(50, true, false, MathGroupType.number) { numeral_base(50, true, false, MathGroupType.number) {
private final List<String> tokens = new ArrayList<String>(10); private final List<String> tokens = new ArrayList<String>(10);
{ {
for (NumeralBase numeralBase : NumeralBase.values()) { for (NumeralBase numeralBase : NumeralBase.values()) {
final String jsclPrefix = numeralBase.getJsclPrefix(); tokens.add(numeralBase.getJsclPrefix());
if (jsclPrefix != null) { }
tokens.add(jsclPrefix); }
}
} @NotNull
} @Override
public List<String> getTokens() {
@NotNull return tokens;
@Override }
public List<String> getTokens() { },
return tokens;
} dot(200, true, true, MathGroupType.number, ".") {
}, @Override
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
dot(200, true, true, MathGroupType.number, ".") { return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit;
@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 {
grouping_separator(250, false, false, MathGroupType.number, "'", " "){ return i;
@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) {
power_10(300, false, false, MathGroupType.number, "E"), @NotNull
@Override
postfix_function(400, false, true, MathGroupType.function) { public List<String> getTokens() {
@NotNull return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getPostfixFunctionsRegistry().getNames();
@Override }
public List<String> getTokens() { },
return CalculatorEngine.instance.getPostfixFunctionsRegistry().getNames();
} unary_operation(500, false, false, MathGroupType.operation, "-", "="),
}, binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "", "/", "^") {
@Override
unary_operation(500, false, false, MathGroupType.operation, "-", "="), protected String getSubstituteToJscl(@NotNull String match) {
binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "", "/", "^") { if (match.equals("×") || match.equals("")) {
@Override return "*";
protected String getSubstituteToJscl(@NotNull String match) { } else {
if (match.equals("×") || match.equals("")) { return null;
return "*"; }
} else { }
return null; },
}
} open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") {
}, @Override
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") { return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator;
@Override }
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator; @Override
} protected String getSubstituteToJscl(@NotNull String match) {
return "(";
@Override }
protected String getSubstituteToJscl(@NotNull String match) { },
return "(";
} close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") {
}, @Override
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") { return false;
@Override }
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
return false; @Override
} protected String getSubstituteToJscl(@NotNull String match) {
return ")";
@Override }
protected String getSubstituteToJscl(@NotNull String match) { },
return ")";
} function(1000, true, true, MathGroupType.function) {
}, @NotNull
@Override
function(1000, true, true, MathGroupType.function) { public List<String> getTokens() {
@NotNull return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getFunctionsRegistry().getNames();
@Override }
public List<String> getTokens() { },
return CalculatorEngine.instance.getFunctionsRegistry().getNames();
} operator(1050, true, true, MathGroupType.function) {
}, @NotNull
@Override
operator(1050, true, true, MathGroupType.function) { public List<String> getTokens() {
@NotNull return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getOperatorsRegistry().getNames();
@Override }
public List<String> getTokens() { },
return CalculatorEngine.instance.getOperatorsRegistry().getNames();
} constant(1100, true, true, MathGroupType.other) {
}, @NotNull
@Override
constant(1100, true, true, MathGroupType.other) { public List<String> getTokens() {
@NotNull return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().getNames();
@Override }
public List<String> 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);
@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<String> tokens = new ArrayList<String>(16);
digit(1125, true, true, MathGroupType.number) { {
for (Character character : NumeralBase.hex.getAcceptableCharacters()) {
private final List<String> tokens = new ArrayList<String>(16); tokens.add(character.toString());
{ }
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*/;
@Override }
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit && mathTypeBefore != dot /*&& mathTypeBefore != numeral_base*/; @NotNull
} @Override
public List<String> getTokens() {
@NotNull return tokens;
@Override }
public List<String> getTokens() { },
return tokens;
} comma(1150, false, false, MathGroupType.other, ","),
},
text(1200, false, false, MathGroupType.other) {
comma(1150, false, false, MathGroupType.other, ","), @Override
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
text(1200, false, false, MathGroupType.other) { if (match.length() > 0) {
@Override result.append(match.charAt(0));
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { }
if (match.length() > 0) { return i;
result.append(match.charAt(0)); }
}
return i; @Override
} public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
if (match.length() > 0) {
@Override result.append(match.charAt(0));
public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { }
if (match.length() > 0) { return i;
result.append(match.charAt(0)); }
} };
return i;
} public static enum MathGroupType {
}; function,
number,
public static enum MathGroupType { operation,
function, other
number, }
operation,
other @NotNull
} private final List<String> tokens;
@NotNull @NotNull
private final List<String> tokens; private final Integer priority;
@NotNull private final boolean needMultiplicationSignBefore;
private final Integer priority;
private final boolean needMultiplicationSignAfter;
private final boolean needMultiplicationSignBefore;
@NotNull
private final boolean needMultiplicationSignAfter; private final MathGroupType groupType;
@NotNull MathType(@NotNull Integer priority,
private final MathGroupType groupType; boolean needMultiplicationSignBefore,
boolean needMultiplicationSignAfter,
MathType(@NotNull Integer priority, @NotNull MathGroupType groupType,
boolean needMultiplicationSignBefore, @NotNull String... tokens) {
boolean needMultiplicationSignAfter, this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens));
@NotNull MathGroupType groupType, }
@NotNull String... tokens) {
this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens)); MathType(@NotNull Integer priority,
} boolean needMultiplicationSignBefore,
boolean needMultiplicationSignAfter,
MathType(@NotNull Integer priority, @NotNull MathGroupType groupType,
boolean needMultiplicationSignBefore, @NotNull List<String> tokens) {
boolean needMultiplicationSignAfter, this.priority = priority;
@NotNull MathGroupType groupType, this.needMultiplicationSignBefore = needMultiplicationSignBefore;
@NotNull List<String> tokens) { this.needMultiplicationSignAfter = needMultiplicationSignAfter;
this.priority = priority; this.groupType = groupType;
this.needMultiplicationSignBefore = needMultiplicationSignBefore; this.tokens = Collections.unmodifiableList(tokens);
this.needMultiplicationSignAfter = needMultiplicationSignAfter; }
this.groupType = groupType;
this.tokens = Collections.unmodifiableList(tokens); @NotNull
} public MathGroupType getGroupType() {
return groupType;
@NotNull }
public MathGroupType getGroupType() {
return groupType; /* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException {
} assert s.length() > position;
/* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException { int numberOfOpenGroups = 0;
assert s.length() > position; int result = position;
for (; result >= 0; result--) {
int numberOfOpenGroups = 0;
int result = position; final MathType mathType = getType(s.toString(), result).getMathType();
for (; result >= 0; result--) {
if (CollectionsUtils.contains(mathType, digit, dot, grouping_separator, power_10)) {
final MathType mathType = getType(s.toString(), result).getMathType(); // continue
} else if (mathType == close_group_symbol) {
if (CollectionsUtils.contains(mathType, digit, dot, grouping_separator, power_10)) { numberOfOpenGroups++;
// continue } else if (mathType == open_group_symbol) {
} else if (mathType == close_group_symbol) { if (numberOfOpenGroups > 0) {
numberOfOpenGroups++; numberOfOpenGroups--;
} else if (mathType == open_group_symbol) { } else {
if (numberOfOpenGroups > 0) { break;
numberOfOpenGroups--; }
} else { } else {
break; if (stop(s, numberOfOpenGroups, result)) break;
} }
} else { }
if (stop(s, numberOfOpenGroups, result)) break;
} if (numberOfOpenGroups != 0){
} throw new ParseException("Could not find start of prefix function!");
}
if (numberOfOpenGroups != 0){
throw new ParseException("Could not find start of prefix function!"); return result;
} }
return result; public static boolean stop(CharSequence s, int numberOfOpenGroups, int i) {
} if (numberOfOpenGroups == 0) {
if (i > 0) {
public static boolean stop(CharSequence s, int numberOfOpenGroups, int i) { final EndsWithFinder endsWithFinder = new EndsWithFinder(s);
if (numberOfOpenGroups == 0) { endsWithFinder.setI(i + 1);
if (i > 0) { if (!CollectionsUtils.contains(function.getTokens(), FilterType.included, endsWithFinder)) {
final EndsWithFinder endsWithFinder = new EndsWithFinder(s); MathType type = getType(s.toString(), i).getMathType();
endsWithFinder.setI(i + 1); if (type != constant) {
if (!CollectionsUtils.contains(function.getTokens(), FilterType.included, endsWithFinder)) { return true;
MathType type = getType(s.toString(), i).getMathType(); }
if (type != constant) { }
return true; } else {
} return true;
} }
} else { }
return true;
} return false;
} }*/
return false; @NotNull
}*/ public List<String> getTokens() {
return tokens;
@NotNull }
public List<String> getTokens() {
return tokens; private boolean isNeedMultiplicationSignBefore() {
} return needMultiplicationSignBefore;
}
private boolean isNeedMultiplicationSignBefore() {
return needMultiplicationSignBefore; private boolean isNeedMultiplicationSignAfter() {
} return needMultiplicationSignAfter;
}
private boolean isNeedMultiplicationSignAfter() {
return needMultiplicationSignAfter; public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
} return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter();
}
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);
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException { return returnI(i, match);
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;
protected int returnI(int i, @NotNull String match) { } else {
if (match.length() > 1) { return i;
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);
public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { return returnI(i, 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 getSubstituteFromJscl(@NotNull String match) {
return null; @Nullable
} protected String getSubstituteToJscl(@NotNull String match) {
return null;
@Nullable }
protected String getSubstituteToJscl(@NotNull String match) {
return null; public static final List<String> openGroupSymbols = Arrays.asList("[]", "()", "{}");
}
public final static Character POWER_10 = 'E';
public static final List<String> openGroupSymbols = Arrays.asList("[]", "()", "{}");
public static final String IMAGINARY_NUMBER = "i";
public final static Character POWER_10 = 'E'; public static final String IMAGINARY_NUMBER_JSCL = "√(-1)";
public static final String IMAGINARY_NUMBER = "i"; public static final String PI = "π";
public static final String IMAGINARY_NUMBER_JSCL = "√(-1)"; public static final String E = "e";
public static final String C = "c";
public static final String PI = "π"; public static final Double C_VALUE = 299792458d;
public static final String E = "e"; public static final String G = "G";
public static final String C = "c"; public static final Double G_VALUE = 6.6738480E-11;
public static final Double C_VALUE = 299792458d; public static final String H_REDUCED = "h";
public static final String G = "G"; public static final Double H_REDUCED_VALUE = 6.6260695729E-34 / ( 2 * Math.PI );
public static final Double G_VALUE = 6.6738480E-11; public final static String NAN = "NaN";
public static final String H_REDUCED = "h";
public static final Double H_REDUCED_VALUE = 6.6260695729E-34 / ( 2 * Math.PI ); public final static String INFINITY = "";
public final static String NAN = "NaN"; public final static String INFINITY_JSCL = "Infinity";
public final static String INFINITY = "";
public final static String INFINITY_JSCL = "Infinity"; /**
* Method determines mathematical entity type for text substring starting from ith index
*
/** *
* 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
* @param text analyzed text * @return math entity type of substring starting from ith index of specified text
* @param i index which points to start of substring */
* @param hexMode @NotNull
* @return math entity type of substring starting from ith index of specified text public static Result getType(@NotNull String text, int i, boolean hexMode) {
*/ if (i < 0) {
@NotNull throw new IllegalArgumentException("I must be more or equals to 0.");
public static Result getType(@NotNull String text, int i, boolean hexMode) { } else if (i >= text.length() && i != 0) {
if (i < 0) { throw new IllegalArgumentException("I must be less than size of text.");
throw new IllegalArgumentException("I must be more or equals to 0."); } else if (i == 0 && text.length() == 0) {
} else if (i >= text.length() && i != 0) { return new Result(MathType.text, text);
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 StartsWithFinder startsWithFinder = new StartsWithFinder(text, i); final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder);
if (s != null) {
for (MathType mathType : getMathTypesByPriority()) { if ( s.length() == 1 ) {
final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder); if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) {
if (s != null) { final Character ch = s.charAt(0);
if ( s.length() == 1 ) { if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) {
if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { return new Result(MathType.digit, s);
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, s);
} return new Result(MathType.text, text.substring(i));
} }
return new Result(MathType.text, text.substring(i));
} private static List<MathType> mathTypesByPriority;
@NotNull
private static List<MathType> mathTypesByPriority; private static List<MathType> getMathTypesByPriority() {
if (mathTypesByPriority == null) {
@NotNull final List<MathType> result = CollectionsUtils.asList(MathType.values());
private static List<MathType> getMathTypesByPriority() {
if (mathTypesByPriority == null) { Collections.sort(result, new Comparator<MathType>() {
final List<MathType> result = CollectionsUtils.asList(MathType.values()); @Override
public int compare(MathType l, MathType r) {
Collections.sort(result, new Comparator<MathType>() { return l.priority.compareTo(r.priority);
@Override }
public int compare(MathType l, MathType r) { });
return l.priority.compareTo(r.priority);
} mathTypesByPriority = result;
}); }
mathTypesByPriority = result; return mathTypesByPriority;
} }
return mathTypesByPriority; public static class Result {
}
@NotNull
public static class Result { private final MathType mathType;
@NotNull @NotNull
private final MathType mathType; private final String match;
@NotNull public Result(@NotNull MathType mathType, @NotNull String match) {
private final String match; this.mathType = mathType;
public Result(@NotNull MathType mathType, @NotNull String match) { this.match = 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 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);
}
public int processFromJscl(@NotNull StringBuilder result, int i) {
return mathType.processFromJscl(result, i, match); @NotNull
} public String getMatch() {
return match;
@NotNull }
public String getMatch() {
return match; @NotNull
} public MathType getMathType() {
return mathType;
@NotNull }
public MathType getMathType() { }
return mathType;
} private static class EndsWithFinder implements JPredicate<String> {
}
private int i;
private static class EndsWithFinder implements JPredicate<String> {
@NotNull
private int i; private final CharSequence targetString;
@NotNull private EndsWithFinder(@NotNull CharSequence targetString) {
private final CharSequence targetString; this.targetString = targetString;
}
private EndsWithFinder(@NotNull CharSequence targetString) {
this.targetString = targetString; @Override
} public boolean apply(@Nullable String s) {
return targetString.subSequence(0, i).toString().endsWith(s);
@Override }
public boolean apply(@Nullable String s) {
return targetString.subSequence(0, i).toString().endsWith(s); public void setI(int i) {
} this.i = i;
}
public void setI(int i) { }
this.i = i; }
}
}
}

View File

@ -6,10 +6,8 @@
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import android.app.Application;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.common.exceptions.SersoException; import org.solovyev.common.exceptions.SersoException;
import org.solovyev.common.msg.Message; import org.solovyev.common.msg.Message;
import org.solovyev.common.msg.MessageType; import org.solovyev.common.msg.MessageType;
@ -39,14 +37,17 @@ public class CalculatorParseException extends SersoException implements Message
this.position = jsclParseException.getPosition(); this.position = jsclParseException.getPosition();
} }
public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @Nullable Integer position, @NotNull String expression, Object... parameters) { public CalculatorParseException(@Nullable Integer position,
this.message = new AndroidMessage(messageId, MessageType.error, application, parameters); @NotNull String expression,
@NotNull Message message) {
this.message = message;
this.expression = expression; this.expression = expression;
this.position = position; this.position = position;
} }
public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @NotNull String expression, Object... parameters) { public CalculatorParseException(@NotNull String expression,
this(messageId, application, null, expression, parameters); @NotNull Message message) {
this(null, expression, message);
} }
@NotNull @NotNull

View File

@ -1,26 +1,26 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import jscl.math.Generic; import jscl.math.Generic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* User: serso * User: serso
* Date: 10/18/11 * Date: 10/18/11
* Time: 10:39 PM * Time: 10:39 PM
*/ */
public enum DummyTextProcessor implements TextProcessor<String, Generic> { public enum DummyTextProcessor implements TextProcessor<String, Generic> {
instance; instance;
@NotNull @NotNull
@Override @Override
public String process(@NotNull Generic s) throws CalculatorParseException { public String process(@NotNull Generic s) throws CalculatorParseException {
return s.toString(); return s.toString();
} }
} }

View File

@ -1,92 +1,94 @@
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import jscl.math.Generic; import jscl.math.Generic;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.CalculatorLocator;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import java.util.Arrays; import org.solovyev.android.calculator.math.MathType;
import java.util.List;
import java.util.Arrays;
/** import java.util.List;
* User: serso
* Date: 10/20/11 /**
* Time: 2:59 PM * User: serso
*/ * Date: 10/20/11
public class FromJsclSimplifyTextProcessor implements TextProcessor<String, Generic> { * Time: 2:59 PM
*/
public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor(); public class FromJsclSimplifyTextProcessor implements TextProcessor<String, Generic> {
public FromJsclSimplifyTextProcessor() { public static final FromJsclSimplifyTextProcessor instance = new FromJsclSimplifyTextProcessor();
}
public FromJsclSimplifyTextProcessor() {
@NotNull }
@Override
public String process(@NotNull Generic from) throws CalculatorParseException { @NotNull
return removeMultiplicationSigns(from.toString()); @Override
} public String process(@NotNull Generic from) throws CalculatorParseException {
return removeMultiplicationSigns(from.toString());
public String process(@NotNull String s) { }
return removeMultiplicationSigns(s);
} public String process(@NotNull String s) {
return removeMultiplicationSigns(s);
@NotNull }
private String removeMultiplicationSigns(String s) {
final StringBuilder sb = new StringBuilder(); @NotNull
private String removeMultiplicationSigns(String s) {
MathType.Result mathTypeBefore; final StringBuilder sb = new StringBuilder();
MathType.Result mathType = null;
MathType.Result mathTypeAfter = null; MathType.Result mathTypeBefore;
MathType.Result mathType = null;
for (int i = 0; i < s.length(); i++) { MathType.Result mathTypeAfter = null;
mathTypeBefore = mathType;
if (mathTypeAfter == null) { for (int i = 0; i < s.length(); i++) {
mathType = MathType.getType(s, i, false); mathTypeBefore = mathType;
} else { if (mathTypeAfter == null) {
mathType = mathTypeAfter; mathType = MathType.getType(s, i, false);
} } else {
mathType = mathTypeAfter;
char ch = s.charAt(i); }
if (ch == '*') {
if (i + 1 < s.length()) { char ch = s.charAt(i);
mathTypeAfter = MathType.getType(s, i + 1, false); if (ch == '*') {
} else { if (i + 1 < s.length()) {
mathTypeAfter = null; 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());
} 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()); } else {
i += mathType.getMatch().length() - 1; if (mathType.getMathType() == MathType.constant || mathType.getMathType() == MathType.function || mathType.getMathType() == MathType.operator) {
} else { sb.append(mathType.getMatch());
sb.append(ch); i += mathType.getMatch().length() - 1;
} } else {
mathTypeAfter = null; sb.append(ch);
} }
mathTypeAfter = null;
} }
return sb.toString(); }
}
return sb.toString();
private final List<MathType> mathTypes = Arrays.asList(MathType.function, MathType.constant); }
private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) { private final List<MathType> mathTypes = Arrays.asList(MathType.function, MathType.constant);
if (mathTypeBefore == null || mathTypeAfter == null) {
return true; private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) {
} else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) { if (mathTypeBefore == null || mathTypeAfter == null) {
return false; return true;
} else if ( mathTypeBefore == MathType.close_group_symbol ) { } else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) {
return false; return false;
} else if ( mathTypeAfter == MathType.open_group_symbol ) { } else if ( mathTypeBefore == MathType.close_group_symbol ) {
return false; return false;
} } else if ( mathTypeAfter == MathType.open_group_symbol ) {
return false;
return true; }
}
return true;
} }
}

View File

@ -1,14 +1,14 @@
package org.solovyev.android.calculator.model; package org.solovyev.android.calculator.model;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* User: serso * User: serso
* Date: 9/26/11 * Date: 9/26/11
* Time: 12:12 PM * Time: 12:12 PM
*/ */
public interface TextProcessor<TO extends CharSequence, FROM> { public interface TextProcessor<TO extends CharSequence, FROM> {
@NotNull @NotNull
TO process(@NotNull FROM from) throws CalculatorParseException; TO process(@NotNull FROM from) throws CalculatorParseException;
} }

View File

@ -82,13 +82,6 @@
<dependency> <dependency>
<groupId>org.solovyev</groupId> <groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId> <artifactId>jscl</artifactId>
<version>0.0.2</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!--OTHER--> <!--OTHER-->

View File

@ -1,92 +1,94 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import net.robotmedia.billing.BillingController; import net.robotmedia.billing.BillingController;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.ads.AdsController; import org.solovyev.android.ads.AdsController;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.CalculatorEngine;
/** /**
* User: serso * User: serso
* Date: 12/1/11 * Date: 12/1/11
* Time: 1:21 PM * Time: 1:21 PM
*/ */
public class CalculatorApplication extends android.app.Application { 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&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; 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&currency_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_PRODUCT_ID = "ad_free";
public static final String AD_FREE_P_KEY = "org.solovyev.android.calculator_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 ADMOB_USER_ID = "a14f02cf9c80cbc";
public static final String REMOTE_STACK_TRACE_URL = "http://calculatorpp.com/crash_reports/upload.php"; public static final String REMOTE_STACK_TRACE_URL = "http://calculatorpp.com/crash_reports/upload.php";
@NotNull @NotNull
private static CalculatorApplication instance; private static CalculatorApplication instance;
public CalculatorApplication() { public CalculatorApplication() {
instance = this; instance = this;
} }
@NotNull @NotNull
public static CalculatorApplication getInstance() { public static CalculatorApplication getInstance() {
return instance; return instance;
} }
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { CalculatorLocatorImpl.getInstance().setCalculatorEngine(CalculatorEngine.instance);
@Override AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() {
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 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(); @Override
} public String getPublicKey() {
}); return CalculatorSecurity.getPK();
}
CalculatorEngine.instance.init(this, PreferenceManager.getDefaultSharedPreferences(this)); });
} 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); public static void showDonationDialog(@NotNull final Context context) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
final TextView donate = (TextView) view.findViewById(R.id.donateText); final View view = layoutInflater.inflate(R.layout.donate, null);
donate.setMovementMethod(LinkMovementMethod.getInstance());
final TextView donate = (TextView) view.findViewById(R.id.donateText);
final AlertDialog.Builder builder = new AlertDialog.Builder(context) donate.setMovementMethod(LinkMovementMethod.getInstance());
.setCancelable(true)
.setNegativeButton(R.string.c_cancel, null) final AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() { .setCancelable(true)
@Override .setNegativeButton(R.string.c_cancel, null)
public void onClick(DialogInterface dialog, int which) { .setPositiveButton(R.string.c_donate, new DialogInterface.OnClickListener() {
final Intent i = new Intent(Intent.ACTION_VIEW); @Override
i.setData(Uri.parse(paypalDonateUrl)); public void onClick(DialogInterface dialog, int which) {
context.startActivity(i); final Intent i = new Intent(Intent.ACTION_VIEW);
} i.setData(Uri.parse(paypalDonateUrl));
}) context.startActivity(i);
.setView(view); }
})
builder.create().show(); .setView(view);
}
builder.create().show();
public static void registerOnRemoteStackTrace() { }
//Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(null, REMOTE_STACK_TRACE_URL));
} public static void registerOnRemoteStackTrace() {
} //Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(null, REMOTE_STACK_TRACE_URL));
}
}

View File

@ -1,110 +1,111 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
*/ */
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.solovyev.android.calculator.ICalculatorDisplay; import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.ICalculatorDisplay;
/**
* User: serso /**
* Date: 9/11/11 * User: serso
* Time: 12:16 AM * Date: 9/11/11
*/ * Time: 12:16 AM
*/
@Root
public class CalculatorHistoryState extends AbstractHistoryState { @Root
public class CalculatorHistoryState extends AbstractHistoryState {
@Element
@NotNull @Element
private EditorHistoryState editorState; @NotNull
private EditorHistoryState editorState;
@Element
@NotNull @Element
private CalculatorDisplayHistoryState displayState; @NotNull
private CalculatorDisplayHistoryState displayState;
private CalculatorHistoryState() {
// for xml private CalculatorHistoryState() {
} // for xml
}
private CalculatorHistoryState(@NotNull EditorHistoryState editorState,
@NotNull CalculatorDisplayHistoryState displayState) { private CalculatorHistoryState(@NotNull EditorHistoryState editorState,
this.editorState = editorState; @NotNull CalculatorDisplayHistoryState displayState) {
this.displayState = displayState; this.editorState = editorState;
} this.displayState = displayState;
}
public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor); public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display); final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor);
return new CalculatorHistoryState(editorHistoryState, displayHistoryState); final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display);
} return new CalculatorHistoryState(editorHistoryState, displayHistoryState);
}
@NotNull
public EditorHistoryState getEditorState() { @NotNull
return editorState; public EditorHistoryState getEditorState() {
} return editorState;
}
public void setEditorState(@NotNull EditorHistoryState editorState) {
this.editorState = editorState; public void setEditorState(@NotNull EditorHistoryState editorState) {
} this.editorState = editorState;
}
@NotNull
public CalculatorDisplayHistoryState getDisplayState() { @NotNull
return displayState; public CalculatorDisplayHistoryState getDisplayState() {
} return displayState;
}
public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) {
this.displayState = displayState; public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) {
} this.displayState = displayState;
}
@Override
public String toString() { @Override
return "CalculatorHistoryState{" + public String toString() {
"editorState=" + editorState + return "CalculatorHistoryState{" +
", displayState=" + displayState + "editorState=" + editorState +
'}'; ", displayState=" + displayState +
} '}';
}
@Override
public boolean equals(Object o) { @Override
if (this == o) return true; public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CalculatorHistoryState that = (CalculatorHistoryState) o;
CalculatorHistoryState that = (CalculatorHistoryState) o;
if (this.isSaved() != that.isSaved()) return false;
if (this.getId() != that.getId()) return false; if (this.isSaved() != that.isSaved()) return false;
if (!displayState.equals(that.displayState)) return false; if (this.getId() != that.getId()) return false;
if (!editorState.equals(that.editorState)) return false; if (!displayState.equals(that.displayState)) return false;
if (!editorState.equals(that.editorState)) return false;
return true;
} return true;
}
@Override
public int hashCode() { @Override
int result = Boolean.valueOf(isSaved()).hashCode(); public int hashCode() {
result = 31 * result + getId(); int result = Boolean.valueOf(isSaved()).hashCode();
result = 31 * result + editorState.hashCode(); result = 31 * result + getId();
result = 31 * result + displayState.hashCode(); result = 31 * result + editorState.hashCode();
return result; result = 31 * result + displayState.hashCode();
} return result;
}
public void setValuesFromHistory(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
this.getEditorState().setValuesFromHistory(editor); public void setValuesFromHistory(@NotNull Editor editor, @NotNull ICalculatorDisplay display) {
this.getDisplayState().setValuesFromHistory(display); this.getEditorState().setValuesFromHistory(editor);
} this.getDisplayState().setValuesFromHistory(display);
}
@Override
protected CalculatorHistoryState clone() { @Override
final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone(); protected CalculatorHistoryState clone() {
final CalculatorHistoryState clone = (CalculatorHistoryState)super.clone();
clone.editorState = this.editorState.clone();
clone.displayState = this.displayState.clone(); clone.editorState = this.editorState.clone();
clone.displayState = this.displayState.clone();
return clone;
} return clone;
} }
}

View File

@ -1,87 +1,88 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
*/ */
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.solovyev.android.calculator.Editor;
@Root
public class EditorHistoryState implements Cloneable{ @Root
public class EditorHistoryState implements Cloneable{
@Element
private int cursorPosition; @Element
private int cursorPosition;
@Element(required = false)
@Nullable @Element(required = false)
private String text; @Nullable
private String text;
private EditorHistoryState() {
// for xml private EditorHistoryState() {
} // for xml
}
@NotNull
public static EditorHistoryState newInstance(@NotNull Editor editor) { @NotNull
final EditorHistoryState result = new EditorHistoryState(); public static EditorHistoryState newInstance(@NotNull Editor editor) {
final EditorHistoryState result = new EditorHistoryState();
result.text = String.valueOf(editor.getText());
result.cursorPosition = editor.getSelection(); result.text = String.valueOf(editor.getText());
result.cursorPosition = editor.getSelection();
return result;
} return result;
}
public void setValuesFromHistory(@NotNull Editor editor) {
editor.setText(this.getText()); public void setValuesFromHistory(@NotNull Editor editor) {
editor.setSelection(this.getCursorPosition()); editor.setText(this.getText());
} editor.setSelection(this.getCursorPosition());
}
@Nullable
public String getText() { @Nullable
return text; public String getText() {
} return text;
}
public int getCursorPosition() {
return cursorPosition; public int getCursorPosition() {
} return cursorPosition;
}
@Override
public boolean equals(Object o) { @Override
if (this == o) return true; public boolean equals(Object o) {
if (!(o instanceof EditorHistoryState)) return false; if (this == o) return true;
if (!(o instanceof EditorHistoryState)) return false;
EditorHistoryState that = (EditorHistoryState) o;
EditorHistoryState that = (EditorHistoryState) o;
if (cursorPosition != that.cursorPosition) return false;
if (text != null ? !text.equals(that.text) : that.text != null) return false; if (cursorPosition != that.cursorPosition) return false;
if (text != null ? !text.equals(that.text) : that.text != null) return false;
return true;
} return true;
}
@Override
public int hashCode() { @Override
int result = cursorPosition; public int hashCode() {
result = 31 * result + (text != null ? text.hashCode() : 0); int result = cursorPosition;
return result; result = 31 * result + (text != null ? text.hashCode() : 0);
} return result;
}
@Override
public String toString() { @Override
return "EditorHistoryState{" + public String toString() {
"cursorPosition=" + cursorPosition + return "EditorHistoryState{" +
", text='" + text + '\'' + "cursorPosition=" + cursorPosition +
'}'; ", text='" + text + '\'' +
} '}';
}
@Override
protected EditorHistoryState clone() { @Override
try { protected EditorHistoryState clone() {
return (EditorHistoryState)super.clone(); try {
} catch (CloneNotSupportedException e) { return (EditorHistoryState)super.clone();
throw new UnsupportedOperationException(e); } catch (CloneNotSupportedException e) {
} throw new UnsupportedOperationException(e);
} }
} }
}

View File

@ -1,49 +1,50 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.Editor;
/**
* User: serso /**
* Date: 12/17/11 * User: serso
* Time: 9:39 PM * Date: 12/17/11
*/ * Time: 9:39 PM
public class TextViewEditorAdapter implements Editor { */
public class TextViewEditorAdapter implements Editor {
@NotNull
private final TextView textView; @NotNull
private final TextView textView;
public TextViewEditorAdapter(@NotNull TextView textView) {
this.textView = textView; public TextViewEditorAdapter(@NotNull TextView textView) {
} this.textView = textView;
}
@Override
public CharSequence getText() { @Override
return textView.getText().toString(); public CharSequence getText() {
} return textView.getText().toString();
}
@Override
public void setText(@Nullable CharSequence text) { @Override
textView.setText(text); public void setText(@Nullable CharSequence text) {
} textView.setText(text);
}
@Override
public int getSelection() { @Override
return textView.getSelectionStart(); public int getSelection() {
} return textView.getSelectionStart();
}
@Override
public void setSelection(int selection) { @Override
if ( textView instanceof EditText ) { public void setSelection(int selection) {
((EditText) textView).setSelection(selection); if ( textView instanceof EditText ) {
} ((EditText) textView).setSelection(selection);
} }
} }
}

View File

@ -16,13 +16,16 @@ import jscl.text.ParseInterruptedException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorApplication; import org.solovyev.android.calculator.CalculatorApplication;
import org.solovyev.android.calculator.JCalculatorEngine;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.android.prefs.BooleanPreference; import org.solovyev.android.prefs.BooleanPreference;
import org.solovyev.android.prefs.Preference; import org.solovyev.android.prefs.Preference;
import org.solovyev.android.prefs.StringPreference; import org.solovyev.android.prefs.StringPreference;
import org.solovyev.common.MutableObject; import org.solovyev.common.MutableObject;
import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.MessageRegistry;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.EnumMapper; import org.solovyev.common.text.EnumMapper;
import org.solovyev.common.text.NumberMapper; import org.solovyev.common.text.NumberMapper;
import org.solovyev.common.text.StringUtils; import org.solovyev.common.text.StringUtils;
@ -40,7 +43,7 @@ import java.util.concurrent.TimeUnit;
* Time: 11:38 PM * Time: 11:38 PM
*/ */
public enum CalculatorEngine { public enum CalculatorEngine implements JCalculatorEngine {
instance; instance;
@ -130,7 +133,8 @@ public enum CalculatorEngine {
this.engine.setUseGroupingSeparator(true); this.engine.setUseGroupingSeparator(true);
} }
@NotNull @Override
@NotNull
public String getMultiplicationSign() { public String getMultiplicationSign() {
return multiplicationSign; return multiplicationSign;
} }
@ -229,10 +233,12 @@ public enum CalculatorEngine {
evalException.setObject(new CalculatorEvalException(e, e, jsclExpression)); evalException.setObject(new CalculatorEvalException(e, e, jsclExpression));
} catch (ArithmeticException e) { } catch (ArithmeticException e) {
//System.out.println(e.getMessage()); //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) { } catch (StackOverflowError e) {
//System.out.println(StringUtils.fromStackTrace(e.getStackTrace())); //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) { } catch (jscl.text.ParseException e) {
//System.out.println(e.getMessage()); //System.out.println(e.getMessage());
parseException.setObject(new CalculatorParseException(e)); parseException.setObject(new CalculatorParseException(e));
@ -278,11 +284,13 @@ public enum CalculatorEngine {
} }
if (calculationResultLocal == null) { 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) { } 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(); final Generic genericResult = calculationResult.getObject();
@ -356,27 +364,32 @@ public enum CalculatorEngine {
} }
} }
@NotNull @Override
@NotNull
public AndroidMathRegistry<IConstant> getVarsRegistry() { public AndroidMathRegistry<IConstant> getVarsRegistry() {
return varsRegistry; return varsRegistry;
} }
@NotNull @Override
@NotNull
public AndroidMathRegistry<Function> getFunctionsRegistry() { public AndroidMathRegistry<Function> getFunctionsRegistry() {
return functionsRegistry; return functionsRegistry;
} }
@NotNull @Override
@NotNull
public AndroidMathRegistry<Operator> getOperatorsRegistry() { public AndroidMathRegistry<Operator> getOperatorsRegistry() {
return operatorsRegistry; return operatorsRegistry;
} }
@NotNull @Override
@NotNull
public AndroidMathRegistry<Operator> getPostfixFunctionsRegistry() { public AndroidMathRegistry<Operator> getPostfixFunctionsRegistry() {
return postfixFunctionsRegistry; return postfixFunctionsRegistry;
} }
@NotNull @Override
@NotNull
public MathEngine getEngine() { public MathEngine getEngine() {
return engine; return engine;
} }

View File

@ -10,9 +10,11 @@ import jscl.math.function.IConstant;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.CalculatorApplication; import org.solovyev.android.calculator.CalculatorApplication;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.common.StartsWithFinder; import org.solovyev.common.StartsWithFinder;
import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.collections.CollectionsUtils; import org.solovyev.common.collections.CollectionsUtils;
import org.solovyev.common.msg.MessageType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -75,7 +77,8 @@ public class ToJsclTextProcessor implements TextProcessor<PreparedExpression, St
if (mathTypeBefore != null && if (mathTypeBefore != null &&
(mathTypeBefore.getMathType() == MathType.function || mathTypeBefore.getMathType() == MathType.operator) && (mathTypeBefore.getMathType() == MathType.function || mathTypeBefore.getMathType() == MathType.operator) &&
CollectionsUtils.find(MathType.openGroupSymbols, startsWithFinder) != null) { CollectionsUtils.find(MathType.openGroupSymbols, startsWithFinder) != null) {
throw new CalculatorParseException(R.string.msg_5, CalculatorApplication.getInstance(), i, s, mathTypeBefore.getMatch()); final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_5, MessageType.error, CalculatorApplication.getInstance(), mathTypeBefore.getMatch());
throw new CalculatorParseException(i, s, androidMessage);
} }
i = mathTypeResult.processToJscl(result, i); i = mathTypeResult.processToJscl(result, i);
@ -86,7 +89,8 @@ public class ToJsclTextProcessor implements TextProcessor<PreparedExpression, St
@NotNull @NotNull
private static PreparedExpression replaceVariables(@NotNull final String s, int depth, @NotNull List<IConstant> undefinedVars) throws CalculatorParseException { private static PreparedExpression replaceVariables(@NotNull final String s, int depth, @NotNull List<IConstant> undefinedVars) throws CalculatorParseException {
if (depth >= MAX_DEPTH) { 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 { } else {
depth++; depth++;
} }

View File

@ -1,320 +1,321 @@
/* /*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev. * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com * For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org * or visit http://se.solovyev.org
*/ */
package org.solovyev.android.calculator.history; package org.solovyev.android.calculator.history;
import jscl.math.Generic; import jscl.math.Generic;
import junit.framework.Assert; import junit.framework.Assert;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.junit.Test; import org.junit.Test;
import org.solovyev.android.calculator.ICalculatorDisplay; import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.ICalculatorDisplay;
import org.solovyev.common.equals.CollectionEqualizer; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.equals.EqualsTool; import org.solovyev.common.equals.CollectionEqualizer;
import org.solovyev.common.history.HistoryHelper; import org.solovyev.common.equals.EqualsTool;
import org.solovyev.common.history.SimpleHistoryHelper; import org.solovyev.common.history.HistoryHelper;
import org.solovyev.common.history.SimpleHistoryHelper;
import java.util.ArrayList;
import java.util.Date; import java.util.ArrayList;
import java.util.List; import java.util.Date;
import java.util.List;
/**
* User: serso /**
* Date: 12/17/11 * User: serso
* Time: 10:01 PM * Date: 12/17/11
*/ * Time: 10:01 PM
public class HistoryUtilsTest { */
public class HistoryUtilsTest {
@Test
public void testFromXml() throws Exception { @Test
public void testFromXml() throws Exception {
}
}
private static final String emptyHistory = "<history>\n" +
" <historyItems class=\"java.util.ArrayList\"/>\n" + private static final String emptyHistory = "<history>\n" +
"</history>"; " <historyItems class=\"java.util.ArrayList\"/>\n" +
"</history>";
private static final String toXml1 = "<history>\n" +
" <historyItems class=\"java.util.ArrayList\">\n" + private static final String toXml1 = "<history>\n" +
" <calculatorHistoryState>\n" + " <historyItems class=\"java.util.ArrayList\">\n" +
" <time>100000000</time>\n" + " <calculatorHistoryState>\n" +
" <editorState>\n" + " <time>100000000</time>\n" +
" <cursorPosition>3</cursorPosition>\n" + " <editorState>\n" +
" <text>1+1</text>\n" + " <cursorPosition>3</cursorPosition>\n" +
" </editorState>\n" + " <text>1+1</text>\n" +
" <displayState>\n" + " </editorState>\n" +
" <editorState>\n" + " <displayState>\n" +
" <cursorPosition>1</cursorPosition>\n" + " <editorState>\n" +
" <text>Error</text>\n" + " <cursorPosition>1</cursorPosition>\n" +
" </editorState>\n" + " <text>Error</text>\n" +
" <jsclOperation>simplify</jsclOperation>\n" + " </editorState>\n" +
" </displayState>\n" + " <jsclOperation>simplify</jsclOperation>\n" +
" </calculatorHistoryState>\n" + " </displayState>\n" +
" </historyItems>\n" + " </calculatorHistoryState>\n" +
"</history>"; " </historyItems>\n" +
"</history>";
private static final String toXml2 = "<history>\n" +
" <historyItems class=\"java.util.ArrayList\">\n" + private static final String toXml2 = "<history>\n" +
" <calculatorHistoryState>\n" + " <historyItems class=\"java.util.ArrayList\">\n" +
" <time>100000000</time>\n" + " <calculatorHistoryState>\n" +
" <editorState>\n" + " <time>100000000</time>\n" +
" <cursorPosition>3</cursorPosition>\n" + " <editorState>\n" +
" <text>1+1</text>\n" + " <cursorPosition>3</cursorPosition>\n" +
" </editorState>\n" + " <text>1+1</text>\n" +
" <displayState>\n" + " </editorState>\n" +
" <editorState>\n" + " <displayState>\n" +
" <cursorPosition>1</cursorPosition>\n" + " <editorState>\n" +
" <text>Error</text>\n" + " <cursorPosition>1</cursorPosition>\n" +
" </editorState>\n" + " <text>Error</text>\n" +
" <jsclOperation>simplify</jsclOperation>\n" + " </editorState>\n" +
" </displayState>\n" + " <jsclOperation>simplify</jsclOperation>\n" +
" </calculatorHistoryState>\n" + " </displayState>\n" +
" <calculatorHistoryState>\n" + " </calculatorHistoryState>\n" +
" <time>100000000</time>\n" + " <calculatorHistoryState>\n" +
" <editorState>\n" + " <time>100000000</time>\n" +
" <cursorPosition>2</cursorPosition>\n" + " <editorState>\n" +
" <text>5/6</text>\n" + " <cursorPosition>2</cursorPosition>\n" +
" </editorState>\n" + " <text>5/6</text>\n" +
" <displayState>\n" + " </editorState>\n" +
" <editorState>\n" + " <displayState>\n" +
" <cursorPosition>3</cursorPosition>\n" + " <editorState>\n" +
" <text>5/6</text>\n" + " <cursorPosition>3</cursorPosition>\n" +
" </editorState>\n" + " <text>5/6</text>\n" +
" <jsclOperation>numeric</jsclOperation>\n" + " </editorState>\n" +
" </displayState>\n" + " <jsclOperation>numeric</jsclOperation>\n" +
" </calculatorHistoryState>\n" + " </displayState>\n" +
" <calculatorHistoryState>\n" + " </calculatorHistoryState>\n" +
" <time>100000000</time>\n" + " <calculatorHistoryState>\n" +
" <editorState>\n" + " <time>100000000</time>\n" +
" <cursorPosition>1</cursorPosition>\n" + " <editorState>\n" +
" <text>null</text>\n" + " <cursorPosition>1</cursorPosition>\n" +
" </editorState>\n" + " <text>null</text>\n" +
" <displayState>\n" + " </editorState>\n" +
" <editorState>\n" + " <displayState>\n" +
" <cursorPosition>1</cursorPosition>\n" + " <editorState>\n" +
" <text>Error</text>\n" + " <cursorPosition>1</cursorPosition>\n" +
" </editorState>\n" + " <text>Error</text>\n" +
" <jsclOperation>elementary</jsclOperation>\n" + " </editorState>\n" +
" </displayState>\n" + " <jsclOperation>elementary</jsclOperation>\n" +
" </calculatorHistoryState>\n" + " </displayState>\n" +
" <calculatorHistoryState>\n" + " </calculatorHistoryState>\n" +
" <time>100000000</time>\n" + " <calculatorHistoryState>\n" +
" <editorState>\n" + " <time>100000000</time>\n" +
" <cursorPosition>0</cursorPosition>\n" + " <editorState>\n" +
" <text>4+5/35sin(41)+dfdsfsdfs</text>\n" + " <cursorPosition>0</cursorPosition>\n" +
" </editorState>\n" + " <text>4+5/35sin(41)+dfdsfsdfs</text>\n" +
" <displayState>\n" + " </editorState>\n" +
" <editorState>\n" + " <displayState>\n" +
" <cursorPosition>1</cursorPosition>\n" + " <editorState>\n" +
" <text>4+5/35sin(41)+dfdsfsdfs</text>\n" + " <cursorPosition>1</cursorPosition>\n" +
" </editorState>\n" + " <text>4+5/35sin(41)+dfdsfsdfs</text>\n" +
" <jsclOperation>numeric</jsclOperation>\n" + " </editorState>\n" +
" </displayState>\n" + " <jsclOperation>numeric</jsclOperation>\n" +
" </calculatorHistoryState>\n" + " </displayState>\n" +
" </historyItems>\n" + " </calculatorHistoryState>\n" +
"</history>"; " </historyItems>\n" +
"</history>";
@Test
public void testToXml() throws Exception { @Test
final Date date = new Date(100000000); public void testToXml() throws Exception {
final Date date = new Date(100000000);
HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setErrorMessage("error_msg1"); ICalculatorDisplay calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setText("Error"); calculatorDisplay.setErrorMessage("error_msg1");
calculatorDisplay.setSelection(1); calculatorDisplay.setText("Error");
calculatorDisplay.setJsclOperation(JsclOperation.simplify); calculatorDisplay.setSelection(1);
calculatorDisplay.setJsclOperation(JsclOperation.simplify);
Editor calculatorEditor = new TestEditor();
calculatorEditor.setSelection(3); Editor calculatorEditor = new TestEditor();
calculatorEditor.setText("1+1"); calculatorEditor.setSelection(3);
calculatorEditor.setText("1+1");
CalculatorHistoryState state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setTime(date.getTime()); CalculatorHistoryState state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
history.addState(state); state.setTime(date.getTime());
history.addState(state);
Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history.getStates()));
Assert.assertEquals(emptyHistory, HistoryUtils.toXml(history.getStates()));
state.setSaved(true);
state.setSaved(true);
Assert.assertEquals(toXml1, HistoryUtils.toXml(history.getStates()));
Assert.assertEquals(toXml1, HistoryUtils.toXml(history.getStates()));
calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setErrorMessage(null); calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setText("5/6"); calculatorDisplay.setErrorMessage(null);
calculatorDisplay.setSelection(3); calculatorDisplay.setText("5/6");
calculatorDisplay.setJsclOperation(JsclOperation.numeric); calculatorDisplay.setSelection(3);
calculatorDisplay.setJsclOperation(JsclOperation.numeric);
calculatorEditor = new TestEditor();
calculatorEditor.setSelection(2); calculatorEditor = new TestEditor();
calculatorEditor.setText("5/6"); calculatorEditor.setSelection(2);
calculatorEditor.setText("5/6");
state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setSaved(true); state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setTime(date.getTime()); state.setSaved(true);
history.addState(state); state.setTime(date.getTime());
history.addState(state);
calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setErrorMessage("error_msg2"); calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setText("Error"); calculatorDisplay.setErrorMessage("error_msg2");
calculatorDisplay.setSelection(1); calculatorDisplay.setText("Error");
calculatorDisplay.setJsclOperation(JsclOperation.elementary); calculatorDisplay.setSelection(1);
calculatorDisplay.setJsclOperation(JsclOperation.elementary);
calculatorEditor = new TestEditor();
calculatorEditor.setSelection(1); calculatorEditor = new TestEditor();
calculatorEditor.setText(null); calculatorEditor.setSelection(1);
calculatorEditor.setText(null);
state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setSaved(true); state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setTime(date.getTime()); state.setSaved(true);
history.addState(state); state.setTime(date.getTime());
history.addState(state);
calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setErrorMessage(null); calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setText("4+5/35sin(41)+dfdsfsdfs"); calculatorDisplay.setErrorMessage(null);
calculatorDisplay.setSelection(1); calculatorDisplay.setText("4+5/35sin(41)+dfdsfsdfs");
calculatorDisplay.setJsclOperation(JsclOperation.numeric); calculatorDisplay.setSelection(1);
calculatorDisplay.setJsclOperation(JsclOperation.numeric);
calculatorEditor = new TestEditor();
calculatorEditor.setSelection(0); calculatorEditor = new TestEditor();
calculatorEditor.setText("4+5/35sin(41)+dfdsfsdfs"); calculatorEditor.setSelection(0);
calculatorEditor.setText("4+5/35sin(41)+dfdsfsdfs");
state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setSaved(true); state = CalculatorHistoryState.newInstance(calculatorEditor, calculatorDisplay);
state.setTime(date.getTime()); state.setSaved(true);
history.addState(state); state.setTime(date.getTime());
history.addState(state);
String xml = HistoryUtils.toXml(history.getStates());
Assert.assertEquals(toXml2, xml); String xml = HistoryUtils.toXml(history.getStates());
Assert.assertEquals(toXml2, xml);
final List<CalculatorHistoryState> fromXml = new ArrayList<CalculatorHistoryState>();
final HistoryHelper<CalculatorHistoryState> historyFromXml = new SimpleHistoryHelper<CalculatorHistoryState>(); final List<CalculatorHistoryState> fromXml = new ArrayList<CalculatorHistoryState>();
HistoryUtils.fromXml(xml, fromXml); final HistoryHelper<CalculatorHistoryState> historyFromXml = new SimpleHistoryHelper<CalculatorHistoryState>();
for (CalculatorHistoryState historyState : fromXml) { HistoryUtils.fromXml(xml, fromXml);
historyFromXml.addState(historyState); for (CalculatorHistoryState historyState : fromXml) {
} historyFromXml.addState(historyState);
}
Assert.assertEquals(history.getStates().size(), historyFromXml.getStates().size());
Assert.assertEquals(history.getStates().size(), historyFromXml.getStates().size());
for (CalculatorHistoryState historyState : history.getStates()) {
historyState.setId(0); for (CalculatorHistoryState historyState : history.getStates()) {
historyState.setSaved(true); historyState.setId(0);
} historyState.setSaved(true);
for (CalculatorHistoryState historyState : historyFromXml.getStates()) { }
historyState.setId(0); for (CalculatorHistoryState historyState : historyFromXml.getStates()) {
historyState.setSaved(true); historyState.setId(0);
} historyState.setSaved(true);
Assert.assertTrue(EqualsTool.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer<CalculatorHistoryState>(null))); }
} Assert.assertTrue(EqualsTool.areEqual(history.getStates(), historyFromXml.getStates(), new CollectionEqualizer<CalculatorHistoryState>(null)));
}
private static class TestCalculatorDisplay implements ICalculatorDisplay {
private static class TestCalculatorDisplay implements ICalculatorDisplay {
@NotNull
private final TestEditor testEditor = new TestEditor(); @NotNull
private final TestEditor testEditor = new TestEditor();
private boolean valid;
private boolean valid;
private String errorMessage;
private String errorMessage;
private JsclOperation operation;
private JsclOperation operation;
private Generic genericResult;
private Generic genericResult;
@Override
public boolean isValid() { @Override
return this.valid; public boolean isValid() {
} return this.valid;
}
@Override
public void setValid(boolean valid) { @Override
this.valid = valid; public void setValid(boolean valid) {
} this.valid = valid;
}
@Override
public String getErrorMessage() { @Override
return this.errorMessage; public String getErrorMessage() {
} return this.errorMessage;
}
@Override
public void setErrorMessage(@Nullable String errorMessage) { @Override
this.errorMessage = errorMessage; public void setErrorMessage(@Nullable String errorMessage) {
} this.errorMessage = errorMessage;
}
@Override
public void setJsclOperation(@NotNull JsclOperation jsclOperation) { @Override
this.operation = jsclOperation; public void setJsclOperation(@NotNull JsclOperation jsclOperation) {
} this.operation = jsclOperation;
}
@NotNull
@Override @NotNull
public JsclOperation getJsclOperation() { @Override
return this.operation; public JsclOperation getJsclOperation() {
} return this.operation;
}
@Override
public void setGenericResult(@Nullable Generic genericResult) { @Override
this.genericResult = genericResult; public void setGenericResult(@Nullable Generic genericResult) {
} this.genericResult = genericResult;
}
@Override
public Generic getGenericResult() { @Override
return this.genericResult; public Generic getGenericResult() {
} return this.genericResult;
}
@Override
public CharSequence getText() { @Override
return this.testEditor.getText(); public CharSequence getText() {
} return this.testEditor.getText();
}
@Override
public void setText(@Nullable CharSequence text) { @Override
this.testEditor.setText(text); public void setText(@Nullable CharSequence text) {
} this.testEditor.setText(text);
}
@Override
public int getSelection() { @Override
return this.testEditor.getSelection(); public int getSelection() {
} return this.testEditor.getSelection();
}
@Override
public void setSelection(int selection) { @Override
this.testEditor.setSelection(selection); public void setSelection(int selection) {
} this.testEditor.setSelection(selection);
} }
}
private static class TestEditor implements Editor {
private static class TestEditor implements Editor {
@Nullable
private CharSequence text; @Nullable
private CharSequence text;
private int selection;
private int selection;
@Nullable
@Override @Nullable
public CharSequence getText() { @Override
return this.text; public CharSequence getText() {
} return this.text;
}
@Override
public void setText(@Nullable CharSequence text) { @Override
this.text = text; public void setText(@Nullable CharSequence text) {
} this.text = text;
}
@Override
public int getSelection() { @Override
return this.selection; public int getSelection() {
} return this.selection;
}
@Override
public void setSelection(int selection) { @Override
this.selection = selection; public void setSelection(int selection) {
} this.selection = selection;
} }
} }
}

12
pom.xml
View File

@ -72,6 +72,18 @@
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
<version>0.0.2</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency> <dependency>
<groupId>org.solovyev.android</groupId> <groupId>org.solovyev.android</groupId>
<artifactId>android-common-other</artifactId> <artifactId>android-common-other</artifactId>