Remove dependencies
This commit is contained in:
		@@ -60,7 +60,6 @@ android {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
dependencies {
 | 
					dependencies {
 | 
				
			||||||
    compile fileTree(include: ['*.jar'], dir: 'libs')
 | 
					    compile fileTree(include: ['*.jar'], dir: 'libs')
 | 
				
			||||||
    compile 'org.solovyev:common-msg:1.0.7'
 | 
					 | 
				
			||||||
    compile 'com.android.support:support-v4:23.2.0'
 | 
					    compile 'com.android.support:support-v4:23.2.0'
 | 
				
			||||||
    compile 'com.android.support:appcompat-v7:23.2.0'
 | 
					    compile 'com.android.support:appcompat-v7:23.2.0'
 | 
				
			||||||
    compile 'com.android.support:cardview-v7:23.2.0'
 | 
					    compile 'com.android.support:cardview-v7:23.2.0'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,9 +48,7 @@ import android.view.View;
 | 
				
			|||||||
import android.view.ViewGroup;
 | 
					import android.view.ViewGroup;
 | 
				
			||||||
import android.view.inputmethod.InputMethodManager;
 | 
					import android.view.inputmethod.InputMethodManager;
 | 
				
			||||||
import android.widget.TextView;
 | 
					import android.widget.TextView;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.squareup.otto.Bus;
 | 
					import com.squareup.otto.Bus;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.solovyev.android.Check;
 | 
					import org.solovyev.android.Check;
 | 
				
			||||||
import org.solovyev.android.calculator.floating.FloatingCalculatorService;
 | 
					import org.solovyev.android.calculator.floating.FloatingCalculatorService;
 | 
				
			||||||
import org.solovyev.android.calculator.ga.Ga;
 | 
					import org.solovyev.android.calculator.ga.Ga;
 | 
				
			||||||
@@ -60,12 +58,10 @@ import org.solovyev.android.calculator.wizard.CalculatorWizards;
 | 
				
			|||||||
import org.solovyev.android.wizard.Wizards;
 | 
					import org.solovyev.android.wizard.Wizards;
 | 
				
			||||||
import org.solovyev.common.JPredicate;
 | 
					import org.solovyev.common.JPredicate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Collection;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.concurrent.atomic.AtomicInteger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This class aggregates several useful in any Android application interfaces and provides access to {@link android.app.Application} object from a static context.
 | 
					 * This class aggregates several useful in any Android application interfaces and provides access to {@link android.app.Application} object from a static context.
 | 
				
			||||||
@@ -262,18 +258,6 @@ public final class App {
 | 
				
			|||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static <T> T find(@Nullable Collection<T> collection, @Nonnull JPredicate<T> finder) {
 | 
					 | 
				
			||||||
        if (collection == null || collection.isEmpty()) {
 | 
					 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (T t : collection) {
 | 
					 | 
				
			||||||
            if (finder.apply(t)) {
 | 
					 | 
				
			||||||
                return t;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Nullable
 | 
					    @Nullable
 | 
				
			||||||
    public static String find(@Nonnull List<String> tokens, @Nonnull String text, int position) {
 | 
					    public static String find(@Nonnull List<String> tokens, @Nonnull String text, int position) {
 | 
				
			||||||
        for (int i = 0; i < tokens.size(); i++) {
 | 
					        for (int i = 0; i < tokens.size(); i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,9 +23,9 @@
 | 
				
			|||||||
package org.solovyev.android.calculator;
 | 
					package org.solovyev.android.calculator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.text.SpannableStringBuilder;
 | 
					import android.text.SpannableStringBuilder;
 | 
				
			||||||
 | 
					import android.text.TextUtils;
 | 
				
			||||||
import jscl.NumeralBase;
 | 
					import jscl.NumeralBase;
 | 
				
			||||||
import org.solovyev.android.calculator.math.MathType;
 | 
					import org.solovyev.android.calculator.math.MathType;
 | 
				
			||||||
import org.solovyev.common.text.Strings;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -60,7 +60,7 @@ public abstract class BaseNumberBuilder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean spaceBefore(@Nonnull MathType.Result mathTypeResult) {
 | 
					    private boolean spaceBefore(@Nonnull MathType.Result mathTypeResult) {
 | 
				
			||||||
        return numberBuilder == null && Strings.isEmpty(mathTypeResult.match.trim());
 | 
					        return numberBuilder == null && TextUtils.isEmpty(mathTypeResult.match.trim());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private boolean numeralBaseInTheStart(@Nonnull MathType mathType) {
 | 
					    private boolean numeralBaseInTheStart(@Nonnull MathType mathType) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,39 +26,8 @@ import android.content.SharedPreferences;
 | 
				
			|||||||
import android.support.annotation.NonNull;
 | 
					import android.support.annotation.NonNull;
 | 
				
			||||||
import android.text.TextUtils;
 | 
					import android.text.TextUtils;
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import com.squareup.otto.Bus;
 | 
					import com.squareup.otto.Bus;
 | 
				
			||||||
import com.squareup.otto.Subscribe;
 | 
					import com.squareup.otto.Subscribe;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.solovyev.android.Check;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.calculations.CalculationCancelledEvent;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.calculations.CalculationFailedEvent;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.calculations.CalculationFinishedEvent;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.calculations.ConversionFailedEvent;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.calculations.ConversionFinishedEvent;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.functions.FunctionsRegistry;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.variables.CppVariable;
 | 
					 | 
				
			||||||
import org.solovyev.common.msg.ListMessageRegistry;
 | 
					 | 
				
			||||||
import org.solovyev.common.msg.Message;
 | 
					 | 
				
			||||||
import org.solovyev.common.msg.MessageRegistry;
 | 
					 | 
				
			||||||
import org.solovyev.common.msg.MessageType;
 | 
					 | 
				
			||||||
import org.solovyev.common.text.Strings;
 | 
					 | 
				
			||||||
import org.solovyev.common.units.ConversionException;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.math.BigInteger;
 | 
					 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.Collections;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
import java.util.concurrent.Executor;
 | 
					 | 
				
			||||||
import java.util.concurrent.atomic.AtomicLong;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					 | 
				
			||||||
import javax.inject.Inject;
 | 
					 | 
				
			||||||
import javax.inject.Named;
 | 
					 | 
				
			||||||
import javax.inject.Singleton;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import jscl.JsclArithmeticException;
 | 
					import jscl.JsclArithmeticException;
 | 
				
			||||||
import jscl.MathEngine;
 | 
					import jscl.MathEngine;
 | 
				
			||||||
import jscl.NumeralBase;
 | 
					import jscl.NumeralBase;
 | 
				
			||||||
@@ -67,6 +36,28 @@ import jscl.math.Generic;
 | 
				
			|||||||
import jscl.math.function.Constants;
 | 
					import jscl.math.function.Constants;
 | 
				
			||||||
import jscl.math.function.IConstant;
 | 
					import jscl.math.function.IConstant;
 | 
				
			||||||
import jscl.text.ParseInterruptedException;
 | 
					import jscl.text.ParseInterruptedException;
 | 
				
			||||||
 | 
					import org.solovyev.android.Check;
 | 
				
			||||||
 | 
					import org.solovyev.android.calculator.calculations.*;
 | 
				
			||||||
 | 
					import org.solovyev.android.calculator.functions.FunctionsRegistry;
 | 
				
			||||||
 | 
					import org.solovyev.android.calculator.jscl.JsclOperation;
 | 
				
			||||||
 | 
					import org.solovyev.android.calculator.variables.CppVariable;
 | 
				
			||||||
 | 
					import org.solovyev.common.msg.ListMessageRegistry;
 | 
				
			||||||
 | 
					import org.solovyev.common.msg.Message;
 | 
				
			||||||
 | 
					import org.solovyev.common.msg.MessageRegistry;
 | 
				
			||||||
 | 
					import org.solovyev.common.msg.MessageType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
 | 
					import javax.inject.Inject;
 | 
				
			||||||
 | 
					import javax.inject.Named;
 | 
				
			||||||
 | 
					import javax.inject.Singleton;
 | 
				
			||||||
 | 
					import javax.measure.converter.ConversionException;
 | 
				
			||||||
 | 
					import java.math.BigInteger;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.concurrent.Executor;
 | 
				
			||||||
 | 
					import java.util.concurrent.atomic.AtomicLong;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Singleton
 | 
					@Singleton
 | 
				
			||||||
public class Calculator implements SharedPreferences.OnSharedPreferenceChangeListener {
 | 
					public class Calculator implements SharedPreferences.OnSharedPreferenceChangeListener {
 | 
				
			||||||
@@ -166,7 +157,7 @@ public class Calculator implements SharedPreferences.OnSharedPreferenceChangeLis
 | 
				
			|||||||
                               @Nonnull String e,
 | 
					                               @Nonnull String e,
 | 
				
			||||||
                               @Nonnull MessageRegistry mr) {
 | 
					                               @Nonnull MessageRegistry mr) {
 | 
				
			||||||
        e = e.trim();
 | 
					        e = e.trim();
 | 
				
			||||||
        if (Strings.isEmpty(e)) {
 | 
					        if (TextUtils.isEmpty(e)) {
 | 
				
			||||||
            bus.post(new CalculationFinishedEvent(o, e, sequence));
 | 
					            bus.post(new CalculationFinishedEvent(o, e, sequence));
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,13 +23,15 @@
 | 
				
			|||||||
package org.solovyev.android.calculator;
 | 
					package org.solovyev.android.calculator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import android.content.SharedPreferences;
 | 
					import android.content.SharedPreferences;
 | 
				
			||||||
 | 
					import android.text.TextUtils;
 | 
				
			||||||
import com.squareup.otto.Bus;
 | 
					import com.squareup.otto.Bus;
 | 
				
			||||||
import jscl.AngleUnit;
 | 
					import jscl.AngleUnit;
 | 
				
			||||||
import jscl.JsclMathEngine;
 | 
					import jscl.JsclMathEngine;
 | 
				
			||||||
import jscl.MathEngine;
 | 
					import jscl.MathEngine;
 | 
				
			||||||
import jscl.NumeralBase;
 | 
					import jscl.NumeralBase;
 | 
				
			||||||
import jscl.math.operator.Operator;
 | 
					import jscl.math.operator.Operator;
 | 
				
			||||||
import jscl.text.*;
 | 
					import jscl.text.Identifier;
 | 
				
			||||||
 | 
					import jscl.text.Parser;
 | 
				
			||||||
import org.solovyev.android.Check;
 | 
					import org.solovyev.android.Check;
 | 
				
			||||||
import org.solovyev.android.calculator.functions.FunctionsRegistry;
 | 
					import org.solovyev.android.calculator.functions.FunctionsRegistry;
 | 
				
			||||||
import org.solovyev.android.calculator.operators.OperatorsRegistry;
 | 
					import org.solovyev.android.calculator.operators.OperatorsRegistry;
 | 
				
			||||||
@@ -40,7 +42,6 @@ import org.solovyev.android.prefs.Preference;
 | 
				
			|||||||
import org.solovyev.android.prefs.StringPreference;
 | 
					import org.solovyev.android.prefs.StringPreference;
 | 
				
			||||||
import org.solovyev.common.text.EnumMapper;
 | 
					import org.solovyev.common.text.EnumMapper;
 | 
				
			||||||
import org.solovyev.common.text.NumberMapper;
 | 
					import org.solovyev.common.text.NumberMapper;
 | 
				
			||||||
import org.solovyev.common.text.Strings;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -104,7 +105,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean isValidName(@Nullable String name) {
 | 
					    public static boolean isValidName(@Nullable String name) {
 | 
				
			||||||
        if (!Strings.isEmpty(name)) {
 | 
					        if (!TextUtils.isEmpty(name)) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Identifier.parser.parse(Parser.Parameters.get(name), null);
 | 
					                Identifier.parser.parse(Parser.Parameters.get(name), null);
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
@@ -205,7 +206,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
 | 
				
			|||||||
        mathEngine.setRoundResult(Preferences.Output.round.getPreference(preferences));
 | 
					        mathEngine.setRoundResult(Preferences.Output.round.getPreference(preferences));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences);
 | 
					        final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences);
 | 
				
			||||||
        if (Strings.isEmpty(groupingSeparator)) {
 | 
					        if (TextUtils.isEmpty(groupingSeparator)) {
 | 
				
			||||||
            mathEngine.setUseGroupingSeparator(false);
 | 
					            mathEngine.setUseGroupingSeparator(false);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            mathEngine.setUseGroupingSeparator(true);
 | 
					            mathEngine.setUseGroupingSeparator(true);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,16 +34,14 @@ import org.solovyev.android.Check;
 | 
				
			|||||||
import org.solovyev.android.calculator.*;
 | 
					import org.solovyev.android.calculator.*;
 | 
				
			||||||
import org.solovyev.android.calculator.entities.BaseEntitiesFragment;
 | 
					import org.solovyev.android.calculator.entities.BaseEntitiesFragment;
 | 
				
			||||||
import org.solovyev.android.calculator.entities.Category;
 | 
					import org.solovyev.android.calculator.entities.Category;
 | 
				
			||||||
import org.solovyev.android.calculator.RemovalConfirmationDialog;
 | 
					 | 
				
			||||||
import org.solovyev.android.calculator.math.MathType;
 | 
					import org.solovyev.android.calculator.math.MathType;
 | 
				
			||||||
import org.solovyev.common.JPredicate;
 | 
					 | 
				
			||||||
import org.solovyev.common.collections.Collections;
 | 
					 | 
				
			||||||
import org.solovyev.common.text.Strings;
 | 
					import org.solovyev.common.text.Strings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
import javax.inject.Inject;
 | 
					import javax.inject.Inject;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Iterator;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class VariablesFragment extends BaseEntitiesFragment<IConstant> {
 | 
					public class VariablesFragment extends BaseEntitiesFragment<IConstant> {
 | 
				
			||||||
@@ -77,16 +75,17 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> {
 | 
				
			|||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected List<IConstant> getEntities() {
 | 
					    protected List<IConstant> getEntities() {
 | 
				
			||||||
        final List<IConstant> result = new ArrayList<>(registry.getEntities());
 | 
					        final List<IConstant> entities = new ArrayList<>(registry.getEntities());
 | 
				
			||||||
 | 
					        for (Iterator<IConstant> it = entities.iterator(); it.hasNext(); ) {
 | 
				
			||||||
        Collections.removeAll(result, new JPredicate<IConstant>() {
 | 
					            final IConstant constant = it.next();
 | 
				
			||||||
            @Override
 | 
					            switch (constant.getName()) {
 | 
				
			||||||
            public boolean apply(@Nullable IConstant var) {
 | 
					                case MathType.INFINITY_JSCL:
 | 
				
			||||||
                return var != null && Collections.contains(var.getName(), MathType.INFINITY_JSCL, MathType.NAN);
 | 
					                case MathType.NAN:
 | 
				
			||||||
 | 
					                    it.remove();
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        }
 | 
				
			||||||
 | 
					        return entities;
 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,6 @@ apply plugin: 'java'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
dependencies {
 | 
					dependencies {
 | 
				
			||||||
    compile fileTree(include: ['*.jar'], dir: 'libs')
 | 
					    compile fileTree(include: ['*.jar'], dir: 'libs')
 | 
				
			||||||
    compile 'org.solovyev:common-msg:1.0.7'
 | 
					 | 
				
			||||||
    compile 'com.google.code.findbugs:annotations:2.0.1'
 | 
					    compile 'com.google.code.findbugs:annotations:2.0.1'
 | 
				
			||||||
    compile 'xerces:xercesImpl:2.8.0'
 | 
					    compile 'xerces:xercesImpl:2.8.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,16 +9,16 @@ import jscl.math.operator.Percent;
 | 
				
			|||||||
import jscl.math.operator.Rand;
 | 
					import jscl.math.operator.Rand;
 | 
				
			||||||
import jscl.math.operator.matrix.OperatorsRegistry;
 | 
					import jscl.math.operator.matrix.OperatorsRegistry;
 | 
				
			||||||
import jscl.text.ParseException;
 | 
					import jscl.text.ParseException;
 | 
				
			||||||
import org.solovyev.common.JPredicate;
 | 
					 | 
				
			||||||
import org.solovyev.common.collections.Collections;
 | 
					 | 
				
			||||||
import org.solovyev.common.math.MathRegistry;
 | 
					import org.solovyev.common.math.MathRegistry;
 | 
				
			||||||
import org.solovyev.common.msg.MessageRegistry;
 | 
					import org.solovyev.common.msg.MessageRegistry;
 | 
				
			||||||
import org.solovyev.common.msg.Messages;
 | 
					import org.solovyev.common.msg.Messages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
import java.math.BigDecimal;
 | 
					import java.math.BigDecimal;
 | 
				
			||||||
import java.text.DecimalFormat;
 | 
					import java.text.DecimalFormat;
 | 
				
			||||||
import java.text.DecimalFormatSymbols;
 | 
					import java.text.DecimalFormatSymbols;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Locale;
 | 
					import java.util.Locale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class JsclMathEngine implements MathEngine {
 | 
					public class JsclMathEngine implements MathEngine {
 | 
				
			||||||
@@ -165,20 +165,7 @@ public class JsclMathEngine implements MathEngine {
 | 
				
			|||||||
                    // decimal numeral base => do specific formatting
 | 
					                    // decimal numeral base => do specific formatting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // detect if current number is precisely equals to constant in constants' registry  (NOTE: ONLY FOR SYSTEM CONSTANTS)
 | 
					                    // detect if current number is precisely equals to constant in constants' registry  (NOTE: ONLY FOR SYSTEM CONSTANTS)
 | 
				
			||||||
                    final Double localValue = value;
 | 
					                    IConstant constant = findConstant(getConstantsRegistry().getSystemEntities(), value);
 | 
				
			||||||
                    IConstant constant = Collections.find(getConstantsRegistry().getSystemEntities(), new JPredicate<IConstant>() {
 | 
					 | 
				
			||||||
                        public boolean apply(@Nonnull IConstant constant) {
 | 
					 | 
				
			||||||
                            if (!localValue.equals(constant.getDoubleValue())) {
 | 
					 | 
				
			||||||
                                return false;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            final String name = constant.getName();
 | 
					 | 
				
			||||||
                            if (name.equals(Constants.PI_INV.getName()) || name.equals(Constants.ANS)) {
 | 
					 | 
				
			||||||
                                return false;
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            return !name.equals(Constants.PI.getName()) || getAngleUnits() == AngleUnit.rad;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (constant == null) {
 | 
					                    if (constant == null) {
 | 
				
			||||||
                        final IConstant piInv = this.getConstantsRegistry().get(Constants.PI_INV.getName());
 | 
					                        final IConstant piInv = this.getConstantsRegistry().get(Constants.PI_INV.getName());
 | 
				
			||||||
@@ -231,6 +218,24 @@ public class JsclMathEngine implements MathEngine {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    private IConstant findConstant(@Nonnull List<IConstant> constants, @Nonnull Double value) {
 | 
				
			||||||
 | 
					        for (int i = 0; i < constants.size(); i++) {
 | 
				
			||||||
 | 
					            final IConstant constant = constants.get(i);
 | 
				
			||||||
 | 
					            if (!value.equals(constant.getDoubleValue())) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            final String name = constant.getName();
 | 
				
			||||||
 | 
					            if (name.equals(Constants.PI_INV.getName()) || name.equals(Constants.ANS)) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (!name.equals(Constants.PI.getName()) || getAngleUnits() == AngleUnit.rad) {
 | 
				
			||||||
 | 
					                return constant;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    public String convert(@Nonnull Double value, @Nonnull NumeralBase to) {
 | 
					    public String convert(@Nonnull Double value, @Nonnull NumeralBase to) {
 | 
				
			||||||
        String ungroupedValue;
 | 
					        String ungroupedValue;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@ package jscl.math.function;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import org.solovyev.common.JBuilder;
 | 
					import org.solovyev.common.JBuilder;
 | 
				
			||||||
import org.solovyev.common.math.MathEntity;
 | 
					import org.solovyev.common.math.MathEntity;
 | 
				
			||||||
import org.solovyev.common.text.Strings;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
@@ -50,7 +49,7 @@ public class ExtendedConstant implements Comparable<ExtendedConstant>, IConstant
 | 
				
			|||||||
        final Double doubleValue = constant.getDoubleValue();
 | 
					        final Double doubleValue = constant.getDoubleValue();
 | 
				
			||||||
        if (doubleValue == null) {
 | 
					        if (doubleValue == null) {
 | 
				
			||||||
            final String stringValue = constant.getValue();
 | 
					            final String stringValue = constant.getValue();
 | 
				
			||||||
            if (!Strings.isEmpty(stringValue)) {
 | 
					            if (stringValue != null && stringValue.length() > 0) {
 | 
				
			||||||
                return constant.getName() + " = " + stringValue;
 | 
					                return constant.getName() + " = " + stringValue;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                return constant.getName();
 | 
					                return constant.getName();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								jscl/src/main/java/org/solovyev/common/Converter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								jscl/src/main/java/org/solovyev/common/Converter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										79
									
								
								jscl/src/main/java/org/solovyev/common/EqualsResult.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								jscl/src/main/java/org/solovyev/common/EqualsResult.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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)));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										550
									
								
								jscl/src/main/java/org/solovyev/common/HashCodeBuilder.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										550
									
								
								jscl/src/main/java/org/solovyev/common/HashCodeBuilder.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,550 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								jscl/src/main/java/org/solovyev/common/JBuilder.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								jscl/src/main/java/org/solovyev/common/JBuilder.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								jscl/src/main/java/org/solovyev/common/JPredicate.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								jscl/src/main/java/org/solovyev/common/JPredicate.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										213
									
								
								jscl/src/main/java/org/solovyev/common/Objects.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								jscl/src/main/java/org/solovyev/common/Objects.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,213 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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;
 | 
				
			||||||
 | 
					import javax.annotation.concurrent.GuardedBy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class SynchronizedObject<D> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @GuardedBy("mutex")
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    protected final D delegate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    protected final Object mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected SynchronizedObject(@Nonnull D delegate) {
 | 
				
			||||||
 | 
					        this.delegate = delegate;
 | 
				
			||||||
 | 
					        this.mutex = this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected SynchronizedObject(@Nonnull D delegate, @Nonnull Object mutex) {
 | 
				
			||||||
 | 
					        this.delegate = delegate;
 | 
				
			||||||
 | 
					        this.mutex = mutex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // for manually synchronization it is allows to use mutex
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public Object getMutex() {
 | 
				
			||||||
 | 
					        return mutex;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean equals(Object o) {
 | 
				
			||||||
 | 
					        if (this == o) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!(o instanceof SynchronizedObject)) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final SynchronizedObject that = (SynchronizedObject) o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        synchronized (mutex) {
 | 
				
			||||||
 | 
					            if (!delegate.equals(that.delegate)) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int hashCode() {
 | 
				
			||||||
 | 
					        synchronized (mutex) {
 | 
				
			||||||
 | 
					            return delegate.hashCode();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String toString() {
 | 
				
			||||||
 | 
					        synchronized (mutex) {
 | 
				
			||||||
 | 
					            return delegate.toString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,262 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.collections;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SortedList<T> implements List<T> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private final Comparator<? super T> comparator;
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private List<T> list = new ArrayList<T>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private SortedList(@Nonnull Comparator<? super T> comparator) {
 | 
				
			||||||
 | 
					        this.comparator = comparator;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private SortedList(@Nonnull List<T> list, @Nonnull Comparator<? super T> comparator) {
 | 
				
			||||||
 | 
					        this.list = list;
 | 
				
			||||||
 | 
					        this.comparator = comparator;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static <T> SortedList<T> newInstance(@Nonnull Comparator<? super T> comparator) {
 | 
				
			||||||
 | 
					        return new SortedList<T>(comparator);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static <T> SortedList<T> newInstance(@Nonnull List<T> list, @Nonnull Comparator<? super T> comparator) {
 | 
				
			||||||
 | 
					        return new SortedList<T>(list, comparator);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int size() {
 | 
				
			||||||
 | 
					        return list.size();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean isEmpty() {
 | 
				
			||||||
 | 
					        return list.isEmpty();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean contains(Object o) {
 | 
				
			||||||
 | 
					        return list.contains(o);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Iterator<T> iterator() {
 | 
				
			||||||
 | 
					        final Iterator<T> it = list.iterator();
 | 
				
			||||||
 | 
					        return new Iterator<T>() {
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public boolean hasNext() {
 | 
				
			||||||
 | 
					                return it.hasNext();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public T next() {
 | 
				
			||||||
 | 
					                return it.next();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void remove() {
 | 
				
			||||||
 | 
					                it.remove();
 | 
				
			||||||
 | 
					                // todo serso: think
 | 
				
			||||||
 | 
					                sort();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Object[] toArray() {
 | 
				
			||||||
 | 
					        return list.toArray();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public <T> T[] toArray(@Nonnull T[] a) {
 | 
				
			||||||
 | 
					        return list.toArray(a);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean add(T t) {
 | 
				
			||||||
 | 
					        boolean result = list.add(t);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean remove(Object o) {
 | 
				
			||||||
 | 
					        boolean result = list.remove(o);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean containsAll(@Nonnull Collection<?> c) {
 | 
				
			||||||
 | 
					        return this.list.containsAll(c);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean addAll(@Nonnull Collection<? extends T> c) {
 | 
				
			||||||
 | 
					        boolean result = this.list.addAll(c);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean addAll(int index, @Nonnull Collection<? extends T> c) {
 | 
				
			||||||
 | 
					        boolean result = this.list.addAll(index, c);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean removeAll(@Nonnull Collection<?> c) {
 | 
				
			||||||
 | 
					        boolean result = this.list.removeAll(c);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean retainAll(@Nonnull Collection<?> c) {
 | 
				
			||||||
 | 
					        boolean result = this.list.retainAll(c);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void clear() {
 | 
				
			||||||
 | 
					        this.list.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public T get(int index) {
 | 
				
			||||||
 | 
					        return this.list.get(index);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public T set(int index, T element) {
 | 
				
			||||||
 | 
					        T result = this.list.set(index, element);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void add(int index, T element) {
 | 
				
			||||||
 | 
					        this.list.add(index, element);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public T remove(int index) {
 | 
				
			||||||
 | 
					        T result = this.list.remove(index);
 | 
				
			||||||
 | 
					        sort();
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int indexOf(Object o) {
 | 
				
			||||||
 | 
					        return this.list.indexOf(o);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int lastIndexOf(Object o) {
 | 
				
			||||||
 | 
					        return this.list.lastIndexOf(o);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public ListIterator<T> listIterator() {
 | 
				
			||||||
 | 
					        return listIterator(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public ListIterator<T> listIterator(int index) {
 | 
				
			||||||
 | 
					        final ListIterator<T> it = this.list.listIterator(index);
 | 
				
			||||||
 | 
					        return new ListIterator<T>() {
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public boolean hasNext() {
 | 
				
			||||||
 | 
					                return it.hasNext();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public T next() {
 | 
				
			||||||
 | 
					                return it.next();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public boolean hasPrevious() {
 | 
				
			||||||
 | 
					                return it.hasPrevious();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public T previous() {
 | 
				
			||||||
 | 
					                return it.previous();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public int nextIndex() {
 | 
				
			||||||
 | 
					                return it.nextIndex();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public int previousIndex() {
 | 
				
			||||||
 | 
					                return it.previousIndex();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void remove() {
 | 
				
			||||||
 | 
					                it.remove();
 | 
				
			||||||
 | 
					                sort();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void set(T t) {
 | 
				
			||||||
 | 
					                it.set(t);
 | 
				
			||||||
 | 
					                sort();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void add(T t) {
 | 
				
			||||||
 | 
					                it.add(t);
 | 
				
			||||||
 | 
					                sort();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void sort() {
 | 
				
			||||||
 | 
					        Collections.sort(list, comparator);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<T> subList(int fromIndex, int toIndex) {
 | 
				
			||||||
 | 
					        return this.list.subList(fromIndex, toIndex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								jscl/src/main/java/org/solovyev/common/equals/Equalizer.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								jscl/src/main/java/org/solovyev/common/equals/Equalizer.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface Equalizer<T> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						boolean areEqual(@Nonnull T first, @Nonnull T second);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,87 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -23,7 +23,6 @@
 | 
				
			|||||||
package org.solovyev.common.math;
 | 
					package org.solovyev.common.math;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.solovyev.common.JBuilder;
 | 
					import org.solovyev.common.JBuilder;
 | 
				
			||||||
import org.solovyev.common.collections.Collections;
 | 
					 | 
				
			||||||
import org.solovyev.common.collections.SortedList;
 | 
					import org.solovyev.common.collections.SortedList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
@@ -64,6 +63,22 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
 | 
				
			|||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    private static <E extends MathEntity> E removeByName(@Nonnull List<E> entities, @Nonnull String name) {
 | 
				
			||||||
 | 
					        for (int i = 0; i < entities.size(); i++) {
 | 
				
			||||||
 | 
					            final E entity = entities.get(i);
 | 
				
			||||||
 | 
					            if (entity.getName().equals(name)) {
 | 
				
			||||||
 | 
					                entities.remove(i);
 | 
				
			||||||
 | 
					                return entity;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean areEqual(@Nullable Object l, @Nullable Object r) {
 | 
				
			||||||
 | 
					        return l != null ? l.equals(r) : r == null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Nonnull
 | 
					    @Nonnull
 | 
				
			||||||
    public List<T> getEntities() {
 | 
					    public List<T> getEntities() {
 | 
				
			||||||
        synchronized (this) {
 | 
					        synchronized (this) {
 | 
				
			||||||
@@ -136,8 +151,8 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
 | 
				
			|||||||
    public void remove(@Nonnull T entity) {
 | 
					    public void remove(@Nonnull T entity) {
 | 
				
			||||||
        synchronized (this) {
 | 
					        synchronized (this) {
 | 
				
			||||||
            if (!entity.isSystem()) {
 | 
					            if (!entity.isSystem()) {
 | 
				
			||||||
                final T removed = Collections.removeFirst(this.entities, new MathEntity.Finder<T>(entity.getName()));
 | 
					                final T removed = removeByName(entities, entity.getName());
 | 
				
			||||||
                if(removed != null) {
 | 
					                if (removed != null) {
 | 
				
			||||||
                    this.entityNames.clear();
 | 
					                    this.entityNames.clear();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -174,10 +189,6 @@ public abstract class AbstractMathRegistry<T extends MathEntity> implements Math
 | 
				
			|||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static boolean areEqual(@Nullable Object l, @Nullable Object r) {
 | 
					 | 
				
			||||||
        return l != null ? l.equals(r) : r == null;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public T getById(@Nonnull final Integer id) {
 | 
					    public T getById(@Nonnull final Integer id) {
 | 
				
			||||||
        synchronized (this) {
 | 
					        synchronized (this) {
 | 
				
			||||||
            for (T entity : entities) {
 | 
					            for (T entity : entities) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,10 +22,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package org.solovyev.common.math;
 | 
					package org.solovyev.common.math;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.solovyev.common.JPredicate;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import javax.annotation.Nullable;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public interface MathEntity {
 | 
					public interface MathEntity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,18 +40,4 @@ public interface MathEntity {
 | 
				
			|||||||
    boolean isIdDefined();
 | 
					    boolean isIdDefined();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void copy(@Nonnull MathEntity that);
 | 
					    void copy(@Nonnull MathEntity that);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    class Finder<T extends MathEntity> implements JPredicate<T> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @Nonnull
 | 
					 | 
				
			||||||
        private final String name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public Finder(@Nonnull String name) {
 | 
					 | 
				
			||||||
            this.name = name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public boolean apply(@Nullable T entity) {
 | 
					 | 
				
			||||||
            return entity != null && name.equals(entity.getName());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										134
									
								
								jscl/src/main/java/org/solovyev/common/msg/AbstractMessage.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								jscl/src/main/java/org/solovyev/common/msg/AbstractMessage.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.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;
 | 
				
			||||||
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class AbstractMessage implements Message {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private final String messageCode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private final List<Object> parameters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private final MessageLevel messageLevel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected AbstractMessage(@Nonnull String messageCode, @Nonnull MessageLevel messageType, @Nullable Object... parameters) {
 | 
				
			||||||
 | 
					        this(messageCode, messageType, parameters == null ? Collections.emptyList() : Arrays.asList(parameters));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected AbstractMessage(@Nonnull String messageCode, @Nonnull MessageLevel messageType, @Nonnull List<?> parameters) {
 | 
				
			||||||
 | 
					        this.messageCode = messageCode;
 | 
				
			||||||
 | 
					        this.parameters = new ArrayList<>(parameters);
 | 
				
			||||||
 | 
					        this.messageLevel = messageType;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public String getMessageCode() {
 | 
				
			||||||
 | 
					        return this.messageCode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public List<Object> getParameters() {
 | 
				
			||||||
 | 
					        return java.util.Collections.unmodifiableList(this.parameters);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public MessageLevel getMessageLevel() {
 | 
				
			||||||
 | 
					        return this.messageLevel;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean equals(Object o) {
 | 
				
			||||||
 | 
					        if (this == o) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (o == null || getClass() != o.getClass()) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final AbstractMessage that = (AbstractMessage) o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!Objects.areEqual(parameters, that.parameters, ListEqualizer.newWithNaturalEquals(true))) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!messageCode.equals(that.messageCode)) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (!messageLevel.equals(that.messageLevel)) {
 | 
				
			||||||
 | 
					            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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Method converts message to string setting passed message parameters and translating some of them.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param locale language to which parameters should be translated (if possible)
 | 
				
			||||||
 | 
					     * @return message as string with properly translated and set parameters
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public String getLocalizedMessage(@Nonnull Locale locale) {
 | 
				
			||||||
 | 
					        String result = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final String messagePattern = getMessagePattern(locale);
 | 
				
			||||||
 | 
					        if (!Strings.isEmpty(messagePattern)) {
 | 
				
			||||||
 | 
					            result = Messages.prepareMessage(locale, messagePattern, parameters);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Strings.getNotEmpty(result, messageLevel.getName() + ": message code = " + messageCode);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getLocalizedMessage() {
 | 
				
			||||||
 | 
					        return this.getLocalizedMessage(Locale.getDefault());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    protected abstract String getMessagePattern(@Nonnull Locale locale);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ListMessageRegistry implements MessageRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private final List<Message> messages = new ArrayList<Message>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void addMessage(@Nonnull Message message) {
 | 
				
			||||||
 | 
					        if (!messages.contains(message)) {
 | 
				
			||||||
 | 
					            messages.add(message);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Message getMessage() {
 | 
				
			||||||
 | 
					        return this.messages.remove(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean hasMessage() {
 | 
				
			||||||
 | 
					        return !this.messages.isEmpty();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										67
									
								
								jscl/src/main/java/org/solovyev/common/msg/Message.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								jscl/src/main/java/org/solovyev/common/msg/Message.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Locale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Interface represents translatable user message.
 | 
				
			||||||
 | 
					 * Implementation of this class will likely contains
 | 
				
			||||||
 | 
					 * some logic for translation message according to
 | 
				
			||||||
 | 
					 * it's message code and list of parameters.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public interface Message {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return message code
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public String getMessageCode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return list of message parameters
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public List<Object> getParameters();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return message level
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public MessageLevel getMessageLevel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param locale locate to which current message should be translated
 | 
				
			||||||
 | 
					     * @return message string translated to specified locale
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public String getLocalizedMessage(@Nonnull Locale locale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return message string translated to deault locale (Locale.getDefault())
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public String getLocalizedMessage();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										32
									
								
								jscl/src/main/java/org/solovyev/common/msg/MessageLevel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								jscl/src/main/java/org/solovyev/common/msg/MessageLevel.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					package org.solovyev.common.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * See {@link MessageType} as default implementation of this class
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public interface MessageLevel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final int INFO_LEVEL = 100;
 | 
				
			||||||
 | 
					    public static final int WARNING_LEVEL = 500;
 | 
				
			||||||
 | 
					    public static final int ERROR_LEVEL = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Position of current message level in some message level hierarchy.
 | 
				
			||||||
 | 
					     * By default, one can use {@link MessageType} implementation which uses next levels:
 | 
				
			||||||
 | 
					     * 100         500           1000          level
 | 
				
			||||||
 | 
					     * --------|-----------|--------------|------------->
 | 
				
			||||||
 | 
					     * Info       Warning         Error
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return int message level
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int getMessageLevel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Some string id for level (might be used in logs)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return string level identifier
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    String getName();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Container for messages
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public interface MessageRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Adds message to the registry.
 | 
				
			||||||
 | 
					     * Note: according to the implementation this method doesn't guarantee that new message will be added
 | 
				
			||||||
 | 
					     * in underlying container (e.g. if such message already exists)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param message message to be added
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void addMessage(@Nonnull Message message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return true if there is any message available in the registry
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    boolean hasMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Method returns message from registry and removes it from underlying container
 | 
				
			||||||
 | 
					     * Note: this method must be called after {@link MessageRegistry#hasMessage()}
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return message from the registry
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    Message getMessage();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										65
									
								
								jscl/src/main/java/org/solovyev/common/msg/MessageType.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								jscl/src/main/java/org/solovyev/common/msg/MessageType.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum MessageType implements MessageLevel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error(ERROR_LEVEL, "ERROR"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    warning(WARNING_LEVEL, "WARNING"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    info(INFO_LEVEL, "INFO");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final int messageLevel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private final String stringValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MessageType(int messageLevel, @Nonnull String stringValue) {
 | 
				
			||||||
 | 
					        this.messageLevel = messageLevel;
 | 
				
			||||||
 | 
					        this.stringValue = stringValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static MessageType getLowestMessageType() {
 | 
				
			||||||
 | 
					        return info;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public String getStringValue() {
 | 
				
			||||||
 | 
					        return stringValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getMessageLevel() {
 | 
				
			||||||
 | 
					        return messageLevel;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getName() {
 | 
				
			||||||
 | 
					        return stringValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										86
									
								
								jscl/src/main/java/org/solovyev/common/msg/Messages.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								jscl/src/main/java/org/solovyev/common/msg/Messages.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
 | 
					import java.text.MessageFormat;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Locale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public final class Messages {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Messages() {
 | 
				
			||||||
 | 
					        throw new AssertionError();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static MessageRegistry synchronizedMessageRegistry(@Nonnull MessageRegistry messageRegistry) {
 | 
				
			||||||
 | 
					        return SynchronizedMessageRegistry.wrap(messageRegistry);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param locale         locale for which default formatting will be applied
 | 
				
			||||||
 | 
					     * @param messagePattern message pattern which will be used for {@link MessageFormat}
 | 
				
			||||||
 | 
					     * @param parameters     message parameters which will be used for {@link MessageFormat}
 | 
				
			||||||
 | 
					     * @return formatted message string according to default locale formatting, nested messages are processed properly
 | 
				
			||||||
 | 
					     * (for each message from parameter method {@link Message#getLocalizedMessage(Locale)} is called)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static String prepareMessage(@Nonnull Locale locale, @Nonnull String messagePattern, @Nonnull List<?> parameters) {
 | 
				
			||||||
 | 
					        String result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (parameters.isEmpty()) {
 | 
				
			||||||
 | 
					            result = messagePattern;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            final MessageFormat format = new MessageFormat(messagePattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            format.setLocale(locale);
 | 
				
			||||||
 | 
					            format.applyPattern(messagePattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            result = format.format(prepareParameters(parameters, locale));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    private static Object[] prepareParameters(@Nonnull List<?> parameters, @Nonnull Locale locale) {
 | 
				
			||||||
 | 
					        final Object[] result = new Object[parameters.size()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = 0; i < parameters.size(); i++) {
 | 
				
			||||||
 | 
					            result[i] = substituteParameter(parameters.get(i), locale);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nullable
 | 
				
			||||||
 | 
					    private static Object substituteParameter(@Nullable Object object, @Nonnull Locale locale) {
 | 
				
			||||||
 | 
					        if (object instanceof Message) {
 | 
				
			||||||
 | 
					            return ((Message) object).getLocalizedMessage(locale);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return object;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.solovyev.common.SynchronizedObject;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SynchronizedMessageRegistry extends SynchronizedObject<MessageRegistry> implements MessageRegistry {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private SynchronizedMessageRegistry(@Nonnull MessageRegistry delegate) {
 | 
				
			||||||
 | 
					        super(delegate);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private SynchronizedMessageRegistry(@Nonnull MessageRegistry delegate, @Nonnull Object mutex) {
 | 
				
			||||||
 | 
					        super(delegate, mutex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static MessageRegistry wrap(@Nonnull MessageRegistry delegate) {
 | 
				
			||||||
 | 
					        return new SynchronizedMessageRegistry(delegate);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static MessageRegistry wrap(@Nonnull MessageRegistry delegate, @Nonnull Object mutex) {
 | 
				
			||||||
 | 
					        return new SynchronizedMessageRegistry(delegate, mutex);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public void addMessage(@Nonnull Message message) {
 | 
				
			||||||
 | 
					        synchronized (this.mutex) {
 | 
				
			||||||
 | 
					            delegate.addMessage(message);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public boolean hasMessage() {
 | 
				
			||||||
 | 
					        synchronized (this.mutex) {
 | 
				
			||||||
 | 
					            return delegate.hasMessage();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Message getMessage() {
 | 
				
			||||||
 | 
					        synchronized (this.mutex) {
 | 
				
			||||||
 | 
					            return delegate.getMessage();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										60
									
								
								jscl/src/main/java/org/solovyev/common/msg/Utf8Control.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								jscl/src/main/java/org/solovyev/common/msg/Utf8Control.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					package org.solovyev.common.msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
 | 
					import java.io.InputStreamReader;
 | 
				
			||||||
 | 
					import java.net.URL;
 | 
				
			||||||
 | 
					import java.net.URLConnection;
 | 
				
			||||||
 | 
					import java.util.Locale;
 | 
				
			||||||
 | 
					import java.util.PropertyResourceBundle;
 | 
				
			||||||
 | 
					import java.util.ResourceBundle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Utf8Control extends ResourceBundle.Control {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Nonnull
 | 
				
			||||||
 | 
						private static final ResourceBundle.Control instance = new Utf8Control();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Nonnull
 | 
				
			||||||
 | 
						public static ResourceBundle.Control getInstance() {
 | 
				
			||||||
 | 
							return instance;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private Utf8Control() {
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
 | 
				
			||||||
 | 
							final ResourceBundle result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// The below is a copy of the default implementation.
 | 
				
			||||||
 | 
							final String bundleName = toBundleName(baseName, locale);
 | 
				
			||||||
 | 
							final String resourceName = toResourceName(bundleName, "properties");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							InputStream stream = null;
 | 
				
			||||||
 | 
							if (reload) {
 | 
				
			||||||
 | 
								final URL url = loader.getResource(resourceName);
 | 
				
			||||||
 | 
								if (url != null) {
 | 
				
			||||||
 | 
									final URLConnection connection = url.openConnection();
 | 
				
			||||||
 | 
									if (connection != null) {
 | 
				
			||||||
 | 
										connection.setUseCaches(false);
 | 
				
			||||||
 | 
										stream = connection.getInputStream();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								stream = loader.getResourceAsStream(resourceName);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (stream != null) {
 | 
				
			||||||
 | 
								try {
 | 
				
			||||||
 | 
									// Only this line is changed to make it to read properties files as UTF-8.
 | 
				
			||||||
 | 
									result = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
 | 
				
			||||||
 | 
								} finally {
 | 
				
			||||||
 | 
									stream.close();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								result = null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.search;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.solovyev.common.JPredicate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class StartsWithFinder implements JPredicate<String> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Nonnull
 | 
				
			||||||
 | 
						private final String targetString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private StartsWithFinder(@Nonnull String targetString, int i) {
 | 
				
			||||||
 | 
							this.targetString = targetString;
 | 
				
			||||||
 | 
							this.i = i;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Nonnull
 | 
				
			||||||
 | 
						public static StartsWithFinder newFrom(@Nonnull String targetString, int i) {
 | 
				
			||||||
 | 
							return new StartsWithFinder(targetString, i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Nonnull
 | 
				
			||||||
 | 
						public static StartsWithFinder newInstance(@Nonnull String targetString) {
 | 
				
			||||||
 | 
							return newFrom(targetString, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public boolean apply(@Nullable String s) {
 | 
				
			||||||
 | 
							return s != null && targetString.startsWith(s, i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setI(int i) {
 | 
				
			||||||
 | 
							this.i = i;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										83
									
								
								jscl/src/main/java/org/solovyev/common/text/Strings.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								jscl/src/main/java/org/solovyev/common/text/Strings.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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.text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
 | 
					import javax.annotation.Nullable;
 | 
				
			||||||
 | 
					import java.util.Date;
 | 
				
			||||||
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class Strings {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
 | 
				
			||||||
 | 
					    public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
 | 
				
			||||||
 | 
					    // random variable: must be synchronized in usage
 | 
				
			||||||
 | 
					    private static final Random RANDOM = new Random(new Date().getTime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // not intended for instantiation
 | 
				
			||||||
 | 
					    protected Strings() {
 | 
				
			||||||
 | 
					        throw new AssertionError();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean isEmpty(@Nullable CharSequence s) {
 | 
				
			||||||
 | 
					        return s == null || s.length() == 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static String getNotEmpty(@Nullable CharSequence s, @Nonnull String defaultValue) {
 | 
				
			||||||
 | 
					        return isEmpty(s) ? defaultValue : s.toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static Character[] toObjects(char[] array) {
 | 
				
			||||||
 | 
					        if (array == null || array.length == 0) {
 | 
				
			||||||
 | 
					            return EMPTY_CHARACTER_OBJECT_ARRAY;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final Character[] result = new Character[array.length];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = 0; i < array.length; i++) {
 | 
				
			||||||
 | 
					            result[i] = array[i];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Nonnull
 | 
				
			||||||
 | 
					    public static String generateRandomString(int length) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final StringBuilder result = new StringBuilder(length);
 | 
				
			||||||
 | 
					        for (int i = 0; i < length; i++) {
 | 
				
			||||||
 | 
					            final char ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            synchronized (RANDOM) {
 | 
				
			||||||
 | 
					                // 'A' = 65
 | 
				
			||||||
 | 
					                ch = (char) (RANDOM.nextInt(52) + 65);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            result.append(ch);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return result.toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user