diff --git a/calculatorpp-core/pom.xml b/calculatorpp-core/pom.xml deleted file mode 100644 index 17ae2ad2..00000000 --- a/calculatorpp-core/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - 4.0.0 - - - org.solovyev.android - calculatorpp-parent - 1.3.1 - - - org.solovyev.android - calculatorpp-core - 1.3.1 - Calculator++ Application Core - - jar - - - - - junit - junit - test - - - - com.intellij - annotations - - - - org.solovyev - jscl - - - - org.simpleframework - simple-xml - - - - - - \ No newline at end of file diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java deleted file mode 100644 index 28b2ae45..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Calculator.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.msg.MessageRegistry; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:38 - */ -public interface Calculator extends CalculatorEventContainer { - - @NotNull - CalculatorEventDataId createFirstEventDataId(); - - void evaluate(@NotNull JsclOperation operation, - @NotNull String expression); - - @NotNull - CalculatorEventDataId evaluate(@NotNull JsclOperation operation, - @NotNull String expression, - @Nullable MessageRegistry mr); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java deleted file mode 100644 index a68d9747..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - * or visit http://se.solovyev.org - */ - -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: serso - * Date: 12/17/11 - * Time: 9:45 PM - */ -public interface CalculatorDisplay extends CalculatorEventListener { - - void setView(@Nullable CalculatorDisplayView view); - - @NotNull - CalculatorDisplayViewState getViewState(); - - void setViewState(@NotNull CalculatorDisplayViewState viewState); - - @NotNull - CalculatorEventData getLastEventData(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java deleted file mode 100644 index 5e794275..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayImpl.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import static org.solovyev.android.calculator.CalculatorEventType.*; - -/** - * User: serso - * Date: 9/20/12 - * Time: 8:24 PM - */ -public class CalculatorDisplayImpl implements CalculatorDisplay { - - @NotNull - private CalculatorEventData lastCalculatorEventData = CalculatorEventDataImpl.newInstance(CalculatorLocatorImpl.getInstance().getCalculator().createFirstEventDataId()); - - @Nullable - private CalculatorDisplayView view; - - @NotNull - private final Object viewLock = new Object(); - - @NotNull - private CalculatorDisplayViewState lastViewState = CalculatorDisplayViewStateImpl.newDefaultInstance(); - - @Override - public void setView(@Nullable CalculatorDisplayView view) { - synchronized (viewLock) { - this.view = view; - - if (view != null) { - this.view.setState(lastViewState); - } - } - } - - @NotNull - @Override - public CalculatorDisplayViewState getViewState() { - return this.lastViewState; - } - - @Override - public void setViewState(@NotNull CalculatorDisplayViewState viewState) { - synchronized (viewLock) { - this.lastViewState = viewState; - if (this.view != null) { - this.view.setState(viewState); - } - } - } - -/* @Override - @Nullable - public CharSequence getText() { - synchronized (viewLock) { - return view != null ? view.getText() : null; - } - } - - @Override - public void setText(@Nullable CharSequence text) { - synchronized (viewLock) { - if (view != null) { - view.setText(text); - } - } - } - - @Override - public int getSelection() { - synchronized (viewLock) { - return view != null ? view.getSelection() : 0; - } - } - - @Override - public void setSelection(int selection) { - synchronized (viewLock) { - if (view != null) { - view.setSelection(selection); - } - } - }*/ - - @Override - @NotNull - public CalculatorEventData getLastEventData() { - return lastCalculatorEventData; - } - - @Override - public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, - @NotNull CalculatorEventType calculatorEventType, - @Nullable Object data) { - if (calculatorEventType.isOfType(calculation_result, calculation_failed, calculation_cancelled)) { - - if (calculatorEventData.isAfter(lastCalculatorEventData)) { - lastCalculatorEventData = calculatorEventData; - } - - switch (calculatorEventType) { - case calculation_result: - processCalculationResult((CalculatorEvaluationEventData)calculatorEventData, (CalculatorOutput) data); - break; - case calculation_cancelled: - processCalculationCancelled((CalculatorEvaluationEventData)calculatorEventData); - break; - case calculation_failed: - processCalculationFailed((CalculatorEvaluationEventData)calculatorEventData, (CalculatorFailure) data); - break; - } - - } - } - - private void processCalculationFailed(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorFailure data) { - - final CalculatorEvalException calculatorEvalException = data.getCalculationEvalException(); - - final String errorMessage; - if (calculatorEvalException != null) { - errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error); - } else { - final CalculatorParseException calculationParseException = data.getCalculationParseException(); - if (calculationParseException != null) { - errorMessage = calculationParseException.getLocalizedMessage(); - } else { - errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error); - } - } - - this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage)); - } - - private void processCalculationCancelled(@NotNull CalculatorEvaluationEventData calculatorEventData) { - final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error); - - this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage)); - } - - private void processCalculationResult(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorOutput data) { - final String stringResult = data.getStringResult(); - this.setViewState(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0)); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java deleted file mode 100644 index 5ddc45df..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayView.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; - -/** - * User: serso - * Date: 9/20/12 - * Time: 8:25 PM - */ -public interface CalculatorDisplayView { - - void setState(@NotNull CalculatorDisplayViewState state); - - @NotNull - CalculatorDisplayViewState getState(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayViewState.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayViewState.java deleted file mode 100644 index 2fdc83b3..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayViewState.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.solovyev.android.calculator; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 9/20/12 - * Time: 9:50 PM - */ -public interface CalculatorDisplayViewState { - - @NotNull - String getText(); - - int getSelection(); - - @Nullable - Generic getResult(); - - boolean isValid(); - - @Nullable - String getErrorMessage(); - - @NotNull - JsclOperation getOperation(); - - @Nullable - String getStringResult(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayViewStateImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayViewStateImpl.java deleted file mode 100644 index ac13a9bc..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorDisplayViewStateImpl.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.solovyev.android.calculator; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.text.StringUtils; - -/** - * User: serso - * Date: 9/20/12 - * Time: 9:50 PM - */ -public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewState { - - @NotNull - private JsclOperation operation = JsclOperation.numeric; - - @Nullable - private Generic result; - - @Nullable - private String stringResult = ""; - - private boolean valid = true; - - @Nullable - private String errorMessage; - - private int selection = 0; - - private CalculatorDisplayViewStateImpl() { - } - - @NotNull - public static CalculatorDisplayViewState newDefaultInstance() { - return new CalculatorDisplayViewStateImpl(); - } - - @NotNull - public static CalculatorDisplayViewState newErrorState(@NotNull JsclOperation operation, - @NotNull String errorMessage) { - final CalculatorDisplayViewStateImpl calculatorDisplayState = new CalculatorDisplayViewStateImpl(); - calculatorDisplayState.valid = false; - calculatorDisplayState.errorMessage = errorMessage; - calculatorDisplayState.operation = operation; - return calculatorDisplayState; - } - - @NotNull - public static CalculatorDisplayViewState newValidState(@NotNull JsclOperation operation, - @Nullable Generic result, - @NotNull String stringResult, - int selection) { - final CalculatorDisplayViewStateImpl calculatorDisplayState = new CalculatorDisplayViewStateImpl(); - calculatorDisplayState.valid = true; - calculatorDisplayState.result = result; - calculatorDisplayState.stringResult = stringResult; - calculatorDisplayState.operation = operation; - calculatorDisplayState.selection = selection; - - return calculatorDisplayState; - } - - @NotNull - @Override - public String getText() { - return StringUtils.getNotEmpty(isValid() ? stringResult : errorMessage, ""); - } - - @Override - public int getSelection() { - return selection; - } - - @Nullable - @Override - public Generic getResult() { - return this.result; - } - - @Override - public boolean isValid() { - return this.valid; - } - - @Nullable - @Override - public String getErrorMessage() { - return this.errorMessage; - } - - @Override - @Nullable - public String getStringResult() { - return stringResult; - } - - @NotNull - @Override - public JsclOperation getOperation() { - return this.operation; - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventData.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventData.java deleted file mode 100644 index 45c74178..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventData.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 9/20/12 - * Time: 10:00 PM - */ -public interface CalculatorEvaluationEventData extends CalculatorEventData{ - - @NotNull - JsclOperation getOperation(); - - @NotNull - String getExpression(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java deleted file mode 100644 index f40cd6cf..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvaluationEventDataImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 9/20/12 - * Time: 10:01 PM - */ -public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData { - - @NotNull - private final CalculatorEventData calculatorEventData; - - @NotNull - private final JsclOperation operation; - - @NotNull - private final String expression; - - public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData, - @NotNull JsclOperation operation, - @NotNull String expression) { - this.calculatorEventData = calculatorEventData; - this.operation = operation; - this.expression = expression; - } - - @NotNull - @Override - public JsclOperation getOperation() { - return this.operation; - } - - @NotNull - @Override - public String getExpression() { - return this.expression; - } - - @Override - public long getEventId() { - return calculatorEventData.getEventId(); - } - - @Override - @Nullable - public Long getCalculationId() { - return calculatorEventData.getCalculationId(); - } - - @Override - public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) { - return calculatorEventData.isAfter(calculatorEventDataId); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventContainer.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventContainer.java deleted file mode 100644 index 20d918d6..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventContainer.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:39 - */ -public interface CalculatorEventContainer { - - void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener); - - void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener); - - void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data); - - void fireCalculatorEvents(@NotNull List calculatorEvents); - - public static class CalculatorEvent { - - @NotNull - private CalculatorEventData calculatorEventData; - - @NotNull - private CalculatorEventType calculatorEventType; - - @Nullable - private Object data; - - public CalculatorEvent(@NotNull CalculatorEventData calculatorEventData, - @NotNull CalculatorEventType calculatorEventType, - @Nullable Object data) { - this.calculatorEventData = calculatorEventData; - this.calculatorEventType = calculatorEventType; - this.data = data; - } - - @NotNull - public CalculatorEventData getCalculatorEventData() { - return calculatorEventData; - } - - @NotNull - public CalculatorEventType getCalculatorEventType() { - return calculatorEventType; - } - - @Nullable - public Object getData() { - return data; - } - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventData.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventData.java deleted file mode 100644 index 567808a7..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventData.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.solovyev.android.calculator; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:51 - */ -public interface CalculatorEventData extends CalculatorEventDataId { - -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java deleted file mode 100644 index f77558cd..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataId.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 18:18 - */ -public interface CalculatorEventDataId { - - // the higher id => the later event - long getEventId(); - - @Nullable - Long getCalculationId(); - - boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java deleted file mode 100644 index 0eb8d4a0..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataIdImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 18:18 - */ -class CalculatorEventDataIdImpl implements CalculatorEventDataId { - - private final long eventId; - - @Nullable - private final Long calculationId; - - private CalculatorEventDataIdImpl(long id, - @Nullable Long calculationId) { - this.eventId = id; - this.calculationId = calculationId; - } - - @NotNull - static CalculatorEventDataId newInstance(long id, - @Nullable Long calculationId) { - return new CalculatorEventDataIdImpl(id, calculationId); - } - - @Override - public long getEventId() { - return this.eventId; - } - - @Nullable - @Override - public Long getCalculationId() { - return this.calculationId; - } - - @Override - public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) { - return this.eventId > calculatorEventDataId.getEventId(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CalculatorEventDataIdImpl)) return false; - - CalculatorEventDataIdImpl that = (CalculatorEventDataIdImpl) o; - - if (eventId != that.eventId) return false; - if (calculationId != null ? !calculationId.equals(that.calculationId) : that.calculationId != null) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = (int) (eventId ^ (eventId >>> 32)); - result = 31 * result + (calculationId != null ? calculationId.hashCode() : 0); - return result; - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java deleted file mode 100644 index 4f7151ce..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventDataImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:54 - */ -class CalculatorEventDataImpl implements CalculatorEventData { - - @NotNull - private CalculatorEventDataId calculatorEventDataId; - - private CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) { - this.calculatorEventDataId = calculatorEventDataId; - } - - @NotNull - public static CalculatorEventData newInstance(@NotNull CalculatorEventDataId calculatorEventDataId) { - return new CalculatorEventDataImpl(calculatorEventDataId); - } - - @Override - public long getEventId() { - return calculatorEventDataId.getEventId(); - } - - @Override - @Nullable - public Long getCalculationId() { - return calculatorEventDataId.getCalculationId(); - } - - @Override - public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) { - return this.calculatorEventDataId.isAfter(calculatorEventDataId); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CalculatorEventDataImpl)) return false; - - CalculatorEventDataImpl that = (CalculatorEventDataImpl) o; - - if (!calculatorEventDataId.equals(that.calculatorEventDataId)) return false; - - return true; - } - - @Override - public int hashCode() { - return calculatorEventDataId.hashCode(); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventListener.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventListener.java deleted file mode 100644 index ea4a34f6..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.EventListener; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:39 - */ -public interface CalculatorEventListener extends EventListener { - - void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data); - -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java deleted file mode 100644 index 95568893..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEventType.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:40 - */ -public enum CalculatorEventType { - - /* - ********************************************************************** - * - * org.solovyev.android.calculator.CalculatorEvaluationEventData - * - ********************************************************************** - */ - - // @NotNull org.solovyev.android.calculator.CalculatorInput - calculation_started, - - // @NotNull org.solovyev.android.calculator.CalculatorOutput - calculation_result, - - calculation_cancelled, - - calculation_finished, - - // @NotNull org.solovyev.android.calculator.CalculatorFailure - calculation_failed; - - public boolean isOfType(@NotNull CalculatorEventType... types) { - for (CalculatorEventType type : types) { - if ( this == type ) { - return true; - } - } - - return false; - } - -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorFailure.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorFailure.java deleted file mode 100644 index 5d07bb40..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorFailure.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: serso - * Date: 9/20/12 - * Time: 7:33 PM - */ -public interface CalculatorFailure { - - @NotNull - Exception getException(); - - @Nullable - CalculatorParseException getCalculationParseException(); - - @Nullable - CalculatorEvalException getCalculationEvalException(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorFailureImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorFailureImpl.java deleted file mode 100644 index 866146b3..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorFailureImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; - -/** - * User: serso - * Date: 9/20/12 - * Time: 7:34 PM - */ -public class CalculatorFailureImpl implements CalculatorFailure { - - @NotNull - private Exception exception; - - public CalculatorFailureImpl(@NotNull Exception exception) { - this.exception = exception; - } - - @NotNull - @Override - public Exception getException() { - return this.exception; - } - - @Override - public CalculatorParseException getCalculationParseException() { - return exception instanceof CalculatorParseException ? (CalculatorParseException)exception : null; - } - - @Override - public CalculatorEvalException getCalculationEvalException() { - return exception instanceof CalculatorEvalException ? (CalculatorEvalException)exception : null; - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java deleted file mode 100644 index 1e299d59..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorImpl.java +++ /dev/null @@ -1,209 +0,0 @@ -package org.solovyev.android.calculator; - -import jscl.AbstractJsclArithmeticException; -import jscl.NumeralBaseException; -import jscl.math.Generic; -import jscl.text.ParseInterruptedException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.calculator.text.TextProcessor; -import org.solovyev.common.msg.MessageRegistry; -import org.solovyev.common.msg.MessageType; - -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.atomic.AtomicLong; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:42 - */ -public class CalculatorImpl implements Calculator { - - private static final long FIRST_ID = 0; - - @NotNull - private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); - - @NotNull - private final AtomicLong counter = new AtomicLong(FIRST_ID); - - @NotNull - private final Object lock = new Object(); - - @NotNull - private final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); - - @NotNull - private final Executor threadPoolExecutor = Executors.newFixedThreadPool(10); - - public CalculatorImpl() { - } - - @NotNull - private CalculatorEventDataId nextCalculatorEventDataId() { - long eventId = counter.incrementAndGet(); - return CalculatorEventDataIdImpl.newInstance(eventId, eventId); - } - - @NotNull - private CalculatorEventDataId nextEventDataId(@NotNull Long calculationId) { - long eventId = counter.incrementAndGet(); - return CalculatorEventDataIdImpl.newInstance(eventId, calculationId); - } - - /* - ********************************************************************** - * - * CALCULATION - * - ********************************************************************** - */ - - @NotNull - @Override - public CalculatorEventDataId createFirstEventDataId() { - return CalculatorEventDataIdImpl.newInstance(FIRST_ID, FIRST_ID); - } - - @Override - public void evaluate(@NotNull JsclOperation operation, - @NotNull String expression) { - evaluate(operation, expression, null); - } - - @Override - @NotNull - public CalculatorEventDataId evaluate(@NotNull final JsclOperation operation, - @NotNull final String expression, - @Nullable final MessageRegistry mr) { - - final CalculatorEventDataId eventDataId = nextCalculatorEventDataId(); - - threadPoolExecutor.execute(new Runnable() { - @Override - public void run() { - CalculatorImpl.this.evaluate(eventDataId.getCalculationId(), operation, expression, mr); - } - }); - - return eventDataId; - } - - private void evaluate(@NotNull Long calculationId, - @NotNull JsclOperation operation, - @NotNull String expression, - @Nullable MessageRegistry mr) { - synchronized (lock) { - - PreparedExpression preparedExpression = null; - - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation)); - - try { - preparedExpression = preprocessor.process(expression); - - final String jsclExpression = preparedExpression.toString(); - - try { - - final Generic result = operation.evaluateGeneric(jsclExpression); - - // NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!) - result.toString(); - - final CalculatorOutputImpl data = new CalculatorOutputImpl(operation.getFromProcessor().process(result), operation, result); - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_result, data); - - } catch (AbstractJsclArithmeticException e) { - handleException(calculationId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression)); - } - - } catch (ArithmeticException e) { - handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage()))); - } catch (StackOverflowError e) { - handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error))); - } catch (jscl.text.ParseException e) { - handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(e)); - } catch (ParseInterruptedException e) { - - // do nothing - we ourselves interrupt the calculations - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_cancelled, null); - - } catch (CalculatorParseException e) { - handleException(calculationId, operation, expression, mr, preparedExpression, e); - } finally { - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_finished, null); - } - } - } - - @NotNull - private CalculatorEventData newCalculationEventData(@NotNull JsclOperation operation, - @NotNull String expression, - @NotNull Long calculationId) { - return new CalculatorEvaluationEventDataImpl(CalculatorEventDataImpl.newInstance(nextEventDataId(calculationId)), operation, expression); - } - - private void handleException(@NotNull Long calculationId, - @NotNull JsclOperation operation, - @NotNull String expression, - @Nullable MessageRegistry mr, - @Nullable PreparedExpression preparedExpression, - @NotNull CalculatorParseException parseException) { - - if (operation == JsclOperation.numeric - && preparedExpression != null - && preparedExpression.isExistsUndefinedVar()) { - - evaluate(calculationId, JsclOperation.simplify, expression, mr); - - } - - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException)); - } - - private void handleException(@NotNull Long calculationId, - @NotNull JsclOperation operation, - @NotNull String expression, - @Nullable MessageRegistry mr, - @NotNull CalculatorEvalException evalException) { - - if (operation == JsclOperation.numeric && evalException.getCause() instanceof NumeralBaseException) { - evaluate(calculationId, JsclOperation.simplify, expression, mr); - } - - fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(evalException)); - } - - /* - ********************************************************************** - * - * EVENTS - * - ********************************************************************** - */ - - @Override - public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { - calculatorEventContainer.addCalculatorEventListener(calculatorEventListener); - } - - @Override - public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { - calculatorEventContainer.removeCalculatorEventListener(calculatorEventListener); - } - - @Override - public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { - calculatorEventContainer.fireCalculatorEvent(calculatorEventData, calculatorEventType, data); - } - - @Override - public void fireCalculatorEvents(@NotNull List calculatorEvents) { - calculatorEventContainer.fireCalculatorEvents(calculatorEvents); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorInput.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorInput.java deleted file mode 100644 index 1f0c98ab..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorInput.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 9/20/12 - * Time: 7:25 PM - */ -public interface CalculatorInput { - - @NotNull - String getExpression(); - - @NotNull - JsclOperation getOperation(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorInputImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorInputImpl.java deleted file mode 100644 index 2ad4608c..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorInputImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 9/20/12 - * Time: 7:26 PM - */ -public class CalculatorInputImpl implements CalculatorInput { - - @NotNull - private String expression; - - @NotNull - private JsclOperation operation; - - public CalculatorInputImpl(@NotNull String expression, @NotNull JsclOperation operation) { - this.expression = expression; - this.operation = operation; - } - - @Override - @NotNull - public String getExpression() { - return expression; - } - - @Override - @NotNull - public JsclOperation getOperation() { - return operation; - } -} 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 deleted file mode 100644 index 3b04e8be..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocator.java +++ /dev/null @@ -1,22 +0,0 @@ -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(); - - @NotNull - Calculator getCalculator(); - - @NotNull - CalculatorDisplay getCalculatorDisplay(); - - 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 deleted file mode 100644 index 989e1445..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorLocatorImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -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 CalculatorDisplay calculatorDisplay = new CalculatorDisplayImpl(); - - @NotNull - private Calculator calculator = new CalculatorImpl(); - - @NotNull - private static final CalculatorLocator instance = new CalculatorLocatorImpl(); - - private CalculatorLocatorImpl() { - } - - @NotNull - public static CalculatorLocator getInstance() { - return instance; - } - - @NotNull - @Override - public JCalculatorEngine getCalculatorEngine() { - return calculatorEngine; - } - - @NotNull - @Override - public Calculator getCalculator() { - return this.calculator; - } - - @Override - public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) { - this.calculatorEngine = calculatorEngine; - } - - @Override - @NotNull - public CalculatorDisplay getCalculatorDisplay() { - return calculatorDisplay; - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMessage.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMessage.java deleted file mode 100644 index ab7e1763..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMessage.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.common.msg.AbstractMessage; -import org.solovyev.common.msg.MessageType; - -import java.util.List; -import java.util.Locale; -import java.util.ResourceBundle; - -/** - * User: serso - * Date: 9/20/12 - * Time: 8:06 PM - */ -public class CalculatorMessage extends AbstractMessage { - - protected CalculatorMessage(@NotNull String messageCode, @NotNull MessageType messageType, @org.jetbrains.annotations.Nullable Object... parameters) { - super(messageCode, messageType, parameters); - } - - protected CalculatorMessage(@NotNull String messageCode, @NotNull MessageType messageType, @NotNull List parameters) { - super(messageCode, messageType, parameters); - } - - @Override - protected String getMessagePattern(@NotNull Locale locale) { - final ResourceBundle rb = CalculatorMessages.getBundle(locale); - return rb.getString(getMessageCode()); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java deleted file mode 100644 index aa21657b..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorMessages.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.solovyev.android.calculator; - -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; - -/** - * User: serso - * Date: 9/20/12 - * Time: 8:10 PM - */ -public final class CalculatorMessages { - - @NotNull - private static final Map bundlesByLocale = new HashMap(); - - private CalculatorMessages() { - throw new AssertionError(); - } - - @NotNull - public static ResourceBundle getBundle() { - return getBundle(Locale.getDefault()); - } - - @NotNull - public static ResourceBundle getBundle(@NotNull Locale locale) { - synchronized (bundlesByLocale) { - ResourceBundle result = bundlesByLocale.get(locale); - if (result == null) { - result = ResourceBundle.getBundle("org/solovyev/android/calculator/messages", locale); - bundlesByLocale.put(locale, result); - } - - return result; - } - } - - /* Arithmetic error occurred: {0} */ - @NotNull - public static final String msg_001 = "msg_1"; - - /* Too complex expression*/ - @NotNull - public static final String msg_002 = "msg_2"; - - /* Too long execution time - check the expression*/ - @NotNull - public static final String msg_003 = "msg_3"; - - /* Evaluation was cancelled*/ - @NotNull - public static final String msg_004 = "msg_4"; - - /* No parameters are specified for function: {0}*/ - @NotNull - public static final String msg_005 = "msg_5"; - - /* Infinite loop is detected in expression*/ - @NotNull - public static final String msg_006 = "msg_6"; - - /* Error */ - @NotNull - public static final String syntax_error = "syntax_error"; -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorOutput.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorOutput.java deleted file mode 100644 index bac56104..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorOutput.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.solovyev.android.calculator; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** - * User: serso - * Date: 9/20/12 - * Time: 7:29 PM - */ -public interface CalculatorOutput { - - @NotNull - String getStringResult(); - - @NotNull - JsclOperation getOperation(); - - @NotNull - Generic getResult(); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorOutputImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorOutputImpl.java deleted file mode 100644 index 0ca7e1fe..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorOutputImpl.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.solovyev.android.calculator; - -import jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.jscl.JsclOperation; - -/** -* User: serso -* Date: 9/20/12 -* Time: 7:28 PM -*/ -public class CalculatorOutputImpl implements CalculatorOutput { - - @NotNull - private Generic result; - - @NotNull - private String stringResult; - - @NotNull - private JsclOperation operation; - - public CalculatorOutputImpl(@NotNull String stringResult, @NotNull JsclOperation operation, @NotNull Generic result) { - this.stringResult = stringResult; - this.operation = operation; - this.result = result; - } - - @Override - @NotNull - public String getStringResult() { - return stringResult; - } - - @Override - @NotNull - public JsclOperation getOperation() { - return operation; - } - - @Override - @NotNull - public Generic getResult() { - return result; - } -} 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 deleted file mode 100644 index c069e378..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/JCalculatorEngine.java +++ /dev/null @@ -1,34 +0,0 @@ -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-core/src/main/java/org/solovyev/android/calculator/ListCalculatorEventContainer.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ListCalculatorEventContainer.java deleted file mode 100644 index 09f18ce8..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/ListCalculatorEventContainer.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.solovyev.android.calculator; - -import android.util.Log; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.common.utils.ListListenersContainer; - -import java.util.Arrays; -import java.util.List; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:42 - */ -public class ListCalculatorEventContainer implements CalculatorEventContainer { - - @NotNull - private static final String TAG = "CalculatorEventData"; - - @NotNull - private final ListListenersContainer listeners = new ListListenersContainer(); - - @Override - public void addCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { - listeners.addListener(calculatorEventListener); - } - - @Override - public void removeCalculatorEventListener(@NotNull CalculatorEventListener calculatorEventListener) { - listeners.removeListener(calculatorEventListener); - } - - @Override - public void fireCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) { - fireCalculatorEvents(Arrays.asList(new CalculatorEvent(calculatorEventData, calculatorEventType, data))); - } - - @Override - public void fireCalculatorEvents(@NotNull List calculatorEvents) { - final List listeners = this.listeners.getListeners(); - - for (CalculatorEvent e : calculatorEvents) { - Log.d(TAG, "Event: " + e.getCalculatorEventType() + " with data: " + e.getData()); - for (CalculatorEventListener listener : listeners) { - listener.onCalculatorEvent(e.getCalculatorEventData(), e.getCalculatorEventType(), e.getData()); - } - } - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java deleted file mode 100644 index c7f8f828..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.solovyev.android.calculator.history; - -import org.jetbrains.annotations.NotNull; -import org.solovyev.common.history.HistoryHelper; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:11 - */ -public interface CalculatorHistory extends HistoryHelper { - - void fromXml(@NotNull String xml); - - String toXml(); - - void clearSavedHistory(); - - void removeSavedHistory(@NotNull CalculatorHistoryState historyState); -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java b/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java deleted file mode 100644 index fc881c5c..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryImpl.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.solovyev.android.calculator.history; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.common.history.HistoryAction; -import org.solovyev.common.history.HistoryHelper; -import org.solovyev.common.history.SimpleHistoryHelper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:12 - */ -public class CalculatorHistoryImpl implements CalculatorHistory { - - private final AtomicInteger counter = new AtomicInteger(0); - - @NotNull - private final HistoryHelper history = new SimpleHistoryHelper(); - - @NotNull - private final List savedHistory = new ArrayList(); - - @Override - public boolean isEmpty() { - return this.history.isEmpty(); - } - - @Override - public CalculatorHistoryState getLastHistoryState() { - return this.history.getLastHistoryState(); - } - - @Override - public boolean isUndoAvailable() { - return history.isUndoAvailable(); - } - - @Override - public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) { - return history.undo(currentState); - } - - @Override - public boolean isRedoAvailable() { - return history.isRedoAvailable(); - } - - @Override - public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) { - return history.redo(currentState); - } - - @Override - public boolean isActionAvailable(@NotNull HistoryAction historyAction) { - return history.isActionAvailable(historyAction); - } - - @Override - public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) { - return history.doAction(historyAction, currentState); - } - - @Override - public void addState(@Nullable CalculatorHistoryState currentState) { - history.addState(currentState); - } - - @NotNull - @Override - public List getStates() { - return history.getStates(); - } - - @Override - public void clear() { - this.history.clear(); - } - - @NotNull - public List getSavedHistory() { - return Collections.unmodifiableList(savedHistory); - } - - @NotNull - public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) { - if (historyState.isSaved()) { - return historyState; - } else { - final CalculatorHistoryState savedState = historyState.clone(); - - savedState.setId(counter.incrementAndGet()); - savedState.setSaved(true); - - savedHistory.add(savedState); - - return savedState; - } - } - - @Override - public void fromXml(@NotNull String xml) { - clearSavedHistory(); - - HistoryUtils.fromXml(xml, this.savedHistory); - for (CalculatorHistoryState historyState : savedHistory) { - historyState.setSaved(true); - historyState.setId(counter.incrementAndGet()); - } - } - - @Override - public String toXml() { - return HistoryUtils.toXml(this.savedHistory); - } - - @Override - public void clearSavedHistory() { - this.savedHistory.clear(); - } - - @Override - public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) { - this.savedHistory.remove(historyState); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/common/utils/ListListenersContainer.java b/calculatorpp-core/src/main/java/org/solovyev/common/utils/ListListenersContainer.java deleted file mode 100644 index fa286f42..00000000 --- a/calculatorpp-core/src/main/java/org/solovyev/common/utils/ListListenersContainer.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.solovyev.common.utils; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:43 - */ -// todo serso: move to common -public class ListListenersContainer { - - @NotNull - private final List> listeners = new ArrayList>(); - - public void addListener(@NotNull final T listener) { - synchronized (listeners) { - boolean contains = Iterables.any(listeners, new WeakReferencePredicate(listener)); - - if (!contains) { - listeners.add(new WeakReference(listener)); - } - } - } - - public void removeListener(@NotNull T listener) { - synchronized (listeners) { - Iterables.removeIf(listeners, new WeakReferencePredicate(listener)); - } - } - - @NotNull - public List getListeners() { - final List localListeners; - - synchronized (listeners) { - localListeners = new ArrayList(listeners.size()); - - // copy listeners and remove garbage collected references - for ( Iterator> it = listeners.iterator(); it.hasNext(); ) { - final WeakReference r = it.next(); - final T t = r.get(); - if ( t == null ) { - it.remove(); - } else { - localListeners.add(t); - } - } - } - - return localListeners; - } - - private static class WeakReferencePredicate implements Predicate> { - - @NotNull - private final T t; - - public WeakReferencePredicate(T t) { - this.t = t; - } - - @Override - public boolean apply(@Nullable WeakReference r) { - final T t = r != null ? r.get() : null; - return this.t.equals(t); - } - } -} diff --git a/calculatorpp-core/src/main/resources/org/solovyev/android/calculator/messages.properties b/calculatorpp-core/src/main/resources/org/solovyev/android/calculator/messages.properties deleted file mode 100644 index e6534912..00000000 --- a/calculatorpp-core/src/main/resources/org/solovyev/android/calculator/messages.properties +++ /dev/null @@ -1,8 +0,0 @@ -msg_1=Arithmetic error occurred: {0} -msg_2=Too complex expression -msg_3=Too long execution time - check the expression -msg_4=Evaluation was cancelled -msg_5=No parameters are specified for function: {0} -msg_6=Infinite loop is detected in expression - -syntax_error=Error \ No newline at end of file diff --git a/calculatorpp-service/pom.xml b/calculatorpp-service/pom.xml index 220ae027..7696378b 100644 --- a/calculatorpp-service/pom.xml +++ b/calculatorpp-service/pom.xml @@ -22,6 +22,7 @@ com.intellij annotations + 7.0.3 diff --git a/calculatorpp/pom.xml b/calculatorpp/pom.xml index 82523499..f94bc176 100644 --- a/calculatorpp/pom.xml +++ b/calculatorpp/pom.xml @@ -19,13 +19,6 @@ - - - org.solovyev.android - calculatorpp-core - 1.3.1 - - org.solovyev common-core @@ -82,6 +75,13 @@ org.solovyev jscl + 0.0.2 + + + xercesImpl + xerces + + @@ -92,6 +92,13 @@ provided + + junit + junit + 4.8.2 + test + + net.sf.opencsv opencsv @@ -102,6 +109,17 @@ org.simpleframework simple-xml + 2.6.1 + + + stax-api + stax + + + xpp3 + xpp3 + + @@ -129,15 +147,10 @@ 11.0.2 - - junit - junit - test - - com.intellij annotations + 7.0.3 diff --git a/calculatorpp/res/layout/calc_display.xml b/calculatorpp/res/layout/calc_display.xml index c44067dd..e8c7288e 100644 --- a/calculatorpp/res/layout/calc_display.xml +++ b/calculatorpp/res/layout/calc_display.xml @@ -1,16 +1,16 @@ - - - - - + + + + \ No newline at end of file diff --git a/calculatorpp-core/src/main/java/org/solovyev/math/units/Unit.java b/calculatorpp/src/main/java/org/solovyev/android/Unit.java similarity index 80% rename from calculatorpp-core/src/main/java/org/solovyev/math/units/Unit.java rename to calculatorpp/src/main/java/org/solovyev/android/Unit.java index 23921ea8..d909f67c 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/math/units/Unit.java +++ b/calculatorpp/src/main/java/org/solovyev/android/Unit.java @@ -1,4 +1,4 @@ -package org.solovyev.math.units; +package org.solovyev.android; import org.jetbrains.annotations.NotNull; diff --git a/calculatorpp-core/src/main/java/org/solovyev/math/units/UnitConverter.java b/calculatorpp/src/main/java/org/solovyev/android/UnitConverter.java similarity index 92% rename from calculatorpp-core/src/main/java/org/solovyev/math/units/UnitConverter.java rename to calculatorpp/src/main/java/org/solovyev/android/UnitConverter.java index 2d56bebd..56782cb3 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/math/units/UnitConverter.java +++ b/calculatorpp/src/main/java/org/solovyev/android/UnitConverter.java @@ -1,4 +1,4 @@ -package org.solovyev.math.units; +package org.solovyev.android; import org.jetbrains.annotations.NotNull; diff --git a/calculatorpp-core/src/main/java/org/solovyev/math/units/UnitImpl.java b/calculatorpp/src/main/java/org/solovyev/android/UnitImpl.java similarity index 90% rename from calculatorpp-core/src/main/java/org/solovyev/math/units/UnitImpl.java rename to calculatorpp/src/main/java/org/solovyev/android/UnitImpl.java index 647e0c6f..a34ec36f 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/math/units/UnitImpl.java +++ b/calculatorpp/src/main/java/org/solovyev/android/UnitImpl.java @@ -1,4 +1,4 @@ -package org.solovyev.math.units; +package org.solovyev.android; import org.jetbrains.annotations.NotNull; diff --git a/calculatorpp-core/src/main/java/org/solovyev/math/units/UnitType.java b/calculatorpp/src/main/java/org/solovyev/android/UnitType.java similarity index 81% rename from calculatorpp-core/src/main/java/org/solovyev/math/units/UnitType.java rename to calculatorpp/src/main/java/org/solovyev/android/UnitType.java index 457442c2..2a84f6a5 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/math/units/UnitType.java +++ b/calculatorpp/src/main/java/org/solovyev/android/UnitType.java @@ -1,4 +1,4 @@ -package org.solovyev.math.units; +package org.solovyev.android; import org.jetbrains.annotations.NotNull; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java index 4abf638d..90f0798d 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidNumeralBase.java @@ -3,10 +3,10 @@ package org.solovyev.android.calculator; import android.app.Activity; import jscl.NumeralBase; import org.jetbrains.annotations.NotNull; -import org.solovyev.math.units.Unit; -import org.solovyev.math.units.UnitConverter; -import org.solovyev.math.units.UnitImpl; -import org.solovyev.math.units.UnitType; +import org.solovyev.android.Unit; +import org.solovyev.android.UnitConverter; +import org.solovyev.android.UnitImpl; +import org.solovyev.android.UnitType; import org.solovyev.android.view.drag.DirectionDragButton; import org.solovyev.android.view.drag.DragDirection; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index d7a3c0c3..608a3aa4 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -32,7 +32,7 @@ import org.solovyev.android.AndroidUtils; import org.solovyev.android.FontSizeAdjuster; import org.solovyev.android.LocalBinder; import org.solovyev.android.calculator.about.CalculatorReleaseNotesActivity; -import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl; +import org.solovyev.android.calculator.history.CalculatorHistory; import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.view.AngleUnitsButton; @@ -136,7 +136,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh vibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE); - AndroidCalculatorHistoryImpl.instance.load(this, preferences); + CalculatorHistory.instance.load(this, preferences); calculatorModel = CalculatorModel.instance.init(this, preferences, CalculatorEngine.instance); dpclRegister.clear(); 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 73a5cca1..c9d1de5a 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorApplication.java @@ -46,8 +46,6 @@ public class CalculatorApplication extends android.app.Application { public void onCreate() { super.onCreate(); - CalculatorLocatorImpl.getInstance().setCalculatorEngine(CalculatorEngine.instance); - AdsController.getInstance().init(ADMOB_USER_ID, AD_FREE_PRODUCT_ID, new BillingController.IConfiguration() { @Override diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java similarity index 52% rename from calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java index 59b68e21..13c8c9d9 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorDisplayView.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java @@ -15,9 +15,12 @@ import jscl.math.Generic; import jscl.math.function.Constant; import jscl.math.function.IConstant; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.android.calculator.model.TextProcessor; +import org.solovyev.android.calculator.model.ToJsclTextProcessor; import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; import org.solovyev.android.calculator.view.TextHighlighter; import org.solovyev.android.calculator.view.UnitConverterViewBuilder; @@ -35,9 +38,9 @@ import java.util.Set; * Date: 9/17/11 * Time: 10:58 PM */ -public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView { +public class CalculatorDisplay extends AutoResizeTextView implements ICalculatorDisplay{ - private static enum ConversionMenuItem implements AMenuItem { + private static enum ConversionMenuItem implements AMenuItem { convert_to_bin(NumeralBase.bin), convert_to_dec(NumeralBase.dec), convert_to_hex(NumeralBase.hex); @@ -70,27 +73,23 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements } @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase(); - final Generic lastResult = CalculatorLocatorImpl.getInstance().getCalculatorDisplay().getViewState().getResult(); + String to; + try { + to = convert(data.getGenericResult()); - if (lastResult != null) { - String to; - try { - to = convert(lastResult); - - // add prefix - if (fromNumeralBase != toNumeralBase) { - to = toNumeralBase.getJsclPrefix() + to; - } - } catch (UnitConverterViewBuilder.ConversionException e) { - to = context.getString(R.string.c_error); + // add prefix + if (fromNumeralBase != toNumeralBase) { + to = toNumeralBase.getJsclPrefix() + to; } - - data.setText(to); - //data.redraw(); + } catch (UnitConverterViewBuilder.ConversionException e) { + to = context.getString(R.string.c_error); } + + data.setText(to); + data.redraw(); } @NotNull @@ -114,18 +113,18 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements } } - public static enum MenuItem implements LabeledMenuItem { + public static enum MenuItem implements LabeledMenuItem { copy(R.string.c_copy) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { CalculatorModel.copyResult(context, data); } }, convert_to_bin(R.string.convert_to_bin) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { ConversionMenuItem.convert_to_bin.onClick(data, context); } @@ -137,7 +136,7 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements convert_to_dec(R.string.convert_to_dec) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { ConversionMenuItem.convert_to_dec.onClick(data, context); } @@ -149,7 +148,7 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements convert_to_hex(R.string.convert_to_hex) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { ConversionMenuItem.convert_to_hex.onClick(data, context); } @@ -161,11 +160,8 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements convert(R.string.c_convert) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { - final Generic result = data.getState().getResult(); - if (result != null) { - new NumeralBaseConverterDialog(result.toString()).show(context); - } + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { + new NumeralBaseConverterDialog(data.getGenericResult().toString()).show(context); } @Override @@ -174,10 +170,10 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements } }, - plot(R.string.c_plot) { + plot(R.string.c_plot) { @Override - public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) { - final Generic generic = data.getState().getResult(); + public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { + final Generic generic = data.getGenericResult(); assert generic != null; final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic)); @@ -185,18 +181,18 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorActivityLauncher.plotGraph(context, generic, constant); } - @Override - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - boolean result = false; + @Override + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + boolean result = false; - if (operation == JsclOperation.simplify) { + if (operation == JsclOperation.simplify) { if (getNotSystemConstants(generic).size() == 1) { - result = true; - } - } + result = true; + } + } - return result; - } + return result; + } @NotNull private Set getNotSystemConstants(@NotNull Generic generic) { @@ -213,104 +209,140 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements } }; - private final int captionId; + private final int captionId; - MenuItem(int captionId) { - this.captionId = captionId; - } + MenuItem(int captionId) { + this.captionId = captionId; + } - public final boolean isItemVisible(@NotNull CalculatorDisplayViewState displayViewState) { - //noinspection ConstantConditions - return displayViewState.isValid() && displayViewState.getResult() != null && isItemVisibleFor(displayViewState.getResult(), displayViewState.getOperation()); - } + public final boolean isItemVisible(@NotNull CalculatorDisplay display) { + //noinspection ConstantConditions + return display.isValid() && display.getGenericResult() != null && isItemVisibleFor(display.getGenericResult(), display.getJsclOperation()); + } - protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { - return true; - } + protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { + return true; + } - @NotNull - @Override - public String getCaption(@NotNull Context context) { - return context.getString(captionId); - } - } + @NotNull + @Override + public String getCaption(@NotNull Context context) { + return context.getString(captionId); + } + } - @NotNull - private CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance(); + private boolean valid = true; - @NotNull - private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine()); + @Nullable + private String errorMessage; - public AndroidCalculatorDisplayView(Context context) { - super(context); - } + @NotNull + private JsclOperation jsclOperation = JsclOperation.numeric; - public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) { - super(context, attrs); - } + @NotNull + private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine()); - public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } + @Nullable + private Generic genericResult; - public boolean isValid() { - return this.state.isValid(); - } + public CalculatorDisplay(Context context) { + super(context); + } + public CalculatorDisplay(Context context, AttributeSet attrs) { + super(context, attrs); + } - @Override - public void setState(@NotNull CalculatorDisplayViewState state) { - this.state = state; - if ( state.isValid() ) { - setTextColor(getResources().getColor(R.color.default_text_color)); - setText(state.getStringResult()); - } else { - setTextColor(getResources().getColor(R.color.display_error_text_color)); - setText(state.getErrorMessage()); - } - } + public CalculatorDisplay(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } - @NotNull - @Override - public CalculatorDisplayViewState getState() { - return this.state; - } + @Override + public boolean isValid() { + return valid; + } - @Override - public void setText(CharSequence text, BufferType type) { - super.setText(text, type); - } + @Override + public void setValid(boolean valid) { + this.valid = valid; + if (valid) { + errorMessage = null; + setTextColor(getResources().getColor(R.color.default_text_color)); + } else { + setTextColor(getResources().getColor(R.color.display_error_text_color)); + } + } - public synchronized void redraw() { - if (isValid()) { - String text = getText().toString(); + @Override + @Nullable + public String getErrorMessage() { + return errorMessage; + } - Log.d(this.getClass().getName(), text); + @Override + public void setErrorMessage(@Nullable String errorMessage) { + this.errorMessage = errorMessage; + } - try { - TextHighlighter.Result result = textHighlighter.process(text); - text = result.toString(); - } catch (CalculatorParseException e) { - Log.e(this.getClass().getName(), e.getMessage(), e); - } + @Override + public void setJsclOperation(@NotNull JsclOperation jsclOperation) { + this.jsclOperation = jsclOperation; + } - Log.d(this.getClass().getName(), text); - super.setText(Html.fromHtml(text), BufferType.EDITABLE); - } + @Override + @NotNull + public JsclOperation getJsclOperation() { + return jsclOperation; + } - // todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize()) - setAddEllipsis(false); - setMinTextSize(10); - resizeText(); - } + @Override + public void setText(CharSequence text, BufferType type) { + super.setText(text, type); - @Override - public int getSelection() { - return this.getSelectionStart(); - } + setValid(true); + } - @Override - public void setSelection(int selection) { - // not supported by TextView - } + public synchronized void redraw() { + if (isValid()) { + String text = getText().toString(); + + Log.d(this.getClass().getName(), text); + + try { + TextHighlighter.Result result = textHighlighter.process(text); + text = result.toString(); + } catch (CalculatorParseException e) { + Log.e(this.getClass().getName(), e.getMessage(), e); + } + + Log.d(this.getClass().getName(), text); + super.setText(Html.fromHtml(text), BufferType.EDITABLE); + } + + // todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize()) + setAddEllipsis(false); + setMinTextSize(10); + resizeText(); + } + + @Override + public void setGenericResult(@Nullable Generic genericResult) { + this.genericResult = genericResult; + } + + @Override + @Nullable + public Generic getGenericResult() { + return genericResult; + } + + @Override + public int getSelection() { + return this.getSelectionStart(); + } + + @Override + public void setSelection(int selection) { + // not supported by TextView + } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java index 3f9b20c9..a2e0f910 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java @@ -16,7 +16,8 @@ import android.view.ContextMenu; import android.widget.EditText; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.android.calculator.model.TextProcessor; import org.solovyev.android.calculator.view.TextHighlighter; import org.solovyev.common.collections.CollectionsUtils; diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java similarity index 100% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorEngineControl.java diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java index d459f15a..387a8ff2 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -20,12 +20,14 @@ import android.widget.Toast; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.CursorControl; -import org.solovyev.android.calculator.history.AndroidCalculatorHistoryImpl; +import org.solovyev.android.calculator.history.CalculatorHistory; import org.solovyev.android.calculator.history.CalculatorHistoryState; import org.solovyev.android.calculator.history.TextViewEditorAdapter; import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.CalculatorEvalException; +import org.solovyev.android.calculator.model.CalculatorParseException; import org.solovyev.android.history.HistoryControl; import org.solovyev.android.menu.AMenuBuilder; import org.solovyev.android.menu.MenuImpl; @@ -53,7 +55,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl 0) { - display.setText(result.getStringResult()); + display.setText(result.getResult()); } else { display.setText(""); } - display.setJsclOperation(result.getOperation()); - display.setGenericResult(result.getResult()); + display.setJsclOperation(result.getUserOperation()); + display.setGenericResult(result.getGenericResult()); } catch (CalculatorParseException e) { handleEvaluationException(expression, display, operation, e); } catch (CalculatorEvalException e) { @@ -256,7 +257,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl filteredMenuItems = new ArrayList(AndroidCalculatorDisplayView.MenuItem.values().length); - for (AndroidCalculatorDisplayView.MenuItem menuItem : AndroidCalculatorDisplayView.MenuItem.values()) { - if (menuItem.isItemVisible(displayViewState)) { + if (cd.isValid()) { + final List filteredMenuItems = new ArrayList(CalculatorDisplay.MenuItem.values().length); + for (CalculatorDisplay.MenuItem menuItem : CalculatorDisplay.MenuItem.values()) { + if (menuItem.isItemVisible(cd)) { filteredMenuItems.add(menuItem); } } @@ -401,7 +400,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl() { + if ( CollectionsUtils.contains(historyState, CalculatorHistory.instance.getSavedHistory(), new Equalizer() { @Override public boolean equals(@Nullable CalculatorHistoryState first, @Nullable CalculatorHistoryState second) { return first != null && second != null && diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryState.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryState.java similarity index 91% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryState.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryState.java index 633d8a7f..fffc09b4 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryState.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AbstractHistoryState.java @@ -6,6 +6,7 @@ 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.Transient; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java deleted file mode 100644 index 2f4dc4b4..00000000 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistory.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.solovyev.android.calculator.history; - -import android.content.Context; -import android.content.SharedPreferences; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * User: Solovyev_S - * Date: 20.09.12 - * Time: 16:07 - */ -public interface AndroidCalculatorHistory extends CalculatorHistory { - - void load(@Nullable Context context, @Nullable SharedPreferences preferences); - - void save(@NotNull Context context); -} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java deleted file mode 100644 index b5cba95f..00000000 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/AndroidCalculatorHistoryImpl.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - * or visit http://se.solovyev.org - */ - -package org.solovyev.android.calculator.history; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.R; -import org.solovyev.common.history.HistoryAction; - -import java.util.List; - -/** - * User: serso - * Date: 10/9/11 - * Time: 6:35 PM - */ -public enum AndroidCalculatorHistoryImpl implements AndroidCalculatorHistory { - - instance; - - @NotNull - private final CalculatorHistoryImpl calculatorHistory = new CalculatorHistoryImpl(); - - @Override - public void load(@Nullable Context context, @Nullable SharedPreferences preferences) { - if (context != null && preferences != null) { - final String value = preferences.getString(context.getString(R.string.p_calc_history), null); - calculatorHistory.fromXml(value); - } - } - - @Override - public void save(@NotNull Context context) { - final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); - final SharedPreferences.Editor editor = settings.edit(); - - editor.putString(context.getString(R.string.p_calc_history), calculatorHistory.toXml()); - - editor.commit(); - } - - public void clearSavedHistory(@NotNull Context context) { - calculatorHistory.clearSavedHistory(); - save(context); - } - - public void removeSavedHistory(@NotNull CalculatorHistoryState historyState, @NotNull Context context) { - historyState.setSaved(false); - calculatorHistory.removeSavedHistory(historyState); - save(context); - } - - @Override - public boolean isEmpty() { - return calculatorHistory.isEmpty(); - } - - @Override - public CalculatorHistoryState getLastHistoryState() { - return calculatorHistory.getLastHistoryState(); - } - - @Override - public boolean isUndoAvailable() { - return calculatorHistory.isUndoAvailable(); - } - - @Override - public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) { - return calculatorHistory.undo(currentState); - } - - @Override - public boolean isRedoAvailable() { - return calculatorHistory.isRedoAvailable(); - } - - @Override - public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) { - return calculatorHistory.redo(currentState); - } - - @Override - public boolean isActionAvailable(@NotNull HistoryAction historyAction) { - return calculatorHistory.isActionAvailable(historyAction); - } - - @Override - public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) { - return calculatorHistory.doAction(historyAction, currentState); - } - - @Override - public void addState(@Nullable CalculatorHistoryState currentState) { - calculatorHistory.addState(currentState); - } - - @NotNull - @Override - public List getStates() { - return calculatorHistory.getStates(); - } - - @Override - public void clear() { - calculatorHistory.clear(); - } - - @NotNull - public List getSavedHistory() { - return calculatorHistory.getSavedHistory(); - } - - @NotNull - public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) { - return calculatorHistory.addSavedState(historyState); - } - - @Override - public void fromXml(@NotNull String xml) { - calculatorHistory.fromXml(xml); - } - - @Override - public String toXml() { - return calculatorHistory.toXml(); - } - - @Override - public void clearSavedHistory() { - calculatorHistory.clearSavedHistory(); - } - - @Override - public void removeSavedHistory(@NotNull CalculatorHistoryState historyState) { - calculatorHistory.removeSavedHistory(historyState); - } -} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java similarity index 68% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java index c8c37c41..b637e901 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorDisplayHistoryState.java @@ -1,144 +1,138 @@ -/* - * 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 jscl.math.Generic; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.simpleframework.xml.Element; -import org.simpleframework.xml.Root; -import org.simpleframework.xml.Transient; -import org.solovyev.android.calculator.CalculatorDisplay; -import org.solovyev.android.calculator.CalculatorDisplayViewState; -import org.solovyev.android.calculator.CalculatorDisplayViewStateImpl; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.text.StringUtils; - -/** - * User: serso - * Date: 9/17/11 - * Time: 11:05 PM - */ - -@Root -public class CalculatorDisplayHistoryState implements Cloneable { - - @Transient - private boolean valid = true; - - @Transient - @Nullable - private String errorMessage = null; - - @Element - @NotNull - private EditorHistoryState editorState; - - @Element - @NotNull - private JsclOperation jsclOperation; - - @Transient - @Nullable - private Generic genericResult; - - private CalculatorDisplayHistoryState() { - // for xml - } - - @NotNull - public static CalculatorDisplayHistoryState newInstance(@NotNull CalculatorDisplay display) { - final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState(); - - result.editorState = EditorHistoryState.newInstance(display.getViewState()); - - final CalculatorDisplayViewState displayViewState = display.getViewState(); - - result.valid = displayViewState.isValid(); - result.jsclOperation = displayViewState.getOperation(); - result.genericResult = displayViewState.getResult(); - result.errorMessage = displayViewState.getErrorMessage(); - - return result; - } - - public void setValuesFromHistory(@NotNull CalculatorDisplay display) { - if ( this.isValid() ) { - display.setViewState(CalculatorDisplayViewStateImpl.newValidState(this.getJsclOperation(), this.getGenericResult(), StringUtils.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition())); - } else { - display.setViewState(CalculatorDisplayViewStateImpl.newErrorState(this.getJsclOperation(), StringUtils.getNotEmpty(this.getErrorMessage(), ""))); - } - } - - - public boolean isValid() { - return valid; - } - - @NotNull - public EditorHistoryState getEditorState() { - return editorState; - } - - @NotNull - public JsclOperation getJsclOperation() { - return jsclOperation; - } - - @Nullable - public String getErrorMessage() { - return errorMessage; - } - - @Nullable - public Generic getGenericResult() { - return genericResult; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o; - - if (!editorState.equals(that.editorState)) return false; - if (jsclOperation != that.jsclOperation) return false; - - return true; - } - - @Override - public int hashCode() { - int result = editorState.hashCode(); - result = 31 * result + jsclOperation.hashCode(); - return result; - } - - @Override - public String toString() { - return "CalculatorDisplayHistoryState{" + - "valid=" + valid + - ", errorMessage='" + errorMessage + '\'' + - ", editorHistoryState=" + editorState + - ", jsclOperation=" + jsclOperation + - '}'; - } - - @Override - protected CalculatorDisplayHistoryState clone() { - try { - final CalculatorDisplayHistoryState clone = (CalculatorDisplayHistoryState) super.clone(); - - clone.editorState = this.editorState.clone(); - - return clone; - } catch (CloneNotSupportedException e) { - throw new RuntimeException(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 jscl.math.Generic; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.simpleframework.xml.Element; +import org.simpleframework.xml.Root; +import org.simpleframework.xml.Transient; +import org.solovyev.android.calculator.ICalculatorDisplay; +import org.solovyev.android.calculator.jscl.JsclOperation; + +/** + * User: serso + * Date: 9/17/11 + * Time: 11:05 PM + */ + +@Root +public class CalculatorDisplayHistoryState implements Cloneable { + + @Transient + private boolean valid = true; + + @Transient + @Nullable + private String errorMessage = null; + + @Element + @NotNull + private EditorHistoryState editorState; + + @Element + @NotNull + private JsclOperation jsclOperation; + + @Transient + @Nullable + private Generic genericResult; + + private CalculatorDisplayHistoryState() { + // for xml + } + + @NotNull + public static CalculatorDisplayHistoryState newInstance(@NotNull ICalculatorDisplay display) { + final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState(); + + result.editorState = EditorHistoryState.newInstance(display); + result.valid = display.isValid(); + result.jsclOperation = display.getJsclOperation(); + result.genericResult = display.getGenericResult(); + result.errorMessage = display.getErrorMessage(); + + return result; + } + + public void setValuesFromHistory(@NotNull ICalculatorDisplay display) { + this.getEditorState().setValuesFromHistory(display); + display.setValid(this.isValid()); + display.setErrorMessage(this.getErrorMessage()); + display.setJsclOperation(this.getJsclOperation()); + display.setGenericResult(this.getGenericResult()); + } + + + public boolean isValid() { + return valid; + } + + @NotNull + public EditorHistoryState getEditorState() { + return editorState; + } + + @NotNull + public JsclOperation getJsclOperation() { + return jsclOperation; + } + + @Nullable + public String getErrorMessage() { + return errorMessage; + } + + @Nullable + public Generic getGenericResult() { + return genericResult; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o; + + if (!editorState.equals(that.editorState)) return false; + if (jsclOperation != that.jsclOperation) return false; + + return true; + } + + @Override + public int hashCode() { + int result = editorState.hashCode(); + result = 31 * result + jsclOperation.hashCode(); + return result; + } + + @Override + public String toString() { + return "CalculatorDisplayHistoryState{" + + "valid=" + valid + + ", errorMessage='" + errorMessage + '\'' + + ", editorHistoryState=" + editorState + + ", jsclOperation=" + jsclOperation + + '}'; + } + + @Override + protected CalculatorDisplayHistoryState clone() { + try { + final CalculatorDisplayHistoryState clone = (CalculatorDisplayHistoryState) super.clone(); + + clone.editorState = this.editorState.clone(); + + return clone; + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } +} diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java new file mode 100644 index 00000000..c6ec0e08 --- /dev/null +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistory.java @@ -0,0 +1,149 @@ +/* + * 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.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.R; +import org.solovyev.common.history.HistoryAction; +import org.solovyev.common.history.HistoryHelper; +import org.solovyev.common.history.SimpleHistoryHelper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * User: serso + * Date: 10/9/11 + * Time: 6:35 PM + */ +public enum CalculatorHistory implements HistoryHelper { + + instance; + + // todo serso: not synchronized + private int counter = 0; + + @NotNull + private final HistoryHelper history = new SimpleHistoryHelper(); + + @NotNull + private final List savedHistory = new ArrayList (); + + @Override + public boolean isEmpty() { + return this.history.isEmpty(); + } + + @Override + public CalculatorHistoryState getLastHistoryState() { + return this.history.getLastHistoryState(); + } + + @Override + public boolean isUndoAvailable() { + return history.isUndoAvailable(); + } + + @Override + public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) { + return history.undo(currentState); + } + + @Override + public boolean isRedoAvailable() { + return history.isRedoAvailable(); + } + + @Override + public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) { + return history.redo(currentState); + } + + @Override + public boolean isActionAvailable(@NotNull HistoryAction historyAction) { + return history.isActionAvailable(historyAction); + } + + @Override + public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) { + return history.doAction(historyAction, currentState); + } + + @Override + public void addState(@Nullable CalculatorHistoryState currentState) { + history.addState(currentState); + } + + @NotNull + @Override + public List getStates() { + return history.getStates(); + } + + @Override + public void clear() { + this.history.clear(); + } + + public void load(@Nullable Context context, @Nullable SharedPreferences preferences) { + if (context != null && preferences != null) { + final String value = preferences.getString(context.getString(R.string.p_calc_history), null); + this.savedHistory.clear(); + HistoryUtils.fromXml(value, this.savedHistory); + for (CalculatorHistoryState historyState : savedHistory) { + historyState.setSaved(true); + historyState.setId(counter++); + } + } + } + + public void save(@NotNull Context context) { + final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); + final SharedPreferences.Editor editor = settings.edit(); + + editor.putString(context.getString(R.string.p_calc_history), HistoryUtils.toXml(this.savedHistory)); + + editor.commit(); + } + + @NotNull + public List getSavedHistory() { + return Collections.unmodifiableList(savedHistory); + } + + @NotNull + public CalculatorHistoryState addSavedState(@NotNull CalculatorHistoryState historyState) { + if (historyState.isSaved()) { + return historyState; + } else { + final CalculatorHistoryState savedState = historyState.clone(); + + savedState.setId(counter++); + savedState.setSaved(true); + + savedHistory.add(savedState); + + return savedState; + } + } + + public void clearSavedHistory(@NotNull Context context) { + this.savedHistory.clear(); + save(context); + } + + public void removeSavedHistory(@NotNull CalculatorHistoryState historyState, @NotNull Context context) { + historyState.setSaved(false); + this.savedHistory.remove(historyState); + save(context); + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java similarity index 91% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java index f866596a..b226390a 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/CalculatorHistoryState.java @@ -1,111 +1,110 @@ -/* - * 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.CalculatorDisplay; -import org.solovyev.android.calculator.Editor; - -/** - * 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 CalculatorDisplay 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 CalculatorDisplay 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.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-core/src/main/java/org/solovyev/android/calculator/Editor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/Editor.java similarity index 85% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/Editor.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/Editor.java index e2f53a0b..e7758d9d 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/Editor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/Editor.java @@ -4,7 +4,7 @@ * or visit http://se.solovyev.org */ -package org.solovyev.android.calculator; +package org.solovyev.android.calculator.history; import org.jetbrains.annotations.Nullable; diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java similarity index 82% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java index 2ffa241b..77a228fb 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/EditorHistoryState.java @@ -1,99 +1,87 @@ -/* - * 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.CalculatorDisplayViewState; -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; - } - - @NotNull - public static EditorHistoryState newInstance(@NotNull CalculatorDisplayViewState viewState) { - final EditorHistoryState result = new EditorHistoryState(); - - result.text = viewState.getText(); - result.cursorPosition = viewState.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; + +@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-core/src/main/java/org/solovyev/android/calculator/history/History.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/History.java similarity index 100% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/History.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/History.java diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java index 73f67340..4638a53c 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryActivityTab.java @@ -26,12 +26,12 @@ public class HistoryActivityTab extends AbstractHistoryActivity { @NotNull @Override protected List getHistoryItems() { - return new ArrayList(AndroidCalculatorHistoryImpl.instance.getStates()); + return new ArrayList(CalculatorHistory.instance.getStates()); } @Override protected void clearHistory() { - AndroidCalculatorHistoryImpl.instance.clear(); + CalculatorHistory.instance.clear(); getAdapter().clear(); } } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java index 7cb1c859..1febb82f 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryItemMenuItem.java @@ -96,7 +96,7 @@ public enum HistoryItemMenuItem implements LabeledMenuItem final CalculatorHistoryState historyState = data.getHistoryState(); if (historyState.isSaved()) { data.getAdapter().remove(historyState); - AndroidCalculatorHistoryImpl.instance.removeSavedHistory(historyState, context); + CalculatorHistory.instance.removeSavedHistory(historyState, context); Toast.makeText(context, context.getText(R.string.c_history_was_removed), Toast.LENGTH_LONG).show(); data.getAdapter().notifyDataSetChanged(); } @@ -122,14 +122,14 @@ public enum HistoryItemMenuItem implements LabeledMenuItem @Override public void onClick(DialogInterface dialog, int which) { if (save) { - final CalculatorHistoryState savedHistoryItem = AndroidCalculatorHistoryImpl.instance.addSavedState(historyState); + final CalculatorHistoryState savedHistoryItem = CalculatorHistory.instance.addSavedState(historyState); savedHistoryItem.setComment(comment.getText().toString()); - AndroidCalculatorHistoryImpl.instance.save(context); + CalculatorHistory.instance.save(context); // we don't need to add element to the adapter as adapter of another activity must be updated and not this //data.getAdapter().add(savedHistoryItem); } else { historyState.setComment(comment.getText().toString()); - AndroidCalculatorHistoryImpl.instance.save(context); + CalculatorHistory.instance.save(context); } data.getAdapter().notifyDataSetChanged(); Toast.makeText(context, context.getText(R.string.c_history_saved), Toast.LENGTH_LONG).show(); diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java similarity index 100% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/history/HistoryUtils.java diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java index 6113c89d..c5bc1c34 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/history/SavedHistoryActivityTab.java @@ -26,12 +26,12 @@ public class SavedHistoryActivityTab extends AbstractHistoryActivity { @NotNull @Override protected List getHistoryItems() { - return new ArrayList(AndroidCalculatorHistoryImpl.instance.getSavedHistory()); + return new ArrayList(CalculatorHistory.instance.getSavedHistory()); } @Override protected void clearHistory() { - AndroidCalculatorHistoryImpl.instance.clearSavedHistory(this); + CalculatorHistory.instance.clearSavedHistory(this); getAdapter().clear(); } } 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 35207b07..42b513a2 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 @@ -10,7 +10,6 @@ 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 diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java similarity index 80% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java index 2251e5b8..b664c9ff 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessor.java @@ -8,8 +8,8 @@ package org.solovyev.android.calculator.jscl; import jscl.math.Generic; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.android.calculator.model.TextProcessor; /** * User: serso diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java similarity index 55% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java index 978964b7..2ba3d902 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java @@ -9,10 +9,10 @@ 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.text.DummyTextProcessor; -import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; -import org.solovyev.android.calculator.text.TextProcessor; +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 { @@ -42,11 +42,11 @@ public enum JsclOperation { public final String evaluate(@NotNull String expression) throws ParseException { switch (this) { case simplify: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplify(expression); + return CalculatorEngine.instance.getEngine().simplify(expression); case elementary: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementary(expression); + return CalculatorEngine.instance.getEngine().elementary(expression); case numeric: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluate(expression); + return CalculatorEngine.instance.getEngine().evaluate(expression); default: throw new UnsupportedOperationException(); } @@ -56,11 +56,11 @@ public enum JsclOperation { public final Generic evaluateGeneric(@NotNull String expression) throws ParseException { switch (this) { case simplify: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().simplifyGeneric(expression); + return CalculatorEngine.instance.getEngine().simplifyGeneric(expression); case elementary: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().elementaryGeneric(expression); + return CalculatorEngine.instance.getEngine().elementaryGeneric(expression); case numeric: - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getEngine().evaluateGeneric(expression); + return CalculatorEngine.instance.getEngine().evaluateGeneric(expression); default: throw new UnsupportedOperationException(); } diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/MathType.java similarity index 91% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/math/MathType.java index 549ae9fd..8efc1f1d 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/math/MathType.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/math/MathType.java @@ -10,10 +10,10 @@ 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.CalculatorParseException; +import org.solovyev.android.calculator.model.CalculatorEngine; +import org.solovyev.android.calculator.model.CalculatorParseException; import org.solovyev.common.collections.CollectionsUtils; import java.util.*; @@ -26,8 +26,11 @@ public enum MathType { private final List tokens = new ArrayList(10); { for (NumeralBase numeralBase : NumeralBase.values()) { - tokens.add(numeralBase.getJsclPrefix()); - } + final String jsclPrefix = numeralBase.getJsclPrefix(); + if (jsclPrefix != null) { + tokens.add(jsclPrefix); + } + } } @NotNull @@ -57,7 +60,7 @@ public enum MathType { @NotNull @Override public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getPostfixFunctionsRegistry().getNames(); + return CalculatorEngine.instance.getPostfixFunctionsRegistry().getNames(); } }, @@ -101,7 +104,7 @@ public enum MathType { @NotNull @Override public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getFunctionsRegistry().getNames(); + return CalculatorEngine.instance.getFunctionsRegistry().getNames(); } }, @@ -109,7 +112,7 @@ public enum MathType { @NotNull @Override public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getOperatorsRegistry().getNames(); + return CalculatorEngine.instance.getOperatorsRegistry().getNames(); } }, @@ -117,7 +120,7 @@ public enum MathType { @NotNull @Override public List getTokens() { - return CalculatorLocatorImpl.getInstance().getCalculatorEngine().getVarsRegistry().getNames(); + return CalculatorEngine.instance.getVarsRegistry().getNames(); } @Override diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/AbstractNumberBuilder.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractNumberBuilder.java similarity index 95% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/AbstractNumberBuilder.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractNumberBuilder.java index a95e6703..a66cd44f 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/AbstractNumberBuilder.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/AbstractNumberBuilder.java @@ -4,7 +4,7 @@ * or visit http://se.solovyev.org */ -package org.solovyev.android.calculator; +package org.solovyev.android.calculator.model; import jscl.MathEngine; import jscl.NumeralBase; 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 4dfa07f0..68bcc9b8 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 @@ -1,404 +1,425 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.model; - -import android.content.Context; -import android.content.SharedPreferences; -import jscl.*; -import jscl.math.Generic; -import jscl.math.function.Function; -import jscl.math.function.IConstant; -import jscl.math.operator.Operator; -import jscl.text.ParseInterruptedException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.*; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.android.calculator.text.TextProcessor; -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; - -import java.text.DecimalFormatSymbols; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * User: serso - * Date: 9/12/11 - * Time: 11:38 PM - */ - -public enum CalculatorEngine implements JCalculatorEngine { - - instance; - - private static final String GROUPING_SEPARATOR_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator"; - - private static final String MULTIPLICATION_SIGN_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_multiplication_sign"; - private static final String MULTIPLICATION_SIGN_DEFAULT = "×"; - - private static final String MAX_CALCULATION_TIME_P_KEY = "calculation.max_calculation_time"; - private static final String MAX_CALCULATION_TIME_DEFAULT = "5"; - - private static final String SCIENCE_NOTATION_P_KEY = "calculation.output.science_notation"; - private static final boolean SCIENCE_NOTATION_DEFAULT = false; - - private static final String ROUND_RESULT_P_KEY = "org.solovyev.android.calculator.CalculatorModel_round_result"; - private static final boolean ROUND_RESULT_DEFAULT = true; - - private static final String RESULT_PRECISION_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision"; - private static final String RESULT_PRECISION_DEFAULT = "5"; - - private static final String NUMERAL_BASES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_numeral_bases"; - private static final String NUMERAL_BASES_DEFAULT = "dec"; - - private static final String ANGLE_UNITS_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_angle_units"; - private static final String ANGLE_UNITS_DEFAULT = "deg"; - - public static class Preferences { - public static final Preference groupingSeparator = StringPreference.newInstance(GROUPING_SEPARATOR_P_KEY, JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); - public static final Preference multiplicationSign = StringPreference.newInstance(MULTIPLICATION_SIGN_P_KEY, MULTIPLICATION_SIGN_DEFAULT); - public static final Preference precision = StringPreference.newInstance(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT, new NumberMapper(Integer.class)); - public static final Preference roundResult = new BooleanPreference(ROUND_RESULT_P_KEY, ROUND_RESULT_DEFAULT); - public static final Preference numeralBase = StringPreference.newInstance(NUMERAL_BASES_P_KEY, NUMERAL_BASES_DEFAULT, EnumMapper.newInstance(NumeralBase.class)); - public static final Preference angleUnit = StringPreference.newInstance(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT, EnumMapper.newInstance(AngleUnit.class)); - public static final Preference scienceNotation = new BooleanPreference(SCIENCE_NOTATION_P_KEY, SCIENCE_NOTATION_DEFAULT); - public static final Preference maxCalculationTime = StringPreference.newInstance(MAX_CALCULATION_TIME_P_KEY, MAX_CALCULATION_TIME_DEFAULT, new NumberMapper(Integer.class)); - - private static final List preferenceKeys = new ArrayList(); - - static { - preferenceKeys.add(groupingSeparator.getKey()); - preferenceKeys.add(multiplicationSign.getKey()); - preferenceKeys.add(precision.getKey()); - preferenceKeys.add(roundResult.getKey()); - preferenceKeys.add(numeralBase.getKey()); - preferenceKeys.add(angleUnit.getKey()); - preferenceKeys.add(scienceNotation.getKey()); - preferenceKeys.add(maxCalculationTime.getKey()); - } - - @NotNull - public static List getPreferenceKeys() { - return Collections.unmodifiableList(preferenceKeys); - } - } - - @NotNull - private final Object lock = new Object(); - - @NotNull - private MathEngine engine = JsclMathEngine.instance; - - @NotNull - public final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); - - @NotNull - private final AndroidMathRegistry varsRegistry = new AndroidVarsRegistryImpl(engine.getConstantsRegistry()); - - @NotNull - private final AndroidMathRegistry functionsRegistry = new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry()); - - @NotNull - private final AndroidMathRegistry operatorsRegistry = new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry()); - - private final AndroidMathRegistry postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry()); - - @Nullable - private ThreadKiller threadKiller = new AndroidThreadKiller(); - - // calculation thread timeout in seconds, after timeout thread would be interrupted - private int timeout = Integer.valueOf(MAX_CALCULATION_TIME_DEFAULT); - - @NotNull - private String multiplicationSign = MULTIPLICATION_SIGN_DEFAULT; - - CalculatorEngine() { - this.engine.setRoundResult(true); - this.engine.setUseGroupingSeparator(true); - } - - @Override - @NotNull - public String getMultiplicationSign() { - return multiplicationSign; - } - - public void setMultiplicationSign(@NotNull String multiplicationSign) { - this.multiplicationSign = multiplicationSign; - } - - public CalculatorOutput evaluate(@NotNull JsclOperation operation, - @NotNull String expression) throws CalculatorParseException, CalculatorEvalException { - return evaluate(operation, expression, null); - } - - public CalculatorOutput evaluate(@NotNull final JsclOperation operation, - @NotNull String expression, - @Nullable MessageRegistry mr) throws CalculatorParseException, CalculatorEvalException { - synchronized (lock) { - final StringBuilder sb = new StringBuilder(); - - final PreparedExpression preparedExpression = preprocessor.process(expression); - sb.append(preparedExpression); - - //Log.d(CalculatorEngine.class.getName(), "Preprocessed expression: " + preparedExpression); - /*if (operation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) { - operation = JsclOperation.simplify; - - if (mr != null) { - final String undefinedVars = CollectionsUtils.formatValue(preparedExpression.getUndefinedVars(), ", ", new Formatter() { - @Override - public String formatValue(@Nullable Var var) throws IllegalArgumentException { - return var != null ? var.getName() : ""; - } - }); - - mr.addMessage(new AndroidMessage(R.string.c_simplify_instead_of_numeric, MessageType.info, undefinedVars)); - } - }*/ - - final String jsclExpression = sb.toString(); - - final MutableObject calculationResult = new MutableObject(null); - final MutableObject parseException = new MutableObject(null); - final MutableObject evalException = new MutableObject(null); - final MutableObject calculationThread = new MutableObject(null); - - final CountDownLatch latch = new CountDownLatch(1); - - new Thread(new Runnable() { - @Override - public void run() { - final Thread thread = Thread.currentThread(); - try { - //Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName()); - //System.out.println(jsclExpression); - calculationThread.setObject(thread); - final Generic genericResult = operation.evaluateGeneric(jsclExpression); - - // NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!) - genericResult.toString(); - - calculationResult.setObject(genericResult); - } catch (AbstractJsclArithmeticException e) { - evalException.setObject(new CalculatorEvalException(e, e, jsclExpression)); - } catch (ArithmeticException e) { - //System.out.println(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())); - 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)); - } catch (ParseInterruptedException e) { - //System.out.println(e.getMessage()); - // do nothing - we ourselves interrupt the calculations - } finally { - //Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName()); - calculationThread.setObject(null); - latch.countDown(); - } - } - }).start(); - - try { - //Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName()); - latch.await(timeout, TimeUnit.SECONDS); - //Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName()); - - final CalculatorParseException parseExceptionObject = parseException.getObject(); - final CalculatorEvalException evalExceptionObject = evalException.getObject(); - final Object calculationResultLocal = calculationResult.getObject(); - final Thread calculationThreadLocal = calculationThread.getObject(); - - if (calculationThreadLocal != null) { - if (threadKiller != null) { - threadKiller.killThread(calculationThreadLocal); - } - //calculationThreadLocal.stop(); - } - - if (parseExceptionObject != null || evalExceptionObject != null) { - if (operation == JsclOperation.numeric && - (preparedExpression.isExistsUndefinedVar() || (evalExceptionObject != null && evalExceptionObject.getCause() instanceof NumeralBaseException))) { - return evaluate(JsclOperation.simplify, expression, mr); - } - - if (parseExceptionObject != null) { - throw parseExceptionObject; - } else { - throw evalExceptionObject; - } - } - - if (calculationResultLocal == null) { - final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_3, MessageType.error, CalculatorApplication.getInstance()); - throw new CalculatorParseException(jsclExpression, androidMessage); - } - - } catch (InterruptedException e) { - final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_4, MessageType.error, CalculatorApplication.getInstance()); - throw new CalculatorParseException(jsclExpression, androidMessage); - } - - final Generic genericResult = calculationResult.getObject(); - - return new CalculatorOutputImpl(operation.getFromProcessor().process(genericResult), operation, genericResult); - } - } - - public void setPrecision(int precision) { - this.getEngine().setPrecision(precision); - } - - public void setRoundResult(boolean roundResult) { - this.getEngine().setRoundResult(roundResult); - } - - public void init(@Nullable Context context, @Nullable SharedPreferences preferences) { - synchronized (lock) { - reset(context, preferences); - } - } - - public void reset(@Nullable Context context, @Nullable SharedPreferences preferences) { - synchronized (lock) { - softReset(context, preferences); - - varsRegistry.load(context, preferences); - functionsRegistry.load(context, preferences); - operatorsRegistry.load(context, preferences); - postfixFunctionsRegistry.load(context, preferences); - } - } - - public void softReset(@Nullable Context context, @Nullable SharedPreferences preferences) { - synchronized (lock) { - if (preferences != null) { - this.setPrecision(Preferences.precision.getPreference(preferences)); - this.setRoundResult(Preferences.roundResult.getPreference(preferences)); - this.setAngleUnits(getAngleUnitsFromPrefs(preferences)); - this.setNumeralBase(getNumeralBaseFromPrefs(preferences)); - this.setMultiplicationSign(Preferences.multiplicationSign.getPreference(preferences)); - this.setScienceNotation(Preferences.scienceNotation.getPreference(preferences)); - this.setTimeout(Preferences.maxCalculationTime.getPreference(preferences)); - - final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences); - if (StringUtils.isEmpty(groupingSeparator)) { - this.getEngine().setUseGroupingSeparator(false); - } else { - this.getEngine().setUseGroupingSeparator(true); - this.getEngine().setGroupingSeparator(groupingSeparator.charAt(0)); - } - } - } - } - - - @NotNull - public NumeralBase getNumeralBaseFromPrefs(@NotNull SharedPreferences preferences) { - return Preferences.numeralBase.getPreference(preferences); - } - - @NotNull - public AngleUnit getAngleUnitsFromPrefs(@NotNull SharedPreferences preferences) { - return Preferences.angleUnit.getPreference(preferences); - } - - //for tests only - void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) { - synchronized (lock) { - this.getEngine().setDecimalGroupSymbols(decimalGroupSymbols); - } - } - - @Override - @NotNull - public AndroidMathRegistry getVarsRegistry() { - return varsRegistry; - } - - @Override - @NotNull - public AndroidMathRegistry getFunctionsRegistry() { - return functionsRegistry; - } - - @Override - @NotNull - public AndroidMathRegistry getOperatorsRegistry() { - return operatorsRegistry; - } - - @Override - @NotNull - public AndroidMathRegistry getPostfixFunctionsRegistry() { - return postfixFunctionsRegistry; - } - - @Override - @NotNull - public MathEngine getEngine() { - return engine; - } - - // package protected for tests - void setTimeout(int timeout) { - this.timeout = timeout; - } - - public void setAngleUnits(@NotNull AngleUnit angleUnits) { - getEngine().setAngleUnits(angleUnits); - } - - public void setScienceNotation(boolean scienceNotation) { - getEngine().setScienceNotation(scienceNotation); - } - - public void setNumeralBase(@NotNull NumeralBase numeralBase) { - getEngine().setNumeralBase(numeralBase); - } - - // for tests only - void setThreadKiller(@Nullable ThreadKiller threadKiller) { - this.threadKiller = threadKiller; - } - - private static interface ThreadKiller { - void killThread(@NotNull Thread thread); - } - - private static class AndroidThreadKiller implements ThreadKiller { - @Override - public void killThread(@NotNull Thread thread) { - thread.setPriority(Thread.MIN_PRIORITY); - thread.interrupt(); - } - } - - public static class ThreadKillerImpl implements ThreadKiller { - @Override - public void killThread(@NotNull Thread thread) { - thread.setPriority(Thread.MIN_PRIORITY); - thread.stop(); - } - } -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.model; + +import android.content.Context; +import android.content.SharedPreferences; +import jscl.*; +import jscl.math.Generic; +import jscl.math.function.Function; +import jscl.math.function.IConstant; +import jscl.math.operator.Operator; +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.R; +import org.solovyev.android.calculator.jscl.JsclOperation; +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.text.EnumMapper; +import org.solovyev.common.text.NumberMapper; +import org.solovyev.common.text.StringUtils; + +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * User: serso + * Date: 9/12/11 + * Time: 11:38 PM + */ + +public enum CalculatorEngine { + + instance; + + private static final String GROUPING_SEPARATOR_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator"; + + private static final String MULTIPLICATION_SIGN_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_multiplication_sign"; + private static final String MULTIPLICATION_SIGN_DEFAULT = "×"; + + private static final String MAX_CALCULATION_TIME_P_KEY = "calculation.max_calculation_time"; + private static final String MAX_CALCULATION_TIME_DEFAULT = "5"; + + private static final String SCIENCE_NOTATION_P_KEY = "calculation.output.science_notation"; + private static final boolean SCIENCE_NOTATION_DEFAULT = false; + + private static final String ROUND_RESULT_P_KEY = "org.solovyev.android.calculator.CalculatorModel_round_result"; + private static final boolean ROUND_RESULT_DEFAULT = true; + + private static final String RESULT_PRECISION_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision"; + private static final String RESULT_PRECISION_DEFAULT = "5"; + + private static final String NUMERAL_BASES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_numeral_bases"; + private static final String NUMERAL_BASES_DEFAULT = "dec"; + + private static final String ANGLE_UNITS_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_angle_units"; + private static final String ANGLE_UNITS_DEFAULT = "deg"; + + public static class Preferences { + public static final Preference groupingSeparator = StringPreference.newInstance(GROUPING_SEPARATOR_P_KEY, JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); + public static final Preference multiplicationSign = StringPreference.newInstance(MULTIPLICATION_SIGN_P_KEY, MULTIPLICATION_SIGN_DEFAULT); + public static final Preference precision = StringPreference.newInstance(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT, new NumberMapper(Integer.class)); + public static final Preference roundResult = new BooleanPreference(ROUND_RESULT_P_KEY, ROUND_RESULT_DEFAULT); + public static final Preference numeralBase = StringPreference.newInstance(NUMERAL_BASES_P_KEY, NUMERAL_BASES_DEFAULT, EnumMapper.newInstance(NumeralBase.class)); + public static final Preference angleUnit = StringPreference.newInstance(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT, EnumMapper.newInstance(AngleUnit.class)); + public static final Preference scienceNotation = new BooleanPreference(SCIENCE_NOTATION_P_KEY, SCIENCE_NOTATION_DEFAULT); + public static final Preference maxCalculationTime = StringPreference.newInstance(MAX_CALCULATION_TIME_P_KEY, MAX_CALCULATION_TIME_DEFAULT, new NumberMapper(Integer.class)); + + private static final List preferenceKeys = new ArrayList(); + + static { + preferenceKeys.add(groupingSeparator.getKey()); + preferenceKeys.add(multiplicationSign.getKey()); + preferenceKeys.add(precision.getKey()); + preferenceKeys.add(roundResult.getKey()); + preferenceKeys.add(numeralBase.getKey()); + preferenceKeys.add(angleUnit.getKey()); + preferenceKeys.add(scienceNotation.getKey()); + preferenceKeys.add(maxCalculationTime.getKey()); + } + + @NotNull + public static List getPreferenceKeys() { + return Collections.unmodifiableList(preferenceKeys); + } + } + + @NotNull + private final Object lock = new Object(); + + @NotNull + private MathEngine engine = JsclMathEngine.instance; + + @NotNull + public final TextProcessor preprocessor = ToJsclTextProcessor.getInstance(); + + @NotNull + private final AndroidMathRegistry varsRegistry = new AndroidVarsRegistryImpl(engine.getConstantsRegistry()); + + @NotNull + private final AndroidMathRegistry functionsRegistry = new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry()); + + @NotNull + private final AndroidMathRegistry operatorsRegistry = new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry()); + + private final AndroidMathRegistry postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry()); + + @Nullable + private ThreadKiller threadKiller = new AndroidThreadKiller(); + + // calculation thread timeout in seconds, after timeout thread would be interrupted + private int timeout = Integer.valueOf(MAX_CALCULATION_TIME_DEFAULT); + + @NotNull + private String multiplicationSign = MULTIPLICATION_SIGN_DEFAULT; + + CalculatorEngine() { + this.engine.setRoundResult(true); + this.engine.setUseGroupingSeparator(true); + } + + @NotNull + public String getMultiplicationSign() { + return multiplicationSign; + } + + public void setMultiplicationSign(@NotNull String multiplicationSign) { + this.multiplicationSign = multiplicationSign; + } + + public static class Result { + + @NotNull + private Generic genericResult; + + @NotNull + private String result; + + @NotNull + private JsclOperation userOperation; + + public Result(@NotNull String result, @NotNull JsclOperation userOperation, @NotNull Generic genericResult) { + this.result = result; + this.userOperation = userOperation; + this.genericResult = genericResult; + } + + @NotNull + public String getResult() { + return result; + } + + @NotNull + public JsclOperation getUserOperation() { + return userOperation; + } + + @NotNull + public Generic getGenericResult() { + return genericResult; + } + } + + public Result evaluate(@NotNull JsclOperation operation, + @NotNull String expression) throws CalculatorParseException, CalculatorEvalException { + return evaluate(operation, expression, null); + } + + public Result evaluate(@NotNull final JsclOperation operation, + @NotNull String expression, + @Nullable MessageRegistry mr) throws CalculatorParseException, CalculatorEvalException { + synchronized (lock) { + final StringBuilder sb = new StringBuilder(); + + final PreparedExpression preparedExpression = preprocessor.process(expression); + sb.append(preparedExpression); + + //Log.d(CalculatorEngine.class.getName(), "Preprocessed expression: " + preparedExpression); + /*if (operation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) { + operation = JsclOperation.simplify; + + if (mr != null) { + final String undefinedVars = CollectionsUtils.formatValue(preparedExpression.getUndefinedVars(), ", ", new Formatter() { + @Override + public String formatValue(@Nullable Var var) throws IllegalArgumentException { + return var != null ? var.getName() : ""; + } + }); + + mr.addMessage(new AndroidMessage(R.string.c_simplify_instead_of_numeric, MessageType.info, undefinedVars)); + } + }*/ + + final String jsclExpression = sb.toString(); + + final MutableObject calculationResult = new MutableObject(null); + final MutableObject parseException = new MutableObject(null); + final MutableObject evalException = new MutableObject(null); + final MutableObject calculationThread = new MutableObject(null); + + final CountDownLatch latch = new CountDownLatch(1); + + new Thread(new Runnable() { + @Override + public void run() { + final Thread thread = Thread.currentThread(); + try { + //Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName()); + //System.out.println(jsclExpression); + calculationThread.setObject(thread); + final Generic genericResult = operation.evaluateGeneric(jsclExpression); + + // NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!) + genericResult.toString(); + + calculationResult.setObject(genericResult); + } catch (AbstractJsclArithmeticException e) { + 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())); + } catch (StackOverflowError e) { + //System.out.println(StringUtils.fromStackTrace(e.getStackTrace())); + parseException.setObject(new CalculatorParseException(R.string.msg_2, CalculatorApplication.getInstance(), jsclExpression)); + } catch (jscl.text.ParseException e) { + //System.out.println(e.getMessage()); + parseException.setObject(new CalculatorParseException(e)); + } catch (ParseInterruptedException e) { + //System.out.println(e.getMessage()); + // do nothing - we ourselves interrupt the calculations + } finally { + //Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName()); + calculationThread.setObject(null); + latch.countDown(); + } + } + }).start(); + + try { + //Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName()); + latch.await(timeout, TimeUnit.SECONDS); + //Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName()); + + final CalculatorParseException parseExceptionObject = parseException.getObject(); + final CalculatorEvalException evalExceptionObject = evalException.getObject(); + final Object calculationResultLocal = calculationResult.getObject(); + final Thread calculationThreadLocal = calculationThread.getObject(); + + if (calculationThreadLocal != null) { + if (threadKiller != null) { + threadKiller.killThread(calculationThreadLocal); + } + //calculationThreadLocal.stop(); + } + + if (parseExceptionObject != null || evalExceptionObject != null) { + if (operation == JsclOperation.numeric && + (preparedExpression.isExistsUndefinedVar() || (evalExceptionObject != null && evalExceptionObject.getCause() instanceof NumeralBaseException))) { + return evaluate(JsclOperation.simplify, expression, mr); + } + + if (parseExceptionObject != null) { + throw parseExceptionObject; + } else { + throw evalExceptionObject; + } + } + + if (calculationResultLocal == null) { + throw new CalculatorParseException(R.string.msg_3, CalculatorApplication.getInstance(), jsclExpression); + } + + } catch (InterruptedException e) { + throw new CalculatorParseException(R.string.msg_4, CalculatorApplication.getInstance(), jsclExpression); + } + + final Generic genericResult = calculationResult.getObject(); + + return new Result(operation.getFromProcessor().process(genericResult), operation, genericResult); + } + } + + public void setPrecision(int precision) { + this.getEngine().setPrecision(precision); + } + + public void setRoundResult(boolean roundResult) { + this.getEngine().setRoundResult(roundResult); + } + + public void init(@Nullable Context context, @Nullable SharedPreferences preferences) { + synchronized (lock) { + reset(context, preferences); + } + } + + public void reset(@Nullable Context context, @Nullable SharedPreferences preferences) { + synchronized (lock) { + softReset(context, preferences); + + varsRegistry.load(context, preferences); + functionsRegistry.load(context, preferences); + operatorsRegistry.load(context, preferences); + postfixFunctionsRegistry.load(context, preferences); + } + } + + public void softReset(@Nullable Context context, @Nullable SharedPreferences preferences) { + synchronized (lock) { + if (preferences != null) { + this.setPrecision(Preferences.precision.getPreference(preferences)); + this.setRoundResult(Preferences.roundResult.getPreference(preferences)); + this.setAngleUnits(getAngleUnitsFromPrefs(preferences)); + this.setNumeralBase(getNumeralBaseFromPrefs(preferences)); + this.setMultiplicationSign(Preferences.multiplicationSign.getPreference(preferences)); + this.setScienceNotation(Preferences.scienceNotation.getPreference(preferences)); + this.setTimeout(Preferences.maxCalculationTime.getPreference(preferences)); + + final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences); + if (StringUtils.isEmpty(groupingSeparator)) { + this.getEngine().setUseGroupingSeparator(false); + } else { + this.getEngine().setUseGroupingSeparator(true); + this.getEngine().setGroupingSeparator(groupingSeparator.charAt(0)); + } + } + } + } + + + @NotNull + public NumeralBase getNumeralBaseFromPrefs(@NotNull SharedPreferences preferences) { + return Preferences.numeralBase.getPreference(preferences); + } + + @NotNull + public AngleUnit getAngleUnitsFromPrefs(@NotNull SharedPreferences preferences) { + return Preferences.angleUnit.getPreference(preferences); + } + + //for tests only + void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) { + synchronized (lock) { + this.getEngine().setDecimalGroupSymbols(decimalGroupSymbols); + } + } + + @NotNull + public AndroidMathRegistry getVarsRegistry() { + return varsRegistry; + } + + @NotNull + public AndroidMathRegistry getFunctionsRegistry() { + return functionsRegistry; + } + + @NotNull + public AndroidMathRegistry getOperatorsRegistry() { + return operatorsRegistry; + } + + @NotNull + public AndroidMathRegistry getPostfixFunctionsRegistry() { + return postfixFunctionsRegistry; + } + + @NotNull + public MathEngine getEngine() { + return engine; + } + + // package protected for tests + void setTimeout(int timeout) { + this.timeout = timeout; + } + + public void setAngleUnits(@NotNull AngleUnit angleUnits) { + getEngine().setAngleUnits(angleUnits); + } + + public void setScienceNotation(boolean scienceNotation) { + getEngine().setScienceNotation(scienceNotation); + } + + public void setNumeralBase(@NotNull NumeralBase numeralBase) { + getEngine().setNumeralBase(numeralBase); + } + + // for tests only + void setThreadKiller(@Nullable ThreadKiller threadKiller) { + this.threadKiller = threadKiller; + } + + private static interface ThreadKiller { + void killThread(@NotNull Thread thread); + } + + private static class AndroidThreadKiller implements ThreadKiller { + @Override + public void killThread(@NotNull Thread thread) { + thread.setPriority(Thread.MIN_PRIORITY); + thread.interrupt(); + } + } + + public static class ThreadKillerImpl implements ThreadKiller { + @Override + public void killThread(@NotNull Thread thread) { + thread.setPriority(Thread.MIN_PRIORITY); + thread.stop(); + } + } +} diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvalException.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEvalException.java similarity index 89% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvalException.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEvalException.java index 8aba31d2..bfaa7698 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorEvalException.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorEvalException.java @@ -4,8 +4,9 @@ * or visit http://se.solovyev.org */ -package org.solovyev.android.calculator; +package org.solovyev.android.calculator.model; +import jscl.AbstractJsclArithmeticException; import org.jetbrains.annotations.NotNull; import org.solovyev.common.exceptions.SersoException; import org.solovyev.common.msg.Message; diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorParseException.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java similarity index 71% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorParseException.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java index 8ebfccf7..e164578f 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/CalculatorParseException.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/CalculatorParseException.java @@ -4,10 +4,12 @@ * or visit http://se.solovyev.org */ -package org.solovyev.android.calculator; +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; @@ -37,17 +39,14 @@ public class CalculatorParseException extends SersoException implements Message this.position = jsclParseException.getPosition(); } - public CalculatorParseException(@Nullable Integer position, - @NotNull String expression, - @NotNull Message message) { - this.message = message; + 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); this.expression = expression; this.position = position; } - public CalculatorParseException(@NotNull String expression, - @NotNull Message message) { - this(null, expression, message); + public CalculatorParseException(@NotNull Integer messageId, @NotNull Application application, @NotNull String expression, Object... parameters) { + this(messageId, application, null, expression, parameters); } @NotNull diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/DummyTextProcessor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java similarity index 78% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/DummyTextProcessor.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java index 22a969c5..779a1fe8 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/DummyTextProcessor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/DummyTextProcessor.java @@ -4,11 +4,10 @@ * or visit http://se.solovyev.org */ -package org.solovyev.android.calculator.text; +package org.solovyev.android.calculator.model; import jscl.math.Generic; import org.jetbrains.annotations.NotNull; -import org.solovyev.android.calculator.CalculatorParseException; /** * User: serso diff --git a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java similarity index 86% rename from calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java rename to calculatorpp/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java index 3fc4da64..2f47d1e7 100644 --- a/calculatorpp-core/src/main/java/org/solovyev/android/calculator/text/FromJsclSimplifyTextProcessor.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java @@ -1,11 +1,9 @@ -package org.solovyev.android.calculator.text; +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.CalculatorLocatorImpl; import org.solovyev.android.calculator.math.MathType; -import org.solovyev.android.calculator.CalculatorParseException; import java.util.Arrays; import java.util.List; @@ -57,7 +55,7 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor undefinedVars) throws CalculatorParseException { if (depth >= MAX_DEPTH) { - final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_6, MessageType.error, CalculatorApplication.getInstance()); - throw new CalculatorParseException(s, androidMessage); + throw new CalculatorParseException(R.string.msg_6, CalculatorApplication.getInstance(), s); } else { depth++; } diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java index c38714bc..e8a29bcf 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotActivity.java @@ -35,9 +35,9 @@ import org.achartengine.tools.ZoomListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.R; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.PreparedExpression; -import org.solovyev.android.calculator.ToJsclTextProcessor; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.android.calculator.model.PreparedExpression; +import org.solovyev.android.calculator.model.ToJsclTextProcessor; import org.solovyev.common.MutableObject; import java.io.Serializable; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java index 78f3a0bd..4b6746a3 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/NumeralBaseConverterDialog.java @@ -6,14 +6,14 @@ import android.view.View; import android.view.WindowManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.math.units.Unit; -import org.solovyev.math.units.UnitImpl; +import org.solovyev.android.Unit; +import org.solovyev.android.UnitImpl; import org.solovyev.android.calculator.AndroidNumeralBase; import org.solovyev.android.calculator.CalculatorModel; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.ToJsclTextProcessor; +import org.solovyev.android.calculator.model.CalculatorParseException; +import org.solovyev.android.calculator.model.ToJsclTextProcessor; import org.solovyev.common.MutableObject; import org.solovyev.common.text.StringUtils; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java index 0d616fcc..a0ba0a31 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/TextHighlighter.java @@ -9,13 +9,8 @@ package org.solovyev.android.calculator.view; import jscl.MathContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.AbstractNumberBuilder; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.LiteNumberBuilder; -import org.solovyev.android.calculator.NumberBuilder; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.*; -import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.common.MutableObject; import java.util.HashMap; diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java index d75c7240..c4393393 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/view/UnitConverterViewBuilder.java @@ -10,10 +10,10 @@ import android.view.ViewGroup; import android.widget.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.math.units.Unit; -import org.solovyev.math.units.UnitConverter; -import org.solovyev.math.units.UnitImpl; -import org.solovyev.math.units.UnitType; +import org.solovyev.android.Unit; +import org.solovyev.android.UnitConverter; +import org.solovyev.android.UnitImpl; +import org.solovyev.android.UnitType; import org.solovyev.android.calculator.R; import org.solovyev.android.view.ViewBuilder; import org.solovyev.android.view.ViewFromLayoutBuilder; diff --git a/calculatorpp/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java b/calculatorpp/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java index 5ad54751..b99ff21a 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/AndroidNumeralBaseTest.java @@ -4,8 +4,6 @@ import junit.framework.Assert; import org.jetbrains.annotations.NotNull; import org.junit.Test; import org.solovyev.android.calculator.AndroidNumeralBase; -import org.solovyev.math.units.Unit; -import org.solovyev.math.units.UnitConverter; import java.util.Date; import java.util.Random; diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java index af984177..021ce608 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java @@ -12,7 +12,7 @@ import jscl.NumeralBase; import junit.framework.Assert; import org.junit.Test; import org.solovyev.android.calculator.model.CalculatorEngine; -import org.solovyev.android.calculator.text.TextProcessor; +import org.solovyev.android.calculator.model.TextProcessor; import org.solovyev.android.calculator.view.TextHighlighter; import java.util.Date; 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 4247f1b8..af7f103e 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,321 +1,320 @@ -/* - * 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.CalculatorDisplay; -import org.solovyev.android.calculator.Editor; -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(); - - CalculatorDisplay 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 CalculatorDisplay { - - @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.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/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java index 375969ef..ac83a8bd 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java @@ -1,445 +1,443 @@ -/* - * Copyright (c) 2009-2011. Created by serso aka se.solovyev. - * For more information, please, contact se.solovyev@gmail.com - */ - -package org.solovyev.android.calculator.model; - -import jscl.AngleUnit; -import jscl.JsclMathEngine; -import jscl.NumeralBase; -import jscl.math.Expression; -import jscl.math.Generic; -import jscl.math.function.Constant; -import jscl.math.function.CustomFunction; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.solovyev.android.calculator.CalculatorEvalException; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.jscl.JsclOperation; - -import java.text.DecimalFormatSymbols; -import java.util.Locale; - -import static junit.framework.Assert.fail; - -/** - * User: serso - * Date: 9/17/11 - * Time: 9:47 PM - */ - -public class CalculatorEngineTest { - - @BeforeClass - public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); - CalculatorEngine.instance.setPrecision(3); - CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); - } - - @Test - public void testDegrees() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); - try { - cm.getEngine().setAngleUnits(AngleUnit.rad); - cm.setPrecision(3); - try { - Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "°")); - fail(); - } catch (CalculatorParseException e) { - - } - - Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "1°").getStringResult()); - Assert.assertEquals("0.349", cm.evaluate(JsclOperation.numeric, "20.0°").getStringResult()); - Assert.assertEquals("0.5", cm.evaluate(JsclOperation.numeric, "sin(30°)").getStringResult()); - Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(sin(30°))").getStringResult()); - Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.numeric, "∂(cos(t),t,t,1°)").getStringResult()); - - Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getStringResult()); - } finally { - cm.getEngine().setAngleUnits(defaultAngleUnit); - } - } - - @Test - public void testLongExecution() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - try { - cm.evaluate(JsclOperation.numeric, "3^10^10^10"); - Assert.fail(); - } catch (CalculatorParseException e) { - if (e.getMessageCode().equals(Messages.msg_3)) { - - } else { - System.out.print(e.getCause().getMessage()); - Assert.fail(); - } - } - - try { - cm.evaluate(JsclOperation.numeric, "9999999!"); - Assert.fail(); - } catch (CalculatorParseException e) { - if (e.getMessageCode().equals(Messages.msg_3)) { - - } else { - System.out.print(e.getCause().getMessage()); - Assert.fail(); - } - } - - /*final long start = System.currentTimeMillis(); - try { - cm.evaluate(JsclOperation.numeric, "3^10^10^10"); - Assert.fail(); - } catch (ParseException e) { - if (e.getMessage().startsWith("Too long calculation")) { - final long end = System.currentTimeMillis(); - Assert.assertTrue(end - start < 1000); - } else { - Assert.fail(); - } - }*/ - - } - - @Test - public void testEvaluate() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getStringResult()); - - final Generic expression = cm.getEngine().simplifyGeneric("cos(t)+10%"); - expression.substitute(new Constant("t"), Expression.valueOf(100d)); - - Assert.assertEquals("it", cm.evaluate(JsclOperation.simplify, "it").getStringResult()); - Assert.assertEquals("10%", cm.evaluate(JsclOperation.simplify, "10%").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq( 1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getStringResult()); - Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getStringResult()); - final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); - try { - cm.getEngine().setAngleUnits(AngleUnit.rad); - Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getStringResult()); - Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getStringResult()); - Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getStringResult()); - Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getStringResult()); - Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getStringResult()); - } finally { - cm.getEngine().setAngleUnits(defaultAngleUnit); - } - Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getStringResult()); - Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getStringResult()); - Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getStringResult()); - Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getStringResult()); - try { - cm.getEngine().setAngleUnits(AngleUnit.rad); - Assert.assertEquals("0.921+Πi", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getStringResult()); - Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getStringResult()); - } finally { - cm.getEngine().setAngleUnits(defaultAngleUnit); - } - Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getStringResult()); - Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getStringResult()); - Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)").getStringResult()); - Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i").getStringResult()); - Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i").getStringResult()); - Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getStringResult()); - Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getStringResult()); - Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getStringResult()); - - junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getStringResult()); - junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getStringResult()); - junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getStringResult()); - junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getStringResult()); - junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getStringResult()); - junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "(3!)!").getStringResult()); - junit.framework.Assert.assertEquals("36", Expression.valueOf("3!^2").numeric().toString()); - junit.framework.Assert.assertEquals("3", Expression.valueOf("cubic(27)").numeric().toString()); - try { - junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getStringResult()); - fail(); - } catch (CalculatorParseException e) { - } - - junit.framework.Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "(π/π)!").getStringResult()); - - try { - junit.framework.Assert.assertEquals("i", cm.evaluate(JsclOperation.numeric, "(-1)i!").getStringResult()); - fail(); - } catch (CalculatorParseException e) { - - } - junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getStringResult()); - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); - - try { - cm.getEngine().setAngleUnits(AngleUnit.rad); - Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getStringResult()); - Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getStringResult()); - Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getStringResult()); - Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si").getStringResult()); - Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getStringResult()); - Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getStringResult()); - } finally { - cm.getEngine().setAngleUnits(defaultAngleUnit); - } - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("s", 1d)); - Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult()); - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", 3.5d)); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k1", 4d)); - Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getStringResult()); - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); - Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getStringResult()); - Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getStringResult()); - Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "∞").getStringResult()); - Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "Infinity").getStringResult()); - Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getStringResult()); - Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getStringResult()); - - Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getStringResult()); - Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getStringResult()); - - Assert.assertEquals("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getStringResult()); - - try { - cm.getEngine().setNumeralBase(NumeralBase.hex); - Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getStringResult()); - Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getStringResult()); - Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getStringResult()); - Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getStringResult()); - } finally { - cm.getEngine().setNumeralBase(NumeralBase.dec); - } - - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getStringResult()); - - - /* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult()); - Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "(10+20)°").getResult()); - Assert.assertEquals("1.047", cm.evaluate(JsclOperation.numeric, "(10+20)°*2").getResult()); - try { - Assert.assertEquals("0.278", cm.evaluate(JsclOperation.numeric, "30°^2").getResult()); - junit.framework.Assert.fail(); - } catch (ParseException e) { - if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) { - junit.framework.Assert.fail(); - } - }*/ - -/* try { - cm.setTimeout(5000); - Assert.assertEquals("2", cm.evaluate(JsclOperation.numeric, "2!").getResult()); - } finally { - cm.setTimeout(3000); - }*/ - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); - Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult()); - Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult()); - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", "2")); - Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult()); - Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult()); - - Assert.assertEquals("-x+x*ln(x)", cm.getEngine().simplify("∫(ln(x), x)")); - Assert.assertEquals("-(x-x*ln(x))/(ln(2)+ln(5))", cm.getEngine().simplify("∫(log(10, x), x)")); - - Assert.assertEquals("∫((ln(2)+ln(5))/ln(x), x)", cm.getEngine().simplify("∫(ln(10)/ln(x), x)")); - Assert.assertEquals("∫(ln(10)/ln(x), x)", Expression.valueOf("∫(log(x, 10), x)").expand().toString()); - Assert.assertEquals("∫((ln(2)+ln(5))/ln(x), x)", cm.getEngine().simplify("∫(log(x, 10), x)")); - } - - @Test - public void testFormatting() throws Exception { - final CalculatorEngine ce = CalculatorEngine.instance; - - Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getStringResult()); - - } - - @Test - public void testI() throws CalculatorParseException, CalculatorEvalException { - final CalculatorEngine cm = CalculatorEngine.instance; - - Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getStringResult()); - for (int i = 0; i < 1000; i++) { - double real = (Math.random()-0.5) * 1000; - double imag = (Math.random()-0.5) * 1000; - int exp = (int)(Math.random() * 10); - - final StringBuilder sb = new StringBuilder(); - sb.append(real); - if ( imag > 0 ) { - sb.append("+"); - } - sb.append(imag); - sb.append("^").append(exp); - try { - cm.evaluate(JsclOperation.numeric, sb.toString()).getStringResult(); - } catch (Throwable e) { - fail(sb.toString()); - } - } - } - - @Test - public void testEmptyFunction() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - try { - cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - Assert.assertEquals("0.34+1.382i", cm.evaluate(JsclOperation.numeric, "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))").getStringResult()); - try { - cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos())))))))))))))))))))))))))))))))))))"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - - final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); - try { - cm.getEngine().setAngleUnits(AngleUnit.rad); - Assert.assertEquals("0.739", cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(1))))))))))))))))))))))))))))))))))))").getStringResult()); - } finally { - cm.getEngine().setAngleUnits(defaultAngleUnit); - } - - CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); - Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult()); - - try { - cm.evaluate(JsclOperation.numeric, "sin"); - Assert.fail(); - } catch (CalculatorParseException e) { - } - } - - @Test - public void testRounding() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - try { - DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); - decimalGroupSymbols.setDecimalSeparator('.'); - decimalGroupSymbols.setGroupingSeparator('\''); - cm.setDecimalGroupSymbols(decimalGroupSymbols); - cm.setPrecision(2); - Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getStringResult()); - cm.setPrecision(10); - Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getStringResult()); - Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getStringResult()); - Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getStringResult()); - } finally { - cm.setPrecision(3); - DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); - decimalGroupSymbols.setDecimalSeparator('.'); - decimalGroupSymbols.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT.charAt(0)); - cm.setDecimalGroupSymbols(decimalGroupSymbols); - } - } - - @Test - public void testComparisonFunction() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1.0)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 1.000000000000001)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 0)").getStringResult()); - - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lt(0, 1)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 1)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 0)").getStringResult()); - - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(0, 1)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "gt(1, 0)").getStringResult()); - - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(0, 1)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ne(1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(1, 0)").getStringResult()); - - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(0, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(1, 1)").getStringResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "le(1, 0)").getStringResult()); - - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ge(0, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 0)").getStringResult()); - - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(0, 1)").getStringResult()); - Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1)").getStringResult()); - //Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1.000000000000001)").getResult()); - Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(1, 0)").getStringResult()); - - } - - - @Test - public void testNumeralSystems() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getStringResult()); - Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getStringResult()); - Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF").getStringResult()); - Assert.assertEquals("e", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF/0x:ABCDEF").getStringResult()); - Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF").getStringResult()); - Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C").getStringResult()); - Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getStringResult()); - Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getStringResult()); - - try { - cm.evaluate(JsclOperation.numeric, "0b:π").getStringResult(); - Assert.fail(); - } catch (CalculatorParseException e) { - // ok - } - - final NumeralBase defaultNumeralBase = cm.getEngine().getNumeralBase(); - try{ - cm.getEngine().setNumeralBase(NumeralBase.bin); - Assert.assertEquals("101", cm.evaluate(JsclOperation.numeric, "10+11").getStringResult()); - Assert.assertEquals("10/11", cm.evaluate(JsclOperation.numeric, "10/11").getStringResult()); - - cm.getEngine().setNumeralBase(NumeralBase.hex); - Assert.assertEquals("63 7B", cm.evaluate(JsclOperation.numeric, "56CE+CAD").getStringResult()); - Assert.assertEquals("E", cm.evaluate(JsclOperation.numeric, "E").getStringResult()); - } finally { - cm.setNumeralBase(defaultNumeralBase); - } - } - - @Test - public void testLog() throws Exception { - final CalculatorEngine cm = CalculatorEngine.instance; - - Assert.assertEquals("∞", Expression.valueOf("1/0").numeric().toString()); - Assert.assertEquals("∞", Expression.valueOf("ln(10)/ln(1)").numeric().toString()); - - // logarithm - Assert.assertEquals("ln(x)/ln(base)", ((CustomFunction) cm.getFunctionsRegistry().get("log")).getContent()); - Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "log(1, 10)").getStringResult()); - Assert.assertEquals("3.322", cm.evaluate(JsclOperation.numeric, "log(2, 10)").getStringResult()); - Assert.assertEquals("1.431", cm.evaluate(JsclOperation.numeric, "log(5, 10)").getStringResult()); - Assert.assertEquals("0.96", cm.evaluate(JsclOperation.numeric, "log(11, 10)").getStringResult()); - Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getStringResult()); - Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getStringResult()); - - } -} +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + */ + +package org.solovyev.android.calculator.model; + +import jscl.AngleUnit; +import jscl.JsclMathEngine; +import jscl.NumeralBase; +import jscl.math.Expression; +import jscl.math.Generic; +import jscl.math.function.Constant; +import jscl.math.function.CustomFunction; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.solovyev.android.calculator.jscl.JsclOperation; + +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +import static junit.framework.Assert.fail; + +/** + * User: serso + * Date: 9/17/11 + * Time: 9:47 PM + */ + +public class CalculatorEngineTest { + + @BeforeClass + public static void setUp() throws Exception { + CalculatorEngine.instance.init(null, null); + CalculatorEngine.instance.setPrecision(3); + CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); + } + + @Test + public void testDegrees() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); + try { + cm.getEngine().setAngleUnits(AngleUnit.rad); + cm.setPrecision(3); + try { + Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "°")); + fail(); + } catch (CalculatorParseException e) { + + } + + Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "1°").getResult()); + Assert.assertEquals("0.349", cm.evaluate(JsclOperation.numeric, "20.0°").getResult()); + Assert.assertEquals("0.5", cm.evaluate(JsclOperation.numeric, "sin(30°)").getResult()); + Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(sin(30°))").getResult()); + Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.numeric, "∂(cos(t),t,t,1°)").getResult()); + + Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getResult()); + } finally { + cm.getEngine().setAngleUnits(defaultAngleUnit); + } + } + + @Test + public void testLongExecution() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + try { + cm.evaluate(JsclOperation.numeric, "3^10^10^10"); + Assert.fail(); + } catch (CalculatorParseException e) { + if (e.getMessageCode().equals(Messages.msg_3)) { + + } else { + System.out.print(e.getCause().getMessage()); + Assert.fail(); + } + } + + try { + cm.evaluate(JsclOperation.numeric, "9999999!"); + Assert.fail(); + } catch (CalculatorParseException e) { + if (e.getMessageCode().equals(Messages.msg_3)) { + + } else { + System.out.print(e.getCause().getMessage()); + Assert.fail(); + } + } + + /*final long start = System.currentTimeMillis(); + try { + cm.evaluate(JsclOperation.numeric, "3^10^10^10"); + Assert.fail(); + } catch (ParseException e) { + if (e.getMessage().startsWith("Too long calculation")) { + final long end = System.currentTimeMillis(); + Assert.assertTrue(end - start < 1000); + } else { + Assert.fail(); + } + }*/ + + } + + @Test + public void testEvaluate() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getResult()); + + final Generic expression = cm.getEngine().simplifyGeneric("cos(t)+10%"); + expression.substitute(new Constant("t"), Expression.valueOf(100d)); + + Assert.assertEquals("it", cm.evaluate(JsclOperation.simplify, "it").getResult()); + Assert.assertEquals("10%", cm.evaluate(JsclOperation.simplify, "10%").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq( 1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getResult()); + Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getResult()); + final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); + try { + cm.getEngine().setAngleUnits(AngleUnit.rad); + Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getResult()); + Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getResult()); + Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getResult()); + Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult()); + Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult()); + } finally { + cm.getEngine().setAngleUnits(defaultAngleUnit); + } + Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getResult()); + Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getResult()); + Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getResult()); + Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getResult()); + try { + cm.getEngine().setAngleUnits(AngleUnit.rad); + Assert.assertEquals("0.921+Πi", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getResult()); + Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getResult()); + } finally { + cm.getEngine().setAngleUnits(defaultAngleUnit); + } + Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getResult()); + Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getResult()); + Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)").getResult()); + Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i").getResult()); + Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i").getResult()); + Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getResult()); + Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getResult()); + Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getResult()); + + junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getResult()); + junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getResult()); + junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getResult()); + junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getResult()); + junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getResult()); + junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "(3!)!").getResult()); + junit.framework.Assert.assertEquals("36", Expression.valueOf("3!^2").numeric().toString()); + junit.framework.Assert.assertEquals("3", Expression.valueOf("cubic(27)").numeric().toString()); + try { + junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getResult()); + fail(); + } catch (CalculatorParseException e) { + } + + junit.framework.Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "(π/π)!").getResult()); + + try { + junit.framework.Assert.assertEquals("i", cm.evaluate(JsclOperation.numeric, "(-1)i!").getResult()); + fail(); + } catch (CalculatorParseException e) { + + } + junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getResult()); + + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); + + try { + cm.getEngine().setAngleUnits(AngleUnit.rad); + Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getResult()); + Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getResult()); + Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getResult()); + Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si").getResult()); + Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getResult()); + Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getResult()); + } finally { + cm.getEngine().setAngleUnits(defaultAngleUnit); + } + + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("s", 1d)); + Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult()); + + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", 3.5d)); + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k1", 4d)); + Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getResult()); + + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); + Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getResult()); + Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getResult()); + Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "∞").getResult()); + Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "Infinity").getResult()); + Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getResult()); + Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult()); + + Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getResult()); + Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult()); + + Assert.assertEquals("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult()); + + try { + cm.getEngine().setNumeralBase(NumeralBase.hex); + Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult()); + Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getResult()); + Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getResult()); + Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getResult()); + } finally { + cm.getEngine().setNumeralBase(NumeralBase.dec); + } + + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getResult()); + + + /* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult()); + Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "(10+20)°").getResult()); + Assert.assertEquals("1.047", cm.evaluate(JsclOperation.numeric, "(10+20)°*2").getResult()); + try { + Assert.assertEquals("0.278", cm.evaluate(JsclOperation.numeric, "30°^2").getResult()); + junit.framework.Assert.fail(); + } catch (ParseException e) { + if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) { + junit.framework.Assert.fail(); + } + }*/ + +/* try { + cm.setTimeout(5000); + Assert.assertEquals("2", cm.evaluate(JsclOperation.numeric, "2!").getResult()); + } finally { + cm.setTimeout(3000); + }*/ + + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); + Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getResult()); + Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getResult()); + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", "2")); + Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getResult()); + Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getResult()); + + Assert.assertEquals("-x+x*ln(x)", cm.getEngine().simplify("∫(ln(x), x)")); + Assert.assertEquals("-(x-x*ln(x))/(ln(2)+ln(5))", cm.getEngine().simplify("∫(log(10, x), x)")); + + Assert.assertEquals("∫((ln(2)+ln(5))/ln(x), x)", cm.getEngine().simplify("∫(ln(10)/ln(x), x)")); + Assert.assertEquals("∫(ln(10)/ln(x), x)", Expression.valueOf("∫(log(x, 10), x)").expand().toString()); + Assert.assertEquals("∫((ln(2)+ln(5))/ln(x), x)", cm.getEngine().simplify("∫(log(x, 10), x)")); + } + + @Test + public void testFormatting() throws Exception { + final CalculatorEngine ce = CalculatorEngine.instance; + + Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getResult()); + + } + + @Test + public void testI() throws CalculatorParseException, CalculatorEvalException { + final CalculatorEngine cm = CalculatorEngine.instance; + + Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getResult()); + for (int i = 0; i < 1000; i++) { + double real = (Math.random()-0.5) * 1000; + double imag = (Math.random()-0.5) * 1000; + int exp = (int)(Math.random() * 10); + + final StringBuilder sb = new StringBuilder(); + sb.append(real); + if ( imag > 0 ) { + sb.append("+"); + } + sb.append(imag); + sb.append("^").append(exp); + try { + cm.evaluate(JsclOperation.numeric, sb.toString()).getResult(); + } catch (Throwable e) { + fail(sb.toString()); + } + } + } + + @Test + public void testEmptyFunction() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + try { + cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + Assert.assertEquals("0.34+1.382i", cm.evaluate(JsclOperation.numeric, "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))").getResult()); + try { + cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos())))))))))))))))))))))))))))))))))))"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + + final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); + try { + cm.getEngine().setAngleUnits(AngleUnit.rad); + Assert.assertEquals("0.739", cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(1))))))))))))))))))))))))))))))))))))").getResult()); + } finally { + cm.getEngine().setAngleUnits(defaultAngleUnit); + } + + CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); + Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult()); + + try { + cm.evaluate(JsclOperation.numeric, "sin"); + Assert.fail(); + } catch (CalculatorParseException e) { + } + } + + @Test + public void testRounding() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + try { + DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); + decimalGroupSymbols.setDecimalSeparator('.'); + decimalGroupSymbols.setGroupingSeparator('\''); + cm.setDecimalGroupSymbols(decimalGroupSymbols); + cm.setPrecision(2); + Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); + cm.setPrecision(10); + Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); + Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getResult()); + Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getResult()); + } finally { + cm.setPrecision(3); + DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); + decimalGroupSymbols.setDecimalSeparator('.'); + decimalGroupSymbols.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT.charAt(0)); + cm.setDecimalGroupSymbols(decimalGroupSymbols); + } + } + + @Test + public void testComparisonFunction() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1.0)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 1.000000000000001)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 0)").getResult()); + + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lt(0, 1)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 1)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 0)").getResult()); + + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(0, 1)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "gt(1, 0)").getResult()); + + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(0, 1)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ne(1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(1, 0)").getResult()); + + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(0, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(1, 1)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "le(1, 0)").getResult()); + + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ge(0, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 0)").getResult()); + + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(0, 1)").getResult()); + Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1)").getResult()); + //Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1.000000000000001)").getResult()); + Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(1, 0)").getResult()); + + } + + + @Test + public void testNumeralSystems() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF").getResult()); + Assert.assertEquals("e", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF/0x:ABCDEF").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C").getResult()); + Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getResult()); + Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getResult()); + + try { + cm.evaluate(JsclOperation.numeric, "0b:π").getResult(); + Assert.fail(); + } catch (CalculatorParseException e) { + // ok + } + + final NumeralBase defaultNumeralBase = cm.getEngine().getNumeralBase(); + try{ + cm.getEngine().setNumeralBase(NumeralBase.bin); + Assert.assertEquals("101", cm.evaluate(JsclOperation.numeric, "10+11").getResult()); + Assert.assertEquals("10/11", cm.evaluate(JsclOperation.numeric, "10/11").getResult()); + + cm.getEngine().setNumeralBase(NumeralBase.hex); + Assert.assertEquals("63 7B", cm.evaluate(JsclOperation.numeric, "56CE+CAD").getResult()); + Assert.assertEquals("E", cm.evaluate(JsclOperation.numeric, "E").getResult()); + } finally { + cm.setNumeralBase(defaultNumeralBase); + } + } + + @Test + public void testLog() throws Exception { + final CalculatorEngine cm = CalculatorEngine.instance; + + Assert.assertEquals("∞", Expression.valueOf("1/0").numeric().toString()); + Assert.assertEquals("∞", Expression.valueOf("ln(10)/ln(1)").numeric().toString()); + + // logarithm + Assert.assertEquals("ln(x)/ln(base)", ((CustomFunction) cm.getFunctionsRegistry().get("log")).getContent()); + Assert.assertEquals("∞", cm.evaluate(JsclOperation.numeric, "log(1, 10)").getResult()); + Assert.assertEquals("3.322", cm.evaluate(JsclOperation.numeric, "log(2, 10)").getResult()); + Assert.assertEquals("1.431", cm.evaluate(JsclOperation.numeric, "log(5, 10)").getResult()); + Assert.assertEquals("0.96", cm.evaluate(JsclOperation.numeric, "log(11, 10)").getResult()); + Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getResult()); + Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getResult()); + + } +} diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java index a52ee3af..dd89677b 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java @@ -3,7 +3,6 @@ package org.solovyev.android.calculator.model; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; import java.text.DecimalFormatSymbols; diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java index 5e05495c..94989a3a 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java @@ -1,148 +1,146 @@ -package org.solovyev.android.calculator.model; - -import au.com.bytecode.opencsv.CSVReader; -import jscl.JsclMathEngine; -import jscl.MathEngine; -import jscl.math.Expression; -import jscl.text.ParseException; -import jscl.util.ExpressionGeneratorWithInput; -import org.jetbrains.annotations.NotNull; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.solovyev.android.calculator.CalculatorEvalException; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.jscl.JsclOperation; -import org.solovyev.common.Converter; - -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -/** - * User: serso - * Date: 12/14/11 - * Time: 4:16 PM - */ -public class NumeralBaseTest { - - @BeforeClass - public static void setUp() throws Exception { - CalculatorEngine.instance.init(null, null); - CalculatorEngine.instance.setPrecision(3); - CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); - } - - @Test - public void testConversion() throws Exception { - CSVReader reader = null; - try { - final MathEngine me = JsclMathEngine.instance; - - reader = new CSVReader(new InputStreamReader(NumeralBaseTest.class.getResourceAsStream("/org/solovyev/android/calculator/model/nb_table.csv")), '\t'); - - // skip first line - reader.readNext(); - - String[] line = reader.readNext(); - for (; line != null; line = reader.readNext()) { - testExpression(line, new DummyExpression()); - testExpression(line, new Expression1()); - testExpression(line, new Expression2()); - testExpression(line, new Expression3()); - - final String dec = line[0].toUpperCase(); - final String hex = "0x:" + line[1].toUpperCase(); - final String bin = "0b:" + line[2].toUpperCase(); - - final List input = new ArrayList(); - input.add(dec); - input.add(hex); - input.add(bin); - - //System.out.println("Dec: " + dec); - //System.out.println("Hex: " + hex); - //System.out.println("Bin: " + bin); - - final ExpressionGeneratorWithInput eg = new ExpressionGeneratorWithInput(input, 20); - final List expressions = eg.generate(); - - final String decExpression = expressions.get(0); - final String hexExpression = expressions.get(1); - final String binExpression = expressions.get(2); - - //System.out.println("Dec expression: " + decExpression); - //System.out.println("Hex expression: " + hexExpression); - //System.out.println("Bin expression: " + binExpression); - - final String decResult = Expression.valueOf(decExpression).numeric().toString(); - //System.out.println("Dec result: " + decResult); - - final String hexResult = Expression.valueOf(hexExpression).numeric().toString(); - //System.out.println("Hex result: " + hexResult); - - final String binResult = Expression.valueOf(binExpression).numeric().toString(); - //System.out.println("Bin result: " + binResult); - - Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); - Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); - } - } finally { - if (reader != null) { - reader.close(); - } - } - } - - public static void testExpression(@NotNull String[] line, @NotNull Converter converter) throws ParseException, CalculatorEvalException, CalculatorParseException { - final String dec = line[0].toUpperCase(); - final String hex = "0x:" + line[1].toUpperCase(); - final String bin = "0b:" + line[2].toUpperCase(); - - final String decExpression = converter.convert(dec); - final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getStringResult(); - final String hexExpression = converter.convert(hex); - final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getStringResult(); - final String binExpression = converter.convert(bin); - final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getStringResult(); - - Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); - Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); - } - - private static class DummyExpression implements Converter { - - @NotNull - @Override - public String convert(@NotNull String s) { - return s; - } - } - - private static class Expression1 implements Converter { - - @NotNull - @Override - public String convert(@NotNull String s) { - return s + "*" + s; - } - } - - private static class Expression2 implements Converter { - - @NotNull - @Override - public String convert(@NotNull String s) { - return s + "*" + s + " * sin(" + s + ") - 0b:1101"; - } - } - - private static class Expression3 implements Converter { - - @NotNull - @Override - public String convert(@NotNull String s) { - return s + "*" + s + " * sin(" + s + ") - 0b:1101 + √(" + s + ") + exp ( " + s + ")"; - } - } -} +package org.solovyev.android.calculator.model; + +import au.com.bytecode.opencsv.CSVReader; +import jscl.JsclMathEngine; +import jscl.MathEngine; +import jscl.math.Expression; +import jscl.text.ParseException; +import jscl.util.ExpressionGeneratorWithInput; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.common.Converter; + +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +/** + * User: serso + * Date: 12/14/11 + * Time: 4:16 PM + */ +public class NumeralBaseTest { + + @BeforeClass + public static void setUp() throws Exception { + CalculatorEngine.instance.init(null, null); + CalculatorEngine.instance.setPrecision(3); + CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); + } + + @Test + public void testConversion() throws Exception { + CSVReader reader = null; + try { + final MathEngine me = JsclMathEngine.instance; + + reader = new CSVReader(new InputStreamReader(NumeralBaseTest.class.getResourceAsStream("/org/solovyev/android/calculator/model/nb_table.csv")), '\t'); + + // skip first line + reader.readNext(); + + String[] line = reader.readNext(); + for (; line != null; line = reader.readNext()) { + testExpression(line, new DummyExpression()); + testExpression(line, new Expression1()); + testExpression(line, new Expression2()); + testExpression(line, new Expression3()); + + final String dec = line[0].toUpperCase(); + final String hex = "0x:" + line[1].toUpperCase(); + final String bin = "0b:" + line[2].toUpperCase(); + + final List input = new ArrayList(); + input.add(dec); + input.add(hex); + input.add(bin); + + //System.out.println("Dec: " + dec); + //System.out.println("Hex: " + hex); + //System.out.println("Bin: " + bin); + + final ExpressionGeneratorWithInput eg = new ExpressionGeneratorWithInput(input, 20); + final List expressions = eg.generate(); + + final String decExpression = expressions.get(0); + final String hexExpression = expressions.get(1); + final String binExpression = expressions.get(2); + + //System.out.println("Dec expression: " + decExpression); + //System.out.println("Hex expression: " + hexExpression); + //System.out.println("Bin expression: " + binExpression); + + final String decResult = Expression.valueOf(decExpression).numeric().toString(); + //System.out.println("Dec result: " + decResult); + + final String hexResult = Expression.valueOf(hexExpression).numeric().toString(); + //System.out.println("Hex result: " + hexResult); + + final String binResult = Expression.valueOf(binExpression).numeric().toString(); + //System.out.println("Bin result: " + binResult); + + Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); + Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); + } + } finally { + if (reader != null) { + reader.close(); + } + } + } + + public static void testExpression(@NotNull String[] line, @NotNull Converter converter) throws ParseException, CalculatorEvalException, CalculatorParseException { + final String dec = line[0].toUpperCase(); + final String hex = "0x:" + line[1].toUpperCase(); + final String bin = "0b:" + line[2].toUpperCase(); + + final String decExpression = converter.convert(dec); + final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getResult(); + final String hexExpression = converter.convert(hex); + final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getResult(); + final String binExpression = converter.convert(bin); + final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getResult(); + + Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); + Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); + } + + private static class DummyExpression implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s; + } + } + + private static class Expression1 implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s + "*" + s; + } + } + + private static class Expression2 implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s + "*" + s + " * sin(" + s + ") - 0b:1101"; + } + } + + private static class Expression3 implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s + "*" + s + " * sin(" + s + ") - 0b:1101 + √(" + s + ") + exp ( " + s + ")"; + } + } +} diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java index 05c4e995..c4372638 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java @@ -11,10 +11,6 @@ import jscl.NumeralBase; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.solovyev.android.calculator.CalculatorParseException; -import org.solovyev.android.calculator.PreparedExpression; -import org.solovyev.android.calculator.ToJsclTextProcessor; -import org.solovyev.android.calculator.text.TextProcessor; /** * User: serso diff --git a/pom.xml b/pom.xml index 61bbd3f4..a4352372 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,6 @@ calculatorpp calculatorpp-service calculatorpp-test - calculatorpp-core @@ -72,18 +71,6 @@ 1.0.0 - - org.solovyev - jscl - 0.0.2 - - - xercesImpl - xerces - - - - org.solovyev.android android-common-other @@ -94,13 +81,7 @@ junit junit - 4.8.2 - - - - com.intellij - annotations - 7.0.3 + 4.8.1 @@ -122,22 +103,6 @@ 11.0.2 - - org.simpleframework - simple-xml - 2.6.1 - - - stax-api - stax - - - xpp3 - xpp3 - - - -