Remove classes
This commit is contained in:
		@@ -81,9 +81,7 @@ dependencies {
 | 
			
		||||
    compile 'com.google.android.gms:play-services-base:8.4.0'
 | 
			
		||||
    compile 'com.google.android.gms:play-services-analytics:8.4.0'
 | 
			
		||||
    compile(name: 'plotter', ext: 'aar')
 | 
			
		||||
    compile('com.google.guava:guava:11.0.2') {
 | 
			
		||||
        exclude(module: 'jsr305')
 | 
			
		||||
    }
 | 
			
		||||
    compile 'com.google.guava:guava:19.0'
 | 
			
		||||
    compile('org.simpleframework:simple-xml:2.6.1') {
 | 
			
		||||
        exclude(module: 'stax-api')
 | 
			
		||||
        exclude(module: 'xpp3')
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,8 @@ import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.view.inputmethod.InputMethodManager;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.common.base.Predicate;
 | 
			
		||||
import com.google.common.base.Strings;
 | 
			
		||||
import com.squareup.otto.Bus;
 | 
			
		||||
import org.solovyev.android.Check;
 | 
			
		||||
import org.solovyev.android.calculator.floating.FloatingCalculatorService;
 | 
			
		||||
@@ -56,7 +58,6 @@ import org.solovyev.android.calculator.language.Languages;
 | 
			
		||||
import org.solovyev.android.calculator.view.ScreenMetrics;
 | 
			
		||||
import org.solovyev.android.calculator.wizard.CalculatorWizards;
 | 
			
		||||
import org.solovyev.android.wizard.Wizards;
 | 
			
		||||
import org.solovyev.common.JPredicate;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -245,19 +246,6 @@ public final class App {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static <T> T find(@Nullable List<T> list, @Nonnull JPredicate<T> finder) {
 | 
			
		||||
        if (list == null || list.isEmpty()) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0; i < list.size(); i++) {
 | 
			
		||||
            final T t = list.get(i);
 | 
			
		||||
            if (finder.apply(t)) {
 | 
			
		||||
                return t;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public static String find(@Nonnull List<String> tokens, @Nonnull String text, int position) {
 | 
			
		||||
        for (int i = 0; i < tokens.size(); i++) {
 | 
			
		||||
 
 | 
			
		||||
@@ -304,7 +304,7 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis
 | 
			
		||||
        b.withSystem(true);
 | 
			
		||||
        b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description));
 | 
			
		||||
 | 
			
		||||
        variablesRegistry.add(b.build().toJsclBuilder(), variable);
 | 
			
		||||
        variablesRegistry.addOrUpdate(b.build().toJsclConstant(), variable);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Subscribe
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
 | 
			
		||||
package org.solovyev.android.calculator;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.Iterables;
 | 
			
		||||
import jscl.math.function.Function;
 | 
			
		||||
import jscl.math.function.IConstant;
 | 
			
		||||
import org.solovyev.android.calculator.math.MathType;
 | 
			
		||||
@@ -109,11 +110,11 @@ public class ToJsclTextProcessor implements TextProcessor<PreparedExpression, St
 | 
			
		||||
            startsWithFinder.setI(i);
 | 
			
		||||
 | 
			
		||||
            int offset = 0;
 | 
			
		||||
            String functionName = App.find(MathType.function.getTokens(engine), startsWithFinder);
 | 
			
		||||
            String functionName = Iterables.find(MathType.function.getTokens(engine), startsWithFinder, null);
 | 
			
		||||
            if (functionName == null) {
 | 
			
		||||
                String operatorName = App.find(MathType.operator.getTokens(engine), startsWithFinder);
 | 
			
		||||
                String operatorName = Iterables.find(MathType.operator.getTokens(engine), startsWithFinder, null);
 | 
			
		||||
                if (operatorName == null) {
 | 
			
		||||
                    String varName = App.find(engine.getVariablesRegistry().getNames(), startsWithFinder);
 | 
			
		||||
                    String varName = Iterables.find(engine.getVariablesRegistry().getNames(), startsWithFinder, null);
 | 
			
		||||
                    if (varName != null) {
 | 
			
		||||
                        final IConstant var = engine.getVariablesRegistry().get(varName);
 | 
			
		||||
                        if (var != null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,6 @@ import org.solovyev.android.calculator.variables.CppVariable;
 | 
			
		||||
import org.solovyev.android.calculator.variables.OldVars;
 | 
			
		||||
import org.solovyev.android.calculator.variables.VariableCategory;
 | 
			
		||||
import org.solovyev.android.io.FileSaver;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -68,8 +67,8 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
 | 
			
		||||
        super(mathEngine.getConstantsRegistry(), "c_var_description_");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void add(@NonNull JBuilder<? extends IConstant> builder, @Nullable IConstant oldVariable) {
 | 
			
		||||
        final IConstant variable = add(builder);
 | 
			
		||||
    public void addOrUpdate(@Nonnull IConstant newVariable, @Nullable IConstant oldVariable) {
 | 
			
		||||
        final IConstant variable = addOrUpdate(newVariable);
 | 
			
		||||
        if (oldVariable == null) {
 | 
			
		||||
            bus.post(new AddedEvent(variable));
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -96,7 +95,7 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
 | 
			
		||||
            migrateOldVariables();
 | 
			
		||||
 | 
			
		||||
            for (CppVariable variable : loadEntities(CppVariable.JSON_CREATOR)) {
 | 
			
		||||
                addSafely(variable.toJsclBuilder());
 | 
			
		||||
                addSafely(variable.toJsclConstant());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            addSafely("x");
 | 
			
		||||
@@ -140,7 +139,7 @@ public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
 | 
			
		||||
 | 
			
		||||
    private void addSafely(@Nonnull String name) {
 | 
			
		||||
        if (!contains(name)) {
 | 
			
		||||
            addSafely(CppVariable.builder(name).build().toJsclBuilder());
 | 
			
		||||
            addSafely(CppVariable.builder(name).build().toJsclConstant());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,25 +28,22 @@ import android.content.SharedPreferences;
 | 
			
		||||
import android.content.res.Resources;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.support.annotation.NonNull;
 | 
			
		||||
 | 
			
		||||
import com.squareup.otto.Bus;
 | 
			
		||||
 | 
			
		||||
import org.json.JSONArray;
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import org.solovyev.android.Check;
 | 
			
		||||
import org.solovyev.android.calculator.App;
 | 
			
		||||
import org.solovyev.android.calculator.AppModule;
 | 
			
		||||
import org.solovyev.android.calculator.CalculatorApplication;
 | 
			
		||||
import org.solovyev.android.calculator.EntitiesRegistry;
 | 
			
		||||
import org.solovyev.android.calculator.ErrorReporter;
 | 
			
		||||
import org.solovyev.android.calculator.*;
 | 
			
		||||
import org.solovyev.android.calculator.json.Json;
 | 
			
		||||
import org.solovyev.android.calculator.json.Jsonable;
 | 
			
		||||
import org.solovyev.android.io.FileSaver;
 | 
			
		||||
import org.solovyev.android.io.FileSystem;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.math.MathEntity;
 | 
			
		||||
import org.solovyev.common.math.MathRegistry;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
import javax.inject.Named;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
@@ -55,11 +52,6 @@ import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.concurrent.Executor;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
import javax.inject.Named;
 | 
			
		||||
 | 
			
		||||
public abstract class BaseEntitiesRegistry<T extends MathEntity> implements EntitiesRegistry<T> {
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
@@ -181,8 +173,8 @@ public abstract class BaseEntitiesRegistry<T extends MathEntity> implements Enti
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public T add(@Nonnull JBuilder<? extends T> builder) {
 | 
			
		||||
        final T entity = mathRegistry.add(builder);
 | 
			
		||||
    public T addOrUpdate(@Nonnull T t) {
 | 
			
		||||
        final T entity = mathRegistry.addOrUpdate(t);
 | 
			
		||||
        if (!entity.isSystem() && isInitialized()) {
 | 
			
		||||
            save();
 | 
			
		||||
        }
 | 
			
		||||
@@ -190,9 +182,9 @@ public abstract class BaseEntitiesRegistry<T extends MathEntity> implements Enti
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    protected T addSafely(@Nonnull JBuilder<? extends T> builder) {
 | 
			
		||||
    protected T addSafely(@Nonnull T entity) {
 | 
			
		||||
        try {
 | 
			
		||||
            return add(builder);
 | 
			
		||||
            return addOrUpdate(entity);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            errorReporter.onException(e);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,26 +4,21 @@ import android.os.Parcel;
 | 
			
		||||
import android.os.Parcelable;
 | 
			
		||||
import android.support.annotation.NonNull;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
 | 
			
		||||
import jscl.math.function.CustomFunction;
 | 
			
		||||
import jscl.math.function.IFunction;
 | 
			
		||||
import org.json.JSONArray;
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
import org.solovyev.android.Check;
 | 
			
		||||
import org.solovyev.android.calculator.json.Json;
 | 
			
		||||
import org.solovyev.android.calculator.json.Jsonable;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.text.Strings;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
import jscl.math.function.CustomFunction;
 | 
			
		||||
import jscl.math.function.Function;
 | 
			
		||||
import jscl.math.function.IFunction;
 | 
			
		||||
 | 
			
		||||
import static java.util.Arrays.asList;
 | 
			
		||||
 | 
			
		||||
public class CppFunction implements Jsonable, Parcelable {
 | 
			
		||||
@@ -185,7 +180,7 @@ public class CppFunction implements Jsonable, Parcelable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public JBuilder<? extends Function> toJsclBuilder() {
 | 
			
		||||
    public CustomFunction.Builder toJsclBuilder() {
 | 
			
		||||
        final CustomFunction.Builder builder = new CustomFunction.Builder(name, parameters, body);
 | 
			
		||||
        builder.setDescription(description);
 | 
			
		||||
        if (id != NO_ID) {
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ public class EditFunctionFragment extends BaseFunctionFragment {
 | 
			
		||||
    protected boolean applyData(@Nonnull @NonNull CppFunction function) {
 | 
			
		||||
        try {
 | 
			
		||||
            final Function oldFunction = isNewFunction() ? null : functionsRegistry.getById(function.id);
 | 
			
		||||
            functionsRegistry.add(function.toJsclBuilder(), oldFunction);
 | 
			
		||||
            functionsRegistry.addOrUpdate(function.toJsclBuilder().create(), oldFunction);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (RuntimeException e) {
 | 
			
		||||
            setError(bodyLabel, e.getLocalizedMessage());
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,6 @@ import org.solovyev.android.calculator.entities.Entities;
 | 
			
		||||
import org.solovyev.android.calculator.json.Json;
 | 
			
		||||
import org.solovyev.android.calculator.json.Jsonable;
 | 
			
		||||
import org.solovyev.android.io.FileSaver;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.text.Strings;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -63,8 +62,8 @@ public class FunctionsRegistry extends BaseEntitiesRegistry<Function> {
 | 
			
		||||
        super(mathEngine.getFunctionsRegistry(), "c_fun_description_");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void add(@NonNull JBuilder<? extends Function> builder, @Nullable Function oldFunction) {
 | 
			
		||||
        final Function function = add(builder);
 | 
			
		||||
    public void addOrUpdate(@Nonnull Function newFunction, @Nullable Function oldFunction) {
 | 
			
		||||
        final Function function = addOrUpdate(newFunction);
 | 
			
		||||
        if (oldFunction == null) {
 | 
			
		||||
            bus.post(new AddedEvent(function));
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -92,6 +91,15 @@ public class FunctionsRegistry extends BaseEntitiesRegistry<Function> {
 | 
			
		||||
            setInitialized();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    @Nullable
 | 
			
		||||
    protected Function addSafely(@Nonnull CustomFunction.Builder builder) {
 | 
			
		||||
        try {
 | 
			
		||||
            return addSafely(builder.create());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            errorReporter.onException(e);
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void remove(@Nonnull Function function) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.android.calculator.model;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.math.MathEntity;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User: serso
 | 
			
		||||
 * Date: 12/22/11
 | 
			
		||||
 * Time: 9:21 PM
 | 
			
		||||
 */
 | 
			
		||||
public interface MathEntityBuilder<T extends MathEntity> extends JBuilder<T> {
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    MathEntityBuilder<T> setName(@Nonnull String name);
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    MathEntityBuilder<T> setDescription(@Nullable String description);
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    MathEntityBuilder<T> setValue(@Nullable String value);
 | 
			
		||||
}
 | 
			
		||||
@@ -11,7 +11,6 @@ import org.solovyev.android.Check;
 | 
			
		||||
import org.solovyev.android.calculator.functions.CppFunction;
 | 
			
		||||
import org.solovyev.android.calculator.json.Json;
 | 
			
		||||
import org.solovyev.android.calculator.json.Jsonable;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
@@ -114,14 +113,8 @@ public class CppVariable implements Jsonable, Parcelable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public JBuilder<? extends IConstant> toJsclBuilder() {
 | 
			
		||||
        return new JBuilder<IConstant>() {
 | 
			
		||||
            @Nonnull
 | 
			
		||||
            @Override
 | 
			
		||||
            public IConstant create() {
 | 
			
		||||
                return new JsclConstant(CppVariable.this);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    public IConstant toJsclConstant() {
 | 
			
		||||
        return new JsclConstant(CppVariable.this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -198,7 +198,7 @@ public class EditVariableFragment extends BaseDialogFragment implements View.OnF
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
                        Check.isTrue(which == DialogInterface.BUTTON_POSITIVE);
 | 
			
		||||
                        variablesRegistry.remove(variable.toJsclBuilder().create());
 | 
			
		||||
                        variablesRegistry.remove(variable.toJsclConstant());
 | 
			
		||||
                        dismiss();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
@@ -217,7 +217,7 @@ public class EditVariableFragment extends BaseDialogFragment implements View.OnF
 | 
			
		||||
                    .withValue(valueView.getText().toString())
 | 
			
		||||
                    .withDescription(descriptionView.getText().toString()).build();
 | 
			
		||||
            final IConstant oldVariable = isNewVariable() ? null : variablesRegistry.getById(variable.id);
 | 
			
		||||
            variablesRegistry.add(newVariable.toJsclBuilder(), oldVariable);
 | 
			
		||||
            variablesRegistry.addOrUpdate(newVariable.toJsclConstant(), oldVariable);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (RuntimeException e) {
 | 
			
		||||
            setError(valueLabel, e.getLocalizedMessage());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,240 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.android.prefs;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.preference.DialogPreference;
 | 
			
		||||
import android.util.AttributeSet;
 | 
			
		||||
import android.view.Gravity;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.solovyev.common.Objects;
 | 
			
		||||
import org.solovyev.common.text.Mapper;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for creating preferences with dialogs
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T>
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractDialogPreference<T> extends DialogPreference {
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    protected final static String localNameSpace = "http://schemas.android.com/apk/res-auto";
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    protected final static String androidns = "http://schemas.android.com/apk/res/android";
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private static final String TAG = AbstractDialogPreference.class.getSimpleName();
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private final Context context;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private final String defaultStringValue;
 | 
			
		||||
    private final boolean needValueText;
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private final Mapper<T> mapper;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private TextView valueTextView;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private String valueText;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private View preferenceView;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private String description;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private T value;
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private T defaultValue;
 | 
			
		||||
 | 
			
		||||
    public AbstractDialogPreference(Context context, AttributeSet attrs, @Nullable String defaultStringValue, boolean needValueText, @Nonnull Mapper<T> mapper) {
 | 
			
		||||
        super(context, attrs);
 | 
			
		||||
        this.context = context;
 | 
			
		||||
        this.defaultStringValue = defaultStringValue;
 | 
			
		||||
        this.needValueText = needValueText;
 | 
			
		||||
        this.mapper = mapper;
 | 
			
		||||
 | 
			
		||||
        final String defaultValueFromAttrs = attrs.getAttributeValue(androidns, "defaultValue");
 | 
			
		||||
        if (defaultValueFromAttrs != null) {
 | 
			
		||||
            defaultValue = getMapper().parseValue(defaultValueFromAttrs);
 | 
			
		||||
        } else if (defaultStringValue != null) {
 | 
			
		||||
            defaultValue = getMapper().parseValue(defaultStringValue);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new IllegalArgumentException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        description = attrs.getAttributeValue(androidns, "dialogMessage");
 | 
			
		||||
        valueText = attrs.getAttributeValue(androidns, "text");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    protected View getPreferenceView() {
 | 
			
		||||
        return preferenceView;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public T getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setValue(@Nullable T value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    protected final LinearLayout onCreateDialogView() {
 | 
			
		||||
        if (shouldPersist()) {
 | 
			
		||||
            value = getPersistedValue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final LinearLayout result = new LinearLayout(context);
 | 
			
		||||
        result.setOrientation(LinearLayout.VERTICAL);
 | 
			
		||||
        result.setPadding(6, 6, 6, 6);
 | 
			
		||||
 | 
			
		||||
        if (description != null) {
 | 
			
		||||
            final TextView splashText = new TextView(context);
 | 
			
		||||
            splashText.setText(description);
 | 
			
		||||
            result.addView(splashText);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (needValueText) {
 | 
			
		||||
            valueTextView = new TextView(context);
 | 
			
		||||
            valueTextView.setGravity(Gravity.CENTER_HORIZONTAL);
 | 
			
		||||
            valueTextView.setTextSize(32);
 | 
			
		||||
 | 
			
		||||
            final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
 | 
			
		||||
                    LinearLayout.LayoutParams.MATCH_PARENT,
 | 
			
		||||
                    LinearLayout.LayoutParams.WRAP_CONTENT);
 | 
			
		||||
            result.addView(valueTextView, params);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        preferenceView = createPreferenceView(context);
 | 
			
		||||
        initPreferenceView(preferenceView, value);
 | 
			
		||||
 | 
			
		||||
        final LinearLayout.LayoutParams params = getParams();
 | 
			
		||||
        if (params != null) {
 | 
			
		||||
            result.addView(preferenceView, params);
 | 
			
		||||
        } else {
 | 
			
		||||
            result.addView(preferenceView);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    protected abstract LinearLayout.LayoutParams getParams();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onSetInitialValue(boolean restore, Object defaultValue) {
 | 
			
		||||
        super.onSetInitialValue(restore, defaultValue);
 | 
			
		||||
 | 
			
		||||
        if (restore) {
 | 
			
		||||
            if (shouldPersist()) {
 | 
			
		||||
                value = getPersistedValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                value = this.defaultValue;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            value = (T) defaultValue;
 | 
			
		||||
            if (shouldPersist()) {
 | 
			
		||||
                persist(this.value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onBindDialogView(View v) {
 | 
			
		||||
        super.onBindDialogView(v);
 | 
			
		||||
        if (this.preferenceView != null) {
 | 
			
		||||
            initPreferenceView(this.preferenceView, value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates view which is responsible for changing preference value (for example, Spinner or EditText)
 | 
			
		||||
     *
 | 
			
		||||
     * @param context context
 | 
			
		||||
     * @return view which changes the preference value
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    protected abstract View createPreferenceView(@Nonnull Context context);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param v     view to be filled with initial data (the one which has been created with {@link #createPreferenceView} method)
 | 
			
		||||
     * @param value current preference value
 | 
			
		||||
     */
 | 
			
		||||
    protected abstract void initPreferenceView(@Nonnull View v, @Nullable T value);
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private T getPersistedValue() {
 | 
			
		||||
        String persistedString = getPersistedString(defaultStringValue);
 | 
			
		||||
 | 
			
		||||
        if (Objects.areEqual(persistedString, defaultStringValue)) {
 | 
			
		||||
            return defaultValue;
 | 
			
		||||
        } else {
 | 
			
		||||
            return getMapper().parseValue(persistedString);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void persistValue(@Nullable T value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
        if (!callChangeListener(value)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (!shouldPersist()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        persist(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void persist(@Nullable T value) {
 | 
			
		||||
        if (value != null) {
 | 
			
		||||
            final String toBePersistedString = getMapper().formatValue(value);
 | 
			
		||||
            if (toBePersistedString != null) {
 | 
			
		||||
                if (callChangeListener(toBePersistedString)) {
 | 
			
		||||
                    persistString(toBePersistedString);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public String getValueText() {
 | 
			
		||||
        return valueText;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void updateValueText(@Nonnull String text) {
 | 
			
		||||
        if (valueTextView != null) {
 | 
			
		||||
            valueTextView.setText(text);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    private Mapper<T> getMapper() {
 | 
			
		||||
        return this.mapper;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,114 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.android.prefs;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.util.AttributeSet;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.SeekBar;
 | 
			
		||||
import org.solovyev.common.text.NumberMapper;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* The following code was written by Matthew Wiggins
 | 
			
		||||
 * and is released under the APACHE 2.0 license
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class SeekBarPreference extends AbstractDialogPreference<Integer> implements SeekBar.OnSeekBarChangeListener {
 | 
			
		||||
 | 
			
		||||
    private int max = 0;
 | 
			
		||||
 | 
			
		||||
    public SeekBarPreference(Context context, AttributeSet attrs) {
 | 
			
		||||
        super(context, attrs, "50", true, NumberMapper.of(Integer.class));
 | 
			
		||||
 | 
			
		||||
        max = attrs.getAttributeIntValue(androidns, "max", 100);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected LinearLayout.LayoutParams getParams() {
 | 
			
		||||
        return new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    protected View createPreferenceView(@Nonnull Context context) {
 | 
			
		||||
        final SeekBar result = new SeekBar(context);
 | 
			
		||||
 | 
			
		||||
        result.setOnSeekBarChangeListener(this);
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void initPreferenceView(@Nonnull View v, Integer value) {
 | 
			
		||||
        ((SeekBar) v).setMax(max);
 | 
			
		||||
        if (value != null) {
 | 
			
		||||
            ((SeekBar) v).setProgress(value);
 | 
			
		||||
            setValueText(value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
 | 
			
		||||
        setValueText(value);
 | 
			
		||||
 | 
			
		||||
        persistValue(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setValueText(int value) {
 | 
			
		||||
        String t = String.valueOf(value);
 | 
			
		||||
        final String valueText = getValueText();
 | 
			
		||||
        updateValueText(valueText == null ? t : t.concat(valueText));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onStartTrackingTouch(SeekBar seek) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void onStopTrackingTouch(SeekBar seek) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getMax() {
 | 
			
		||||
        return max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMax(int max) {
 | 
			
		||||
        this.max = max;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getProgress() {
 | 
			
		||||
        final Integer value = getValue();
 | 
			
		||||
        return value == null ? 0 : value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setProgress(int progress) {
 | 
			
		||||
        setValue(progress);
 | 
			
		||||
        final View preferenceView = getPreferenceView();
 | 
			
		||||
        if (preferenceView != null) {
 | 
			
		||||
            ((SeekBar) preferenceView).setProgress(progress);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -48,15 +48,15 @@ public class FromJsclSimplifyTextProcessorTest {
 | 
			
		||||
        //Assert.assertEquals("e", tp.process("2.718281828459045"));
 | 
			
		||||
        //Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045"));
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("t2.718281828459045", 2).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t2.718281828459045", 2).build().toJsclConstant());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t").build().toJsclConstant());
 | 
			
		||||
        //Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045"));
 | 
			
		||||
        //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045"));
 | 
			
		||||
        assertEquals("t×", tp.process("t*"));
 | 
			
		||||
        assertEquals("×t", tp.process("*t"));
 | 
			
		||||
        assertEquals("t2", tp.process("t*2"));
 | 
			
		||||
        assertEquals("2t", tp.process("2*t"));
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t").build().toJsclConstant());
 | 
			
		||||
        assertEquals("t×", tp.process("t*"));
 | 
			
		||||
        assertEquals("×t", tp.process("*t"));
 | 
			
		||||
 | 
			
		||||
@@ -69,7 +69,7 @@ public class FromJsclSimplifyTextProcessorTest {
 | 
			
		||||
        assertEquals("t^[2×2t]", tp.process("t^[2*2*t]"));
 | 
			
		||||
        assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]"));
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("k").build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("k").build().toJsclConstant());
 | 
			
		||||
        assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]"));
 | 
			
		||||
        assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]"));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -123,7 +123,7 @@ public class AndroidEngineTest extends BaseCalculatorTest {
 | 
			
		||||
            me.setAngleUnits(defaultAngleUnit);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("si").withValue(5d).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("si").withValue(5d).build().toJsclConstant());
 | 
			
		||||
        assertEval("5", me.evaluate("si"));
 | 
			
		||||
 | 
			
		||||
        assertError("sin");
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ public class EvaluateTest extends BaseCalculatorTest {
 | 
			
		||||
        assertError("(-1)i!");
 | 
			
		||||
        assertEval("24i", "4!i");
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("si", 5d).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("si", 5d).build().toJsclConstant());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            cm.setAngleUnits(AngleUnit.rad);
 | 
			
		||||
@@ -121,14 +121,14 @@ public class EvaluateTest extends BaseCalculatorTest {
 | 
			
		||||
            cm.setAngleUnits(defaultAngleUnit);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("s", 1d).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("s", 1d).build().toJsclConstant());
 | 
			
		||||
        assertEval("5", cm.evaluate("si"));
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("k", 3.5d).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("k1", 4d).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("k", 3.5d).build().toJsclConstant());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("k1", 4d).build().toJsclConstant());
 | 
			
		||||
        assertEval("4", "k11");
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t").build().toJsclConstant());
 | 
			
		||||
        assertEval("11t", "t11");
 | 
			
		||||
        assertEval("11et", "t11e");
 | 
			
		||||
        assertEval("∞", "∞");
 | 
			
		||||
@@ -174,10 +174,10 @@ public class EvaluateTest extends BaseCalculatorTest {
 | 
			
		||||
			cm.setTimeout(3000);
 | 
			
		||||
		}*/
 | 
			
		||||
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("t").build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t").build().toJsclConstant());
 | 
			
		||||
        assertEval("2t", "∂(t^2,t)", JsclOperation.simplify);
 | 
			
		||||
        assertEval("2t", "∂(t^2,t)");
 | 
			
		||||
        engine.getVariablesRegistry().add(CppVariable.builder("t", 2d).build().toJsclBuilder());
 | 
			
		||||
        engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t", 2d).build().toJsclConstant());
 | 
			
		||||
        assertEval("2t", "∂(t^2,t)", JsclOperation.simplify);
 | 
			
		||||
        assertEval("4", "∂(t^2,t)");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
package org.solovyev.android.calculator.model;
 | 
			
		||||
 | 
			
		||||
import au.com.bytecode.opencsv.CSVReader;
 | 
			
		||||
import com.google.common.base.Function;
 | 
			
		||||
import jscl.JsclMathEngine;
 | 
			
		||||
import jscl.MathEngine;
 | 
			
		||||
import jscl.math.Expression;
 | 
			
		||||
@@ -32,7 +33,6 @@ import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.solovyev.android.calculator.BaseCalculatorTest;
 | 
			
		||||
import org.solovyev.android.calculator.ParseException;
 | 
			
		||||
import org.solovyev.common.Converter;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
@@ -47,16 +47,16 @@ public class NumeralBaseTest extends BaseCalculatorTest {
 | 
			
		||||
        engine.getMathEngine().setPrecision(3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void testExpression(@Nonnull String[] line, @Nonnull Converter<String, String> converter) throws jscl.text.ParseException, ParseException {
 | 
			
		||||
    public void testExpression(@Nonnull String[] line, @Nonnull Function<String, String> converter) throws jscl.text.ParseException, ParseException {
 | 
			
		||||
        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 decExpression = converter.apply(dec);
 | 
			
		||||
        final String decResult = engine.getMathEngine().evaluate(decExpression);
 | 
			
		||||
        final String hexExpression = converter.convert(hex);
 | 
			
		||||
        final String hexExpression = converter.apply(hex);
 | 
			
		||||
        final String hexResult = engine.getMathEngine().evaluate(hexExpression);
 | 
			
		||||
        final String binExpression = converter.convert(bin);
 | 
			
		||||
        final String binExpression = converter.apply(bin);
 | 
			
		||||
        final String binResult = engine.getMathEngine().evaluate(binExpression);
 | 
			
		||||
 | 
			
		||||
        Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult);
 | 
			
		||||
@@ -124,38 +124,38 @@ public class NumeralBaseTest extends BaseCalculatorTest {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class DummyExpression implements Converter<String, String> {
 | 
			
		||||
    private static class DummyExpression implements Function<String, String> {
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public String convert(@Nonnull String s) {
 | 
			
		||||
        public String apply(@Nonnull String s) {
 | 
			
		||||
            return s;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class Expression1 implements Converter<String, String> {
 | 
			
		||||
    private static class Expression1 implements Function<String, String> {
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public String convert(@Nonnull String s) {
 | 
			
		||||
        public String apply(@Nonnull String s) {
 | 
			
		||||
            return s + "*" + s;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class Expression2 implements Converter<String, String> {
 | 
			
		||||
    private static class Expression2 implements Function<String, String> {
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public String convert(@Nonnull String s) {
 | 
			
		||||
        public String apply(@Nonnull String s) {
 | 
			
		||||
            return s + "*" + s + " * sin(" + s + ") - 0b:1101";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class Expression3 implements Converter<String, String> {
 | 
			
		||||
    private static class Expression3 implements Function<String, String> {
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public String convert(@Nonnull String s) {
 | 
			
		||||
        public String apply(@Nonnull String s) {
 | 
			
		||||
            return s + "*" + s + " * sin(" + s + ") - 0b:1101 + √(" + s + ") + exp ( " + s + ")";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,27 +22,18 @@
 | 
			
		||||
 | 
			
		||||
package org.solovyev.android.calculator.model;
 | 
			
		||||
 | 
			
		||||
import org.hamcrest.BaseMatcher;
 | 
			
		||||
import org.hamcrest.Description;
 | 
			
		||||
import jscl.util.ExpressionGenerator;
 | 
			
		||||
import org.junit.Assert;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.simpleframework.xml.Serializer;
 | 
			
		||||
import org.simpleframework.xml.core.Persister;
 | 
			
		||||
import org.solovyev.android.calculator.functions.OldFunction;
 | 
			
		||||
import org.solovyev.android.calculator.functions.OldFunctions;
 | 
			
		||||
import org.solovyev.common.Objects;
 | 
			
		||||
import org.solovyev.common.equals.CollectionEqualizer;
 | 
			
		||||
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
import jscl.util.ExpressionGenerator;
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User: serso
 | 
			
		||||
@@ -138,21 +129,4 @@ public class OldFunctionsTest {
 | 
			
		||||
        testXml(in, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void assertEquals(@Nonnull final OldFunction expected,
 | 
			
		||||
                              @Nonnull OldFunction actual) {
 | 
			
		||||
        //Assert.assertEquals(expected.getId(), actual.getId());
 | 
			
		||||
        Assert.assertEquals(expected.content, actual.content);
 | 
			
		||||
        Assert.assertEquals(expected.description, actual.description);
 | 
			
		||||
        Assert.assertEquals(expected.name, actual.name);
 | 
			
		||||
        Assert.assertThat(actual.parameterNames, new BaseMatcher<List<String>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean matches(Object item) {
 | 
			
		||||
                return Objects.areEqual(expected.parameterNames, (List<String>) item, new CollectionEqualizer<String>(null));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void describeTo(Description description) {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ dependencies {
 | 
			
		||||
    compile fileTree(include: ['*.jar'], dir: 'libs')
 | 
			
		||||
    compile 'com.google.code.findbugs:annotations:2.0.1'
 | 
			
		||||
    compile 'xerces:xercesImpl:2.8.0'
 | 
			
		||||
    compile 'com.google.guava:guava:19.0'
 | 
			
		||||
 | 
			
		||||
    testCompile 'junit:junit:4.12'
 | 
			
		||||
    testCompile 'net.sf.opencsv:opencsv:2.0'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package jscl.math;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.Converter;
 | 
			
		||||
 | 
			
		||||
import jscl.math.function.Constant;
 | 
			
		||||
import jscl.math.function.Fraction;
 | 
			
		||||
import jscl.math.function.Inverse;
 | 
			
		||||
@@ -16,38 +14,33 @@ import jscl.text.ParserUtils;
 | 
			
		||||
import jscl.text.msg.Messages;
 | 
			
		||||
import jscl.util.ArrayUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class Expression extends Generic {
 | 
			
		||||
 | 
			
		||||
    protected static final Converter<Variable, Generic> FACTORIZE_CONVERTER = new Converter<Variable, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Variable, Generic> FACTORIZE_CONVERTER = new com.google.common.base.Function<Variable, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        public Generic convert(@Nonnull Variable variable) {
 | 
			
		||||
        public Generic apply(@Nonnull Variable variable) {
 | 
			
		||||
            return variable.factorize();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    protected static final Converter<Variable, Generic> ELEMENTARY_CONVERTER = new Converter<Variable, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Variable, Generic> ELEMENTARY_CONVERTER = new com.google.common.base.Function<Variable, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        public Generic convert(@Nonnull Variable variable) {
 | 
			
		||||
        public Generic apply(@Nonnull Variable variable) {
 | 
			
		||||
            return variable.elementary();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    protected static final Converter<Variable, Generic> EXPAND_CONVERTER = new Converter<Variable, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Variable, Generic> EXPAND_CONVERTER = new com.google.common.base.Function<Variable, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        public Generic convert(@Nonnull Variable variable) {
 | 
			
		||||
        public Generic apply(@Nonnull Variable variable) {
 | 
			
		||||
            return variable.expand();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    protected static final Converter<Variable, Generic> NUMERIC_CONVERTER = new Converter<Variable, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Variable, Generic> NUMERIC_CONVERTER = new com.google.common.base.Function<Variable, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        public Generic convert(@Nonnull Variable variable) {
 | 
			
		||||
        public Generic apply(@Nonnull Variable variable) {
 | 
			
		||||
            return variable.numeric();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
@@ -495,9 +488,9 @@ public class Expression extends Generic {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Generic substitute(@Nonnull final Variable variable, final Generic generic) {
 | 
			
		||||
        final Map<Variable, Generic> content = literalScm().content(new Converter<Variable, Generic>() {
 | 
			
		||||
        final Map<Variable, Generic> content = literalScm().content(new com.google.common.base.Function<Variable, Generic>() {
 | 
			
		||||
            @Nonnull
 | 
			
		||||
            public Generic convert(@Nonnull Variable v) {
 | 
			
		||||
            public Generic apply(@Nonnull Variable v) {
 | 
			
		||||
                return v.substitute(variable, generic);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
package jscl.math;
 | 
			
		||||
 | 
			
		||||
import com.google.common.base.Function;
 | 
			
		||||
import jscl.math.function.Fraction;
 | 
			
		||||
import jscl.math.function.Pow;
 | 
			
		||||
import jscl.math.polynomial.Monomial;
 | 
			
		||||
import jscl.mathml.MathML;
 | 
			
		||||
import org.solovyev.common.Converter;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
@@ -381,11 +381,11 @@ public class Literal implements Comparable {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Map<Variable, Generic> content(@Nonnull Converter<Variable, Generic> c) {
 | 
			
		||||
    Map<Variable, Generic> content(@Nonnull Function<Variable, Generic> c) {
 | 
			
		||||
        final Map<Variable, Generic> result = new TreeMap<Variable, Generic>();
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < size; i++) {
 | 
			
		||||
            result.put(variables[i], c.convert(variables[i]));
 | 
			
		||||
            result.put(variables[i], c.apply(variables[i]));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ import jscl.math.operator.Factorial;
 | 
			
		||||
import jscl.math.operator.Operator;
 | 
			
		||||
import jscl.mathml.MathML;
 | 
			
		||||
import jscl.text.ParseException;
 | 
			
		||||
import org.solovyev.common.Converter;
 | 
			
		||||
import org.solovyev.common.math.MathEntity;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -19,31 +18,31 @@ public abstract class Variable implements Comparable, MathEntity {
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static final Comparator<Variable> comparator = VariableComparator.comparator;
 | 
			
		||||
    protected static final Converter<Generic, Generic> FACTORIZE_CONVERTER = new Converter<Generic, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Generic, Generic> FACTORIZE_CONVERTER = new com.google.common.base.Function<Generic, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Generic convert(@Nonnull Generic generic) {
 | 
			
		||||
        public Generic apply(@Nonnull Generic generic) {
 | 
			
		||||
            return generic.factorize();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    protected static final Converter<Generic, Generic> ELEMENTARY_CONVERTER = new Converter<Generic, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Generic, Generic> ELEMENTARY_CONVERTER = new com.google.common.base.Function<Generic, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Generic convert(@Nonnull Generic generic) {
 | 
			
		||||
        public Generic apply(@Nonnull Generic generic) {
 | 
			
		||||
            return generic.elementary();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    protected static final Converter<Generic, Generic> EXPAND_CONVERTER = new Converter<Generic, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Generic, Generic> EXPAND_CONVERTER = new com.google.common.base.Function<Generic, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Generic convert(@Nonnull Generic generic) {
 | 
			
		||||
        public Generic apply(@Nonnull Generic generic) {
 | 
			
		||||
            return generic.expand();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    protected static final Converter<Generic, Generic> NUMERIC_CONVERTER = new Converter<Generic, Generic>() {
 | 
			
		||||
    protected static final com.google.common.base.Function<Generic, Generic> NUMERIC_CONVERTER = new com.google.common.base.Function<Generic, Generic>() {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Generic convert(@Nonnull Generic generic) {
 | 
			
		||||
        public Generic apply(@Nonnull Generic generic) {
 | 
			
		||||
            return generic.numeric();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,10 @@ import jscl.JsclMathEngine;
 | 
			
		||||
import jscl.math.*;
 | 
			
		||||
import jscl.mathml.MathML;
 | 
			
		||||
import jscl.util.ArrayComparator;
 | 
			
		||||
import org.solovyev.common.HashCodeBuilder;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class Constant extends Variable {
 | 
			
		||||
@@ -148,14 +148,7 @@ public class Constant extends Variable {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        final HashCodeBuilder result = HashCodeBuilder.newInstance();
 | 
			
		||||
 | 
			
		||||
        result.append(Constant.class);
 | 
			
		||||
        result.append(name);
 | 
			
		||||
        result.append(subscripts);
 | 
			
		||||
        result.append(prime);
 | 
			
		||||
 | 
			
		||||
        return result.toHashCode();
 | 
			
		||||
        return Objects.hash(Constant.class, name, subscripts, prime);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toString() {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,6 @@ package jscl.math.function;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.math.AbstractMathRegistry;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User: serso
 | 
			
		||||
 * Date: 11/7/11
 | 
			
		||||
 * Time: 11:59 AM
 | 
			
		||||
 */
 | 
			
		||||
public class ConstantsRegistry extends AbstractMathRegistry<IConstant> {
 | 
			
		||||
 | 
			
		||||
    public static final String E = "e";
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ import jscl.CustomFunctionCalculationException;
 | 
			
		||||
import jscl.JsclMathEngine;
 | 
			
		||||
import jscl.math.*;
 | 
			
		||||
import jscl.text.ParseException;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.math.MathEntity;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -211,7 +210,7 @@ public class CustomFunction extends Function implements IFunction {
 | 
			
		||||
        return new CustomFunction(name, parameterNames, content, description);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Builder implements JBuilder<CustomFunction> {
 | 
			
		||||
    public static class Builder {
 | 
			
		||||
 | 
			
		||||
        private final boolean system;
 | 
			
		||||
 | 
			
		||||
@@ -320,7 +319,6 @@ public class CustomFunction extends Function implements IFunction {
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        public CustomFunction create() throws CustomFunctionCalculationException {
 | 
			
		||||
            final CustomFunction customFunction = new CustomFunction(name, parameterNames, prepareContent(content), description);
 | 
			
		||||
            customFunction.setSystem(system);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package jscl.math.function;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.math.MathEntity;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -176,7 +175,7 @@ public class ExtendedConstant implements Comparable<ExtendedConstant>, IConstant
 | 
			
		||||
        return this.constant.compareTo(o.getConstant());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final class Builder implements JBuilder<ExtendedConstant> {
 | 
			
		||||
    public static final class Builder {
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        private Constant constant;
 | 
			
		||||
 | 
			
		||||
@@ -209,7 +208,6 @@ public class ExtendedConstant implements Comparable<ExtendedConstant>, IConstant
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Nonnull
 | 
			
		||||
        @Override
 | 
			
		||||
        public ExtendedConstant create() {
 | 
			
		||||
            final ExtendedConstant result = new ExtendedConstant();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface converts one object to another
 | 
			
		||||
 *
 | 
			
		||||
 * @param <FROM> type of object to be converted
 | 
			
		||||
 * @param <TO>   type of result object (converted object)
 | 
			
		||||
 */
 | 
			
		||||
public interface Converter<FROM, TO> {
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    TO convert(@Nonnull FROM from);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.equals.Equalizer;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
public class EqualsResult<T> {
 | 
			
		||||
 | 
			
		||||
    public static final Integer BOTH_NULLS_CONST = 0;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private final Integer result;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private final T o1;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private final T o2;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private final Equalizer<? super T> equalizer;
 | 
			
		||||
 | 
			
		||||
    EqualsResult(@Nullable T o1, @Nullable T o2, @Nullable Equalizer<? super T> equalizer) {
 | 
			
		||||
        this.equalizer = equalizer;
 | 
			
		||||
        if (o1 == null && o2 == null) {
 | 
			
		||||
            result = EqualsResult.BOTH_NULLS_CONST;
 | 
			
		||||
        } else if (o1 == null) {
 | 
			
		||||
            result = -1;
 | 
			
		||||
        } else if (o2 == null) {
 | 
			
		||||
            result = 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            //both not nulls
 | 
			
		||||
            result = null;
 | 
			
		||||
        }
 | 
			
		||||
        this.o1 = o1;
 | 
			
		||||
        this.o2 = o2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public Integer getResult() {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean areBothNotNulls() {
 | 
			
		||||
        return result == null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean areBothNulls() {
 | 
			
		||||
        return result != null && result.equals(BOTH_NULLS_CONST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean areEqual() {
 | 
			
		||||
        //noinspection ConstantConditions
 | 
			
		||||
        boolean areSame = o1 == o2;
 | 
			
		||||
        return areBothNulls() || areSame || (areBothNotNulls() && (equalizer == null ? o1.equals(o2) : equalizer.areEqual(o1, o2)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,550 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Assists in implementing {@link Object#hashCode()} methods.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This class enables a good <code>hashCode</code> method to be built for any class. It follows the rules laid out in
 | 
			
		||||
 * the book <a href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a> by Joshua Bloch. Writing a
 | 
			
		||||
 * good <code>hashCode</code> method is actually quite difficult. This class aims to simplify the process.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * All relevant fields from the object should be included in the <code>hashCode</code> method. Derived fields may be
 | 
			
		||||
 * excluded. In general, any field used in the <code>equals</code> method must be used in the <code>hashCode</code>
 | 
			
		||||
 * method.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * To use this class write code as follows:
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public class Person {
 | 
			
		||||
 *   String name;
 | 
			
		||||
 *   int age;
 | 
			
		||||
 *   boolean smoker;
 | 
			
		||||
 *   ...
 | 
			
		||||
 *
 | 
			
		||||
 *   public int hashCode() {
 | 
			
		||||
 * 	// you pick a hard-coded, randomly chosen, non-zero, odd number
 | 
			
		||||
 * 	// ideally different for each class
 | 
			
		||||
 *     return new HashCodeBuilder(17, 37).
 | 
			
		||||
 *       append(name).
 | 
			
		||||
 *       append(age).
 | 
			
		||||
 *       append(smoker).
 | 
			
		||||
 *       toHashCode();
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * If required, the superclass <code>hashCode()</code> can be added using {@link #appendSuper}.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Alternatively, there is a method that uses reflection to determine the fields to test. Because these fields are
 | 
			
		||||
 * usually private, the method, <code>reflectionHashCode</code>, uses <code>AccessibleObject.setAccessible</code>
 | 
			
		||||
 * to change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions
 | 
			
		||||
 * are set up correctly. It is also slower than testing explicitly.
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <p>
 | 
			
		||||
 * A typical invocation for this method would look like:
 | 
			
		||||
 * </p>
 | 
			
		||||
 * <p/>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public int hashCode() {
 | 
			
		||||
 *   return HashCodeBuilder.reflectionHashCode(this);
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Apache Software Foundation
 | 
			
		||||
 * @author Gary Gregory
 | 
			
		||||
 * @author Pete Gieser
 | 
			
		||||
 * @author Sergey Solovyev
 | 
			
		||||
 * @version $Id: HashCodeBuilder.java 907376 2010-02-07 03:43:02Z mbenson $
 | 
			
		||||
 * @since 1.0
 | 
			
		||||
 */
 | 
			
		||||
public class HashCodeBuilder {
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*
 | 
			
		||||
	*                           FIELDS
 | 
			
		||||
	*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constant to use in building the hashCode.
 | 
			
		||||
	 */
 | 
			
		||||
	private final int constant;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Running total of the hashCode.
 | 
			
		||||
	 */
 | 
			
		||||
	private int total = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*
 | 
			
		||||
	*                           CONSTRUCTORS
 | 
			
		||||
	*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Uses two hard coded choices for the constants needed to build a <code>hashCode</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 */
 | 
			
		||||
	private HashCodeBuilder() {
 | 
			
		||||
		constant = 37;
 | 
			
		||||
		total = 17;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Two randomly chosen, non-zero, odd numbers must be passed in. Ideally these should be different for each class,
 | 
			
		||||
	 * however this is not vital.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 * <p/>
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Prime numbers are preferred, especially for the multiplier.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param initialNonZeroOddNumber    a non-zero, odd number used as the initial value
 | 
			
		||||
	 * @param multiplierNonZeroOddNumber a non-zero, odd number used as the multiplier
 | 
			
		||||
	 * @throws IllegalArgumentException if the number is zero or even
 | 
			
		||||
	 */
 | 
			
		||||
	private HashCodeBuilder(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
 | 
			
		||||
		if (initialNonZeroOddNumber == 0) {
 | 
			
		||||
			throw new IllegalArgumentException("HashCodeBuilder requires a non zero initial value");
 | 
			
		||||
		}
 | 
			
		||||
		if (initialNonZeroOddNumber % 2 == 0) {
 | 
			
		||||
			throw new IllegalArgumentException("HashCodeBuilder requires an odd initial value");
 | 
			
		||||
		}
 | 
			
		||||
		if (multiplierNonZeroOddNumber == 0) {
 | 
			
		||||
			throw new IllegalArgumentException("HashCodeBuilder requires a non zero multiplier");
 | 
			
		||||
		}
 | 
			
		||||
		if (multiplierNonZeroOddNumber % 2 == 0) {
 | 
			
		||||
			throw new IllegalArgumentException("HashCodeBuilder requires an odd multiplier");
 | 
			
		||||
		}
 | 
			
		||||
		constant = multiplierNonZeroOddNumber;
 | 
			
		||||
		total = initialNonZeroOddNumber;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Nonnull
 | 
			
		||||
	public static HashCodeBuilder newInstance() {
 | 
			
		||||
		return new HashCodeBuilder();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Nonnull
 | 
			
		||||
	public static HashCodeBuilder newInstance(int initialNonZeroOddNumber, int multiplierNonZeroOddNumber) {
 | 
			
		||||
		return new HashCodeBuilder(initialNonZeroOddNumber, multiplierNonZeroOddNumber);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*
 | 
			
		||||
	*                           METHODS
 | 
			
		||||
	*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>boolean</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * This adds <code>constant * 1</code> to the <code>hashCode</code> and not a <code>1231</code> or
 | 
			
		||||
	 * <code>1237</code> as done in java.lang.Boolean. This is in accordance with the <quote>Effective Java</quote>
 | 
			
		||||
	 * design.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the boolean to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(boolean value) {
 | 
			
		||||
		total = total * constant + (value ? 0 : 1);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>boolean</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(boolean[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (boolean element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>byte</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the byte to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(byte value) {
 | 
			
		||||
		total = total * constant + value;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>byte</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(byte[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (byte element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>char</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the char to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(char value) {
 | 
			
		||||
		total = total * constant + value;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>char</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(char[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (char element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>double</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the double to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(double value) {
 | 
			
		||||
		return append(Double.doubleToLongBits(value));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>double</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(double[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (double element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>float</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the float to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(float value) {
 | 
			
		||||
		total = total * constant + Float.floatToIntBits(value);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>float</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(float[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (float element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for an <code>int</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the int to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(int value) {
 | 
			
		||||
		total = total * constant + value;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for an <code>int</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(int[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (int element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>long</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the long to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	// NOTE: This method uses >> and not >>> as Effective Java and
 | 
			
		||||
	//       Long.hashCode do. Ideally we should switch to >>> at
 | 
			
		||||
	//       some stage. There are backwards compat issues, so
 | 
			
		||||
	//       that will have to wait for the time being. cf LANG-342.
 | 
			
		||||
	public HashCodeBuilder append(long value) {
 | 
			
		||||
		total = total * constant + ((int) (value ^ (value >> 32)));
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>long</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(long[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (long element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for an <code>Object</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param object the Object to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(Object object) {
 | 
			
		||||
		if (object == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
			if (object.getClass().isArray()) {
 | 
			
		||||
				// 'Switch' on type of array, to dispatch to the correct handler
 | 
			
		||||
				// This handles multi dimensional arrays
 | 
			
		||||
				if (object instanceof long[]) {
 | 
			
		||||
					append((long[]) object);
 | 
			
		||||
				} else if (object instanceof int[]) {
 | 
			
		||||
					append((int[]) object);
 | 
			
		||||
				} else if (object instanceof short[]) {
 | 
			
		||||
					append((short[]) object);
 | 
			
		||||
				} else if (object instanceof char[]) {
 | 
			
		||||
					append((char[]) object);
 | 
			
		||||
				} else if (object instanceof byte[]) {
 | 
			
		||||
					append((byte[]) object);
 | 
			
		||||
				} else if (object instanceof double[]) {
 | 
			
		||||
					append((double[]) object);
 | 
			
		||||
				} else if (object instanceof float[]) {
 | 
			
		||||
					append((float[]) object);
 | 
			
		||||
				} else if (object instanceof boolean[]) {
 | 
			
		||||
					append((boolean[]) object);
 | 
			
		||||
				} else {
 | 
			
		||||
					// Not an array of primitives
 | 
			
		||||
					append((Object[]) object);
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				total = total * constant + object.hashCode();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for an <code>Object</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(Object[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (Object element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>short</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param value the short to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(short value) {
 | 
			
		||||
		total = total * constant + value;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Append a <code>hashCode</code> for a <code>short</code> array.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array the array to add to the <code>hashCode</code>
 | 
			
		||||
	 * @return this
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder append(short[] array) {
 | 
			
		||||
		if (array == null) {
 | 
			
		||||
			total = total * constant;
 | 
			
		||||
		} else {
 | 
			
		||||
			for (short element : array) {
 | 
			
		||||
				append(element);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Adds the result of super.hashCode() to this builder.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param superHashCode the result of calling <code>super.hashCode()</code>
 | 
			
		||||
	 * @return this HashCodeBuilder, used to chain calls.
 | 
			
		||||
	 * @since 2.0
 | 
			
		||||
	 */
 | 
			
		||||
	public HashCodeBuilder appendSuper(int superHashCode) {
 | 
			
		||||
		total = total * constant + superHashCode;
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p>
 | 
			
		||||
	 * Return the computed <code>hashCode</code>.
 | 
			
		||||
	 * </p>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return <code>hashCode</code> based on the fields appended
 | 
			
		||||
	 */
 | 
			
		||||
	public int toHashCode() {
 | 
			
		||||
		return total;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * <p/>
 | 
			
		||||
	 * The computed <code>hashCode</code> from toHashCode() is returned due to the likelyhood
 | 
			
		||||
	 * of bugs in mis-calling toHashCode() and the unlikelyness of it mattering what the hashCode for
 | 
			
		||||
	 * HashCodeBuilder itself is.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return <code>hashCode</code> based on the fields appended
 | 
			
		||||
	 * @since 2.5
 | 
			
		||||
	 */
 | 
			
		||||
	public int hashCode() {
 | 
			
		||||
		return toHashCode();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
public interface JBuilder<T> {
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    T create();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Predicate, copy of Guava's {@link com.google.common.base.Predicate}
 | 
			
		||||
 */
 | 
			
		||||
public interface JPredicate<T> {
 | 
			
		||||
 | 
			
		||||
	boolean apply(@Nullable T t);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,213 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User: serso
 | 
			
		||||
 * Date: 5/18/11
 | 
			
		||||
 * Time: 11:18 AM
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.equals.Equalizer;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class Objects {
 | 
			
		||||
 | 
			
		||||
	protected Objects() {
 | 
			
		||||
		throw new AssertionError();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*
 | 
			
		||||
	*                           EQUALS
 | 
			
		||||
	*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	public static EqualsResult getEqualsResult(@Nullable Object o1, @Nullable Object o2) {
 | 
			
		||||
		return new EqualsResult<Object>(o1, o2, null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> boolean areEqual(@Nullable T o1, @Nullable T o2) {
 | 
			
		||||
		return new EqualsResult<T>(o1, o2, null).areEqual();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> boolean areEqual(@Nullable T o1, @Nullable T o2, @Nullable Equalizer<? super T> equalizer) {
 | 
			
		||||
		return new EqualsResult<T>(o1, o2, equalizer).areEqual();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*
 | 
			
		||||
	*                           COMPARE
 | 
			
		||||
	*
 | 
			
		||||
	**********************************************************************
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	public static int compare(Object value1, Object value2) {
 | 
			
		||||
		Integer result = compareOnNullness(value1, value2);
 | 
			
		||||
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			if (value1 instanceof Comparable && value2 instanceof Comparable) {
 | 
			
		||||
				//noinspection unchecked
 | 
			
		||||
				result = ((Comparable) value1).compareTo(value2);
 | 
			
		||||
			} else {
 | 
			
		||||
				result = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T extends Comparable<T>> int compare(@Nullable T l,
 | 
			
		||||
														@Nullable T r) {
 | 
			
		||||
		Integer result = compareOnNullness(l, r);
 | 
			
		||||
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			assert l != null;
 | 
			
		||||
			result = l.compareTo(r);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int compare(List list1, List list2) {
 | 
			
		||||
		Integer result = compareOnNullness(list1, list2);
 | 
			
		||||
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			result = list1.size() - list2.size();
 | 
			
		||||
			if (result == 0) {
 | 
			
		||||
				for (int i = 0; i < list1.size(); i++) {
 | 
			
		||||
					result = compare(list1.get(i), list2.get(i));
 | 
			
		||||
					if (result != 0) {
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int compare(Number value1, Number value2) {
 | 
			
		||||
		Integer result = compareOnNullness(value1, value2);
 | 
			
		||||
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			if (value1 instanceof Comparable && value2 instanceof Comparable) {
 | 
			
		||||
				//noinspection unchecked
 | 
			
		||||
				result = ((Comparable) value1).compareTo(value2);
 | 
			
		||||
			} else {
 | 
			
		||||
				result = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int compare(Date value1, Date value2) {
 | 
			
		||||
		Integer result = compareOnNullness(value1, value2);
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			if (value1.before(value2)) {
 | 
			
		||||
				result = -1;
 | 
			
		||||
			} else if (value1.after(value2)) {
 | 
			
		||||
				result = 1;
 | 
			
		||||
			} else {
 | 
			
		||||
				result = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int compare(int value1, int value2) {
 | 
			
		||||
		if (value1 > value2) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} else if (value1 == value2) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int compare(String value1, String value2, boolean ignoreCase) {
 | 
			
		||||
		Integer result = compareOnNullness(value1, value2);
 | 
			
		||||
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			if (ignoreCase) {
 | 
			
		||||
				result = value1.toLowerCase().compareTo(value2.toLowerCase());
 | 
			
		||||
			} else {
 | 
			
		||||
				result = value1.compareTo(value2);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static int compare(Boolean value1, Boolean value2) {
 | 
			
		||||
		Integer result = compareOnNullness(value1, value2);
 | 
			
		||||
 | 
			
		||||
		if (result == null) {
 | 
			
		||||
			result = value1.compareTo(value2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method compares objects according their nullness property
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param o1 first compared object
 | 
			
		||||
	 * @param o2 second compared object
 | 
			
		||||
	 * @return if both objects are nulls then 0 (they are equal), if first is null then -1, if second is null then 1, otherwise - null
 | 
			
		||||
	 */
 | 
			
		||||
	@Nullable
 | 
			
		||||
	public static Integer compareOnNullness(Object o1, Object o2) {
 | 
			
		||||
		Integer result;
 | 
			
		||||
 | 
			
		||||
		if (o1 == null && o2 == null) {
 | 
			
		||||
			result = EqualsResult.BOTH_NULLS_CONST;
 | 
			
		||||
		} else if (o1 == null) {
 | 
			
		||||
			result = -1;
 | 
			
		||||
		} else if (o2 == null) {
 | 
			
		||||
			result = 1;
 | 
			
		||||
		} else {
 | 
			
		||||
			//both not nulls
 | 
			
		||||
			result = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Method compares objects according their nullness property
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param o1 first compared object
 | 
			
		||||
	 * @param o2 second compared object
 | 
			
		||||
	 * @return if both objects are nulls then 0 (they are equal), if first is null then -1, if second is null then 1, otherwise - null
 | 
			
		||||
	 */
 | 
			
		||||
	public static EqualsResult compareOnNullnessWithResult(Object o1, Object o2) {
 | 
			
		||||
		return getEqualsResult(o1, o2);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,67 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common.equals;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.Objects;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
public class CollectionEqualizer<T> implements Equalizer<Collection<T>> {
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    protected final Equalizer<T> nestedEqualizer;
 | 
			
		||||
 | 
			
		||||
    public CollectionEqualizer(@Nullable Equalizer<T> nestedEqualizer) {
 | 
			
		||||
        this.nestedEqualizer = nestedEqualizer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean areEqual(@Nonnull Collection<T> first, @Nonnull Collection<T> second) {
 | 
			
		||||
        boolean result = false;
 | 
			
		||||
 | 
			
		||||
        if (first.size() == second.size()) {
 | 
			
		||||
            result = true;
 | 
			
		||||
 | 
			
		||||
            for (T el1 : first) {
 | 
			
		||||
                boolean found = false;
 | 
			
		||||
 | 
			
		||||
                for (T el2 : second) {
 | 
			
		||||
                    if (Objects.areEqual(el1, el2, nestedEqualizer)) {
 | 
			
		||||
                        found = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!found) {
 | 
			
		||||
                    result = false;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 serso aka se.solovyev
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * ---------------------------------------------------------------------
 | 
			
		||||
 * Contact details
 | 
			
		||||
 *
 | 
			
		||||
 * Email: se.solovyev@gmail.com
 | 
			
		||||
 * Site:  http://se.solovyev.org
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common.equals;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.Objects;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class ListEqualizer<T> implements Equalizer<List<T>> {
 | 
			
		||||
 | 
			
		||||
	@Nonnull
 | 
			
		||||
	private static final Equalizer<List<Object>> instanceWithOrder = new ListEqualizer<>(true, null);
 | 
			
		||||
 | 
			
		||||
	@Nonnull
 | 
			
		||||
	private static final Equalizer<List<Object>> instanceWithoutOrder = new ListEqualizer<>(false, null);
 | 
			
		||||
 | 
			
		||||
	private final boolean checkOrder;
 | 
			
		||||
 | 
			
		||||
	@Nullable
 | 
			
		||||
	protected final Equalizer<T> nestedEqualizer;
 | 
			
		||||
 | 
			
		||||
	private ListEqualizer(boolean checkOrder, @Nullable Equalizer<T> nestedEqualizer) {
 | 
			
		||||
		this.checkOrder = checkOrder;
 | 
			
		||||
		this.nestedEqualizer = nestedEqualizer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Nonnull
 | 
			
		||||
	public static <T> ListEqualizer<T> newWithNestedEqualizer(boolean checkOrder, @Nullable Equalizer<T> nestedEqualizer) {
 | 
			
		||||
		return new ListEqualizer<>(checkOrder, nestedEqualizer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Nonnull
 | 
			
		||||
	public static <T> ListEqualizer<T> newWithNaturalEquals(boolean checkOrder) {
 | 
			
		||||
		if (checkOrder) {
 | 
			
		||||
			return (ListEqualizer<T>) instanceWithOrder;
 | 
			
		||||
		} else {
 | 
			
		||||
			return (ListEqualizer<T>) instanceWithoutOrder;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean areEqual(@Nonnull List<T> first, @Nonnull List<T> second) {
 | 
			
		||||
		boolean result = false;
 | 
			
		||||
 | 
			
		||||
		if (first.size() == second.size()) {
 | 
			
		||||
			if (checkOrder) {
 | 
			
		||||
				result = true;
 | 
			
		||||
				for (int i = 0; i < first.size(); i++) {
 | 
			
		||||
					final T el1 = first.get(i);
 | 
			
		||||
					final T el2 = second.get(i);
 | 
			
		||||
 | 
			
		||||
					if (!Objects.areEqual(el1, el2, nestedEqualizer)) {
 | 
			
		||||
						result = false;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				result = Objects.areEqual(first, second, new CollectionEqualizer<>(nestedEqualizer));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -22,7 +22,6 @@
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common.math;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.collections.SortedList;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -117,34 +116,23 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
 | 
			
		||||
        list.add(entity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public T add(@Nonnull JBuilder<? extends T> builder) {
 | 
			
		||||
    public T addOrUpdate(@Nonnull T entity) {
 | 
			
		||||
        synchronized (this) {
 | 
			
		||||
            final T entity = builder.create();
 | 
			
		||||
 | 
			
		||||
            T varFromRegister;
 | 
			
		||||
 | 
			
		||||
            if (entity.isIdDefined()) {
 | 
			
		||||
                varFromRegister = getById(entity.getId());
 | 
			
		||||
            } else {
 | 
			
		||||
                varFromRegister = get(entity.getName());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (varFromRegister == null) {
 | 
			
		||||
                varFromRegister = entity;
 | 
			
		||||
 | 
			
		||||
                addEntity(entity, this.entities);
 | 
			
		||||
                this.entityNames.clear();
 | 
			
		||||
            final T existingEntity = entity.isIdDefined() ? getById(entity.getId()) : get(entity.getName());
 | 
			
		||||
            if (existingEntity == null) {
 | 
			
		||||
                addEntity(entity, entities);
 | 
			
		||||
                entityNames.clear();
 | 
			
		||||
                if (entity.isSystem()) {
 | 
			
		||||
                    this.systemEntities.add(entity);
 | 
			
		||||
                    systemEntities.add(entity);
 | 
			
		||||
                }
 | 
			
		||||
                return entity;
 | 
			
		||||
            } else {
 | 
			
		||||
                varFromRegister.copy(entity);
 | 
			
		||||
                existingEntity.copy(entity);
 | 
			
		||||
                this.entities.sort();
 | 
			
		||||
                this.entityNames.clear();
 | 
			
		||||
                this.systemEntities.sort();
 | 
			
		||||
                return existingEntity;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return varFromRegister;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,6 @@
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common.math;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -36,7 +34,7 @@ public interface MathRegistry<T extends MathEntity> {
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    List<T> getSystemEntities();
 | 
			
		||||
 | 
			
		||||
    T add(@Nonnull JBuilder<? extends T> JBuilder);
 | 
			
		||||
    T addOrUpdate(@Nonnull T t);
 | 
			
		||||
 | 
			
		||||
    void remove(@Nonnull T var);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,6 @@
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common.msg;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.HashCodeBuilder;
 | 
			
		||||
import org.solovyev.common.Objects;
 | 
			
		||||
import org.solovyev.common.equals.ListEqualizer;
 | 
			
		||||
import org.solovyev.common.text.Strings;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -81,7 +78,7 @@ public abstract class AbstractMessage implements Message {
 | 
			
		||||
 | 
			
		||||
        final AbstractMessage that = (AbstractMessage) o;
 | 
			
		||||
 | 
			
		||||
        if (!Objects.areEqual(parameters, that.parameters, ListEqualizer.newWithNaturalEquals(true))) {
 | 
			
		||||
        if (!areEqual(parameters, that.parameters)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!messageCode.equals(that.messageCode)) {
 | 
			
		||||
@@ -94,15 +91,23 @@ public abstract class AbstractMessage implements Message {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean areEqual(@Nonnull List<Object> thisList, @Nonnull List<Object> thatList) {
 | 
			
		||||
        if (thisList.size() != thatList.size()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0; i < thisList.size(); i++) {
 | 
			
		||||
            final Object thisItem = thisList.get(i);
 | 
			
		||||
            final Object thatItem = thatList.get(i);
 | 
			
		||||
            if (!thisItem.equals(thatItem)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        final HashCodeBuilder hcb = HashCodeBuilder.newInstance();
 | 
			
		||||
 | 
			
		||||
        hcb.append(messageCode);
 | 
			
		||||
        hcb.append(messageLevel);
 | 
			
		||||
        hcb.append(parameters);
 | 
			
		||||
 | 
			
		||||
        return hcb.toHashCode();
 | 
			
		||||
        return com.google.common.base.Objects.hashCode(messageCode, messageLevel, parameters);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -22,12 +22,12 @@
 | 
			
		||||
 | 
			
		||||
package org.solovyev.common.search;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.JPredicate;
 | 
			
		||||
import com.google.common.base.Predicate;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
public class StartsWithFinder implements JPredicate<String> {
 | 
			
		||||
public class StartsWithFinder implements Predicate<String> {
 | 
			
		||||
 | 
			
		||||
	private int i;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -47,13 +47,15 @@ public class NumeralBaseTest {
 | 
			
		||||
 | 
			
		||||
        IConstant constant = null;
 | 
			
		||||
        try {
 | 
			
		||||
            constant = me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("a"), 2d));
 | 
			
		||||
            final ExtendedConstant.Builder a = new ExtendedConstant.Builder(new Constant("a"), 2d);
 | 
			
		||||
            constant = me.getConstantsRegistry().addOrUpdate(a.create());
 | 
			
		||||
            Assert.assertEquals("2748", me.evaluate("0x:ABC"));
 | 
			
		||||
            Assert.assertEquals("5496", me.evaluate("0x:ABC*a"));
 | 
			
		||||
            Assert.assertEquals("27480", me.evaluate("0x:ABC*0x:A"));
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (constant != null) {
 | 
			
		||||
                me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("a"), (String) null));
 | 
			
		||||
                final ExtendedConstant.Builder a = new ExtendedConstant.Builder(new Constant("a"), (String) null);
 | 
			
		||||
                me.getConstantsRegistry().addOrUpdate(a.create());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,8 @@ public class ExpressionTest {
 | 
			
		||||
 | 
			
		||||
        final JsclMathEngine me = JsclMathEngine.getInstance();
 | 
			
		||||
        try {
 | 
			
		||||
            constant = me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("t_0"), 1d));
 | 
			
		||||
            final ExtendedConstant.Builder t_0 = new ExtendedConstant.Builder(new Constant("t_0"), 1d);
 | 
			
		||||
            constant = me.getConstantsRegistry().addOrUpdate(t_0.create());
 | 
			
		||||
 | 
			
		||||
            constants = Expression.valueOf("3+4*t_0+t_0+t_1").getConstants();
 | 
			
		||||
            Assert.assertTrue(constants.size() == 2);
 | 
			
		||||
@@ -136,7 +137,8 @@ public class ExpressionTest {
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (constant != null) {
 | 
			
		||||
                me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant(constant.getName()), (String) null));
 | 
			
		||||
                final ExtendedConstant.Builder jBuilder = new ExtendedConstant.Builder(new Constant(constant.getName()), (String) null);
 | 
			
		||||
                me.getConstantsRegistry().addOrUpdate(jBuilder.create());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -268,23 +270,27 @@ public class ExpressionTest {
 | 
			
		||||
        Assert.assertEquals("2.8284271247461903", Expression.valueOf("abs(2-2*i)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("k"), 2.8284271247461903));
 | 
			
		||||
            final ExtendedConstant.Builder k = new ExtendedConstant.Builder(new Constant("k"), 2.8284271247461903);
 | 
			
		||||
            me.getConstantsRegistry().addOrUpdate(k.create());
 | 
			
		||||
            Assert.assertEquals("k", Expression.valueOf("k").numeric().toString());
 | 
			
		||||
            Assert.assertEquals("k", Expression.valueOf("k").simplify().toString());
 | 
			
		||||
            Assert.assertEquals("k", Expression.valueOf("k").simplify().toString());
 | 
			
		||||
            Assert.assertEquals("k^3", Expression.valueOf("k*k*k").simplify().toString());
 | 
			
		||||
            Assert.assertEquals("22.627416997969526", Expression.valueOf("k*k*k").numeric().toString());
 | 
			
		||||
        } finally {
 | 
			
		||||
            me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("k"), (String) null));
 | 
			
		||||
            final ExtendedConstant.Builder k = new ExtendedConstant.Builder(new Constant("k"), (String) null);
 | 
			
		||||
            me.getConstantsRegistry().addOrUpdate(k.create());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("k_1"), 3d));
 | 
			
		||||
            final ExtendedConstant.Builder k_1 = new ExtendedConstant.Builder(new Constant("k_1"), 3d);
 | 
			
		||||
            me.getConstantsRegistry().addOrUpdate(k_1.create());
 | 
			
		||||
            Assert.assertEquals("k_1", Expression.valueOf("k_1").numeric().toString());
 | 
			
		||||
            Assert.assertEquals("k_1", Expression.valueOf("k_1[0]").numeric().toString());
 | 
			
		||||
            Assert.assertEquals("k_1", Expression.valueOf("k_1[2]").numeric().toString());
 | 
			
		||||
        } finally {
 | 
			
		||||
            me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("k_1"), (String) null));
 | 
			
		||||
            final ExtendedConstant.Builder k_1 = new ExtendedConstant.Builder(new Constant("k_1"), (String) null);
 | 
			
		||||
            me.getConstantsRegistry().addOrUpdate(k_1.create());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Generic expression = me.simplifyGeneric("cos(t)+∂(cos(t),t)");
 | 
			
		||||
@@ -357,7 +363,8 @@ public class ExpressionTest {
 | 
			
		||||
        } catch (ArithmeticException e) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("t"), (String) null));
 | 
			
		||||
        final ExtendedConstant.Builder t = new ExtendedConstant.Builder(new Constant("t"), (String) null);
 | 
			
		||||
        me.getConstantsRegistry().addOrUpdate(t.create());
 | 
			
		||||
        try {
 | 
			
		||||
            Expression.valueOf("t").numeric();
 | 
			
		||||
            fail();
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ import jscl.text.ParseException;
 | 
			
		||||
import jscl.util.ExpressionGeneratorWithInput;
 | 
			
		||||
import org.junit.Assert;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.solovyev.common.Converter;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
package jscl.math.function;
 | 
			
		||||
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
import org.solovyev.common.math.AbstractMathRegistry;
 | 
			
		||||
import org.solovyev.common.math.AbstractMathRegistryTest;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User: serso
 | 
			
		||||
 * Date: 6/15/13
 | 
			
		||||
 * Time: 9:23 PM
 | 
			
		||||
 */
 | 
			
		||||
public class ConstantsRegistryTest extends AbstractMathRegistryTest<IConstant> {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected JBuilder<? extends IConstant> createBuilder(@Nonnull final String name) {
 | 
			
		||||
        return new JBuilder<IConstant>() {
 | 
			
		||||
            @Nonnull
 | 
			
		||||
            @Override
 | 
			
		||||
            public IConstant create() {
 | 
			
		||||
                return new ExtendedConstant(new Constant(name), name, name);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @Override
 | 
			
		||||
    protected AbstractMathRegistry<IConstant> getRegistry() {
 | 
			
		||||
        return new ConstantsRegistry();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -24,7 +24,8 @@ public class CustomFunctionTest {
 | 
			
		||||
        Assert.assertEquals("∞", Expression.valueOf("ln(10)/ln(1)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        // logarithm
 | 
			
		||||
        Function function = mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder(true, "log", Arrays.asList("a", "b"), "ln(b)/ln(a)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder = new CustomFunction.Builder(true, "log", Arrays.asList("a", "b"), "ln(b)/ln(a)");
 | 
			
		||||
        Function function = mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder.create());
 | 
			
		||||
        Assert.assertEquals("log(a, b)", function.toString());
 | 
			
		||||
        Assert.assertEquals("ln(b)/ln(a)", ((CustomFunction) mathEngine.getFunctionsRegistry().get("log")).getContent());
 | 
			
		||||
        Assert.assertEquals("∞", Expression.valueOf("log(1, 10)").numeric().toString());
 | 
			
		||||
@@ -40,13 +41,15 @@ public class CustomFunctionTest {
 | 
			
		||||
    public void testDerivative() throws Exception {
 | 
			
		||||
        JsclMathEngine mathEngine = JsclMathEngine.getInstance();
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("t1", Arrays.asList("a"), "sin(a)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder = new CustomFunction.Builder("t1", Arrays.asList("a"), "sin(a)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder.create());
 | 
			
		||||
        Assert.assertEquals("1", Expression.valueOf("t1(90)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("cos(t)", Expression.valueOf("∂(t1(t), t)").expand().toString());
 | 
			
		||||
        Assert.assertEquals("0", Expression.valueOf("∂(t1(t), t2)").expand().toString());
 | 
			
		||||
        Assert.assertEquals("cos(a)", Expression.valueOf("∂(t1(a), a)").expand().toString());
 | 
			
		||||
        Assert.assertEquals("1", Expression.valueOf("∂(t1(a), t1(a))").expand().toString());
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("t2", Arrays.asList("a", "b"), "b*sin(a)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder1 = new CustomFunction.Builder("t2", Arrays.asList("a", "b"), "b*sin(a)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder1.create());
 | 
			
		||||
        Assert.assertEquals("y*cos(x)", Expression.valueOf("∂(t2(x, y), x)").expand().toString());
 | 
			
		||||
        Assert.assertEquals("sin(x)", Expression.valueOf("∂(t2(x, y), y)").expand().toString());
 | 
			
		||||
    }
 | 
			
		||||
@@ -55,7 +58,8 @@ public class CustomFunctionTest {
 | 
			
		||||
    public void testAntiDerivative() throws Exception {
 | 
			
		||||
        JsclMathEngine mathEngine = JsclMathEngine.getInstance();
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("t1", Arrays.asList("a"), "sin(a)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder = new CustomFunction.Builder("t1", Arrays.asList("a"), "sin(a)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder.create());
 | 
			
		||||
        Assert.assertEquals("1", Expression.valueOf("t1(90)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +69,8 @@ public class CustomFunctionTest {
 | 
			
		||||
            Assert.assertEquals("t2*sin(t)", Expression.valueOf("∫(t1(t), t2)").expand().toString());
 | 
			
		||||
            Assert.assertEquals("-cos(a)", Expression.valueOf("∫(t1(a), a)").expand().toString());
 | 
			
		||||
            Assert.assertEquals("1/2*sin(a)^2", Expression.valueOf("∫(t1(a), t1(a))").expand().toString());
 | 
			
		||||
            mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("t2", Arrays.asList("a", "b"), "b*sin(a)"));
 | 
			
		||||
            final CustomFunction.Builder jBuilder1 = new CustomFunction.Builder("t2", Arrays.asList("a", "b"), "b*sin(a)");
 | 
			
		||||
            mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder1.create());
 | 
			
		||||
            Assert.assertEquals("-y*cos(x)", Expression.valueOf("∫(t2(x, y), x)").expand().toString());
 | 
			
		||||
            Assert.assertEquals("1/2*y^2*sin(x)", Expression.valueOf("∫(t2(x, y), y)").expand().toString());
 | 
			
		||||
        } finally {
 | 
			
		||||
@@ -78,7 +83,8 @@ public class CustomFunctionTest {
 | 
			
		||||
    public void testFunction() throws Exception {
 | 
			
		||||
        JsclMathEngine mathEngine = JsclMathEngine.getInstance();
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction", Arrays.asList("a", "b", "c", "d"), "b*cos(a)/c+d"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder = new CustomFunction.Builder("testFunction", Arrays.asList("a", "b", "c", "d"), "b*cos(a)/c+d");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder.create());
 | 
			
		||||
        Assert.assertEquals("6.749543120264322", Expression.valueOf("testFunction(2, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("7.749543120264322", Expression.valueOf("testFunction(2, 3, 4, 7)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("6.749543120264322", Expression.valueOf("testFunction(2*1, 3, 4, 6)").numeric().toString());
 | 
			
		||||
@@ -96,26 +102,31 @@ public class CustomFunctionTest {
 | 
			
		||||
            // ok, not enough parameters
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mathEngine.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("a"), 1000d));
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction2", Arrays.asList("a", "b", "c", "d"), "b*cos(a)/c+d"));
 | 
			
		||||
        final ExtendedConstant.Builder a = new ExtendedConstant.Builder(new Constant("a"), 1000d);
 | 
			
		||||
        mathEngine.getConstantsRegistry().addOrUpdate(a.create());
 | 
			
		||||
        final CustomFunction.Builder jBuilder1 = new CustomFunction.Builder("testFunction2", Arrays.asList("a", "b", "c", "d"), "b*cos(a)/c+d");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder1.create());
 | 
			
		||||
        Assert.assertEquals("6.749543120264322", Expression.valueOf("testFunction2(2, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("7.749543120264322", Expression.valueOf("testFunction2(2, 3, 4, 7)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("6.749543120264322", Expression.valueOf("testFunction2(2*1, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("6.749543120264322", Expression.valueOf("testFunction2(2*1, 3, 2^2-1+e^0, 3!)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction3", Arrays.asList("a", "b", "c", "d"), "testFunction2(a, b, c, d) - testFunction(a, b, c, d)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder2 = new CustomFunction.Builder("testFunction3", Arrays.asList("a", "b", "c", "d"), "testFunction2(a, b, c, d) - testFunction(a, b, c, d)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder2.create());
 | 
			
		||||
        Assert.assertEquals("0", Expression.valueOf("testFunction3(2, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("0", Expression.valueOf("testFunction3(2, 3, 4, 7)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("0", Expression.valueOf("testFunction3(2*1, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("0", Expression.valueOf("testFunction3(2*1, 3, 2^2-1+e^0, 3!)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction4", Arrays.asList("a", "b", "c", "d"), "testFunction2(a, b/2, c/3, d/4) - testFunction(a, b!, c, d)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder3 = new CustomFunction.Builder("testFunction4", Arrays.asList("a", "b", "c", "d"), "testFunction2(a, b/2, c/3, d/4) - testFunction(a, b!, c, d)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder3.create());
 | 
			
		||||
        Assert.assertEquals("-4.874771560132161", Expression.valueOf("testFunction4(2, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("-5.624771560132161", Expression.valueOf("testFunction4(2, 3, 4, 7)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("-4.874771560132161", Expression.valueOf("testFunction4(2*1, 3, 4, 6)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("-4.874771560132161", Expression.valueOf("testFunction4(2*1, 3, 2^2-1+e^0, 3!)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction5", Arrays.asList("a", "b"), "testFunction2(a, b/2, 2, 1) - testFunction(a, b!, 4!, 1)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder4 = new CustomFunction.Builder("testFunction5", Arrays.asList("a", "b"), "testFunction2(a, b/2, 2, 1) - testFunction(a, b!, 4!, 1)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder4.create());
 | 
			
		||||
        Assert.assertEquals("0.4996954135095478", Expression.valueOf("testFunction5(2, 3)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("0.4996954135095478", Expression.valueOf("testFunction5(2, 3)").numeric().toString());
 | 
			
		||||
        Assert.assertEquals("0.4996954135095478", Expression.valueOf("testFunction5(2*1, 3)").numeric().toString());
 | 
			
		||||
@@ -128,15 +139,20 @@ public class CustomFunctionTest {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction6", Arrays.asList("a", "b"), "testFunction(a, b!, 4!, Π)"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder5 = new CustomFunction.Builder("testFunction6", Arrays.asList("a", "b"), "testFunction(a, b!, 4!, Π)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder5.create());
 | 
			
		||||
        Assert.assertEquals("180.24984770675476", Expression.valueOf("testFunction6(2, 3)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        mathEngine.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("e"), 181d));
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction7", Arrays.asList("a", "b"), "testFunction(a, b!, 4!, e)"));
 | 
			
		||||
        final ExtendedConstant.Builder e = new ExtendedConstant.Builder(new Constant("e"), 181d);
 | 
			
		||||
        mathEngine.getConstantsRegistry().addOrUpdate(e.create());
 | 
			
		||||
        final CustomFunction.Builder jBuilder6 = new CustomFunction.Builder("testFunction7", Arrays.asList("a", "b"), "testFunction(a, b!, 4!, e)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder6.create());
 | 
			
		||||
        Assert.assertEquals("181.24984770675476", Expression.valueOf("testFunction7(2, 3)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
        mathEngine.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("e"), 181d));
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("testFunction8", Arrays.asList("a", "b"), "testFunction(sin(a), b!, 4!, e)"));
 | 
			
		||||
        final ExtendedConstant.Builder e1 = new ExtendedConstant.Builder(new Constant("e"), 181d);
 | 
			
		||||
        mathEngine.getConstantsRegistry().addOrUpdate(e1.create());
 | 
			
		||||
        final CustomFunction.Builder jBuilder7 = new CustomFunction.Builder("testFunction8", Arrays.asList("a", "b"), "testFunction(sin(a), b!, 4!, e)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder7.create());
 | 
			
		||||
        Assert.assertEquals("181.24999995362296", Expression.valueOf("testFunction8(2, 3)").numeric().toString());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@@ -145,9 +161,12 @@ public class CustomFunctionTest {
 | 
			
		||||
    public void testFunction2() throws Exception {
 | 
			
		||||
        JsclMathEngine mathEngine = JsclMathEngine.getInstance();
 | 
			
		||||
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("f", Arrays.asList("x", "y"), "z1/z2*√(x^2+y^2)"));
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("f2", Arrays.asList("x", "y"), "√(x^2+y^2)"));
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("f3", Arrays.asList("x", "y"), "x^2+y^2"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder = new CustomFunction.Builder("f", Arrays.asList("x", "y"), "z1/z2*√(x^2+y^2)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder.create());
 | 
			
		||||
        final CustomFunction.Builder jBuilder1 = new CustomFunction.Builder("f2", Arrays.asList("x", "y"), "√(x^2+y^2)");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder1.create());
 | 
			
		||||
        final CustomFunction.Builder jBuilder2 = new CustomFunction.Builder("f3", Arrays.asList("x", "y"), "x^2+y^2");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder2.create());
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            Assert.assertEquals("1", Expression.valueOf("f(1, 1)").numeric().toString());
 | 
			
		||||
@@ -163,8 +182,10 @@ public class CustomFunctionTest {
 | 
			
		||||
        Assert.assertEquals("2*z2", Expression.valueOf("∂(f3(z1, z2), z2)").expand().toString());
 | 
			
		||||
 | 
			
		||||
        // test symbols
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("f4", Arrays.asList("x", "y"), "2 000*x^2+y^2"));
 | 
			
		||||
        mathEngine.getFunctionsRegistry().add(new CustomFunction.Builder("f5", Arrays.asList("x", "y"), "2'000* x ^2+y^2\r"));
 | 
			
		||||
        final CustomFunction.Builder jBuilder3 = new CustomFunction.Builder("f4", Arrays.asList("x", "y"), "2 000*x^2+y^2");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder3.create());
 | 
			
		||||
        final CustomFunction.Builder jBuilder4 = new CustomFunction.Builder("f5", Arrays.asList("x", "y"), "2'000* x ^2+y^2\r");
 | 
			
		||||
        mathEngine.getFunctionsRegistry().addOrUpdate(jBuilder4.create());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,8 @@ public class CosTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testIntegral() throws Exception {
 | 
			
		||||
        final JsclMathEngine me = JsclMathEngine.getInstance();
 | 
			
		||||
        me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("t"), 10d));
 | 
			
		||||
        final ExtendedConstant.Builder t = new ExtendedConstant.Builder(new Constant("t"), 10d);
 | 
			
		||||
        me.getConstantsRegistry().addOrUpdate(t.create());
 | 
			
		||||
        Assert.assertEquals("-sin(t)", me.simplify("∂(cos(t),t,t,1)"));
 | 
			
		||||
        Assert.assertEquals("∂(cos(t), t, t, 1°)", me.simplify("∂(cos(t),t,t,1°)"));
 | 
			
		||||
        Assert.assertEquals("-0.17364817766693033", me.evaluate("∂(cos(t),t,t,1)"));
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,10 @@ public class SumTest {
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testExp() throws Exception {
 | 
			
		||||
        final JsclMathEngine me = JsclMathEngine.getInstance();
 | 
			
		||||
        me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("x"), 2d));
 | 
			
		||||
        me.getConstantsRegistry().add(new ExtendedConstant.Builder(new Constant("i"), (String) null));
 | 
			
		||||
        final ExtendedConstant.Builder x = new ExtendedConstant.Builder(new Constant("x"), 2d);
 | 
			
		||||
        me.getConstantsRegistry().addOrUpdate(x.create());
 | 
			
		||||
        final ExtendedConstant.Builder i = new ExtendedConstant.Builder(new Constant("i"), (String) null);
 | 
			
		||||
        me.getConstantsRegistry().addOrUpdate(i.create());
 | 
			
		||||
        Assert.assertEquals("51.735296462438285", me.evaluate("Σ((1+x/i)^i, i, 1, 10)"));
 | 
			
		||||
        Assert.assertEquals("686.0048440525586", me.evaluate("Σ((1+x/i)^i, i, 1, 100)"));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
package org.solovyev.common.math;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.solovyev.common.JBuilder;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * User: serso
 | 
			
		||||
 * Date: 6/15/13
 | 
			
		||||
 * Time: 9:20 PM
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractMathRegistryTest<T extends MathEntity> {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testAdd() throws Exception {
 | 
			
		||||
        final AbstractMathRegistry<T> registry = getRegistry();
 | 
			
		||||
 | 
			
		||||
        final int oldSize = registry.getEntities().size();
 | 
			
		||||
 | 
			
		||||
        registry.add(createBuilder("test"));
 | 
			
		||||
        registry.add(createBuilder("test"));
 | 
			
		||||
        registry.add(createBuilder("test1"));
 | 
			
		||||
 | 
			
		||||
        assertEquals(2, registry.getEntities().size() - oldSize);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract JBuilder<? extends T> createBuilder(@Nonnull String name);
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    protected abstract AbstractMathRegistry<T> getRegistry();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user