Merge pull request #48 from TouchInstinct/rxjava2/validation
validation
This commit is contained in:
commit
cf47237e49
|
|
@ -4,11 +4,13 @@ import android.support.annotation.NonNull;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.reactivex.functions.Function;
|
||||
|
||||
/**
|
||||
* Created by Ilia Kurtov on 30/01/2017.
|
||||
* Simple interface that gets one parameter with {@link TInput} type as input and returns other type {@link TReturn} as a result.
|
||||
* Interface extends {@link Serializable} to survive after {@link ru.touchin.roboswag.components.navigation.AbstractState} recreation.
|
||||
* Created as a replace for {@link rx.functions.Func1} because it needed to be {@link Serializable}
|
||||
* Created as a replace for {@link Function} because it needed to be {@link Serializable}
|
||||
*
|
||||
* @param <TInput> input type.
|
||||
* @param <TReturn> return type.
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public class BooleanValidationController extends ValidationController<Boolean, B
|
|||
|
||||
/**
|
||||
* This method validates bounded view.
|
||||
*
|
||||
* @param activatedObservable emits true when we need to show error on empty fields. Eg when user clicks on Done button but he missed some
|
||||
* necessary fields to fill.
|
||||
* @return observable without any concrete type. Simply subscribe to this method to make it works.
|
||||
|
|
@ -45,7 +46,7 @@ public class BooleanValidationController extends ValidationController<Boolean, B
|
|||
public Observable<?> validation(@NonNull final Observable<Boolean> activatedObservable) {
|
||||
return Observable.combineLatest(activatedObservable, getValidator().getWrapperModel().observe(),
|
||||
(activated, flag) -> {
|
||||
final boolean selected = flag == null ? false : flag;
|
||||
final boolean selected = flag.get() == null ? false : flag.get();
|
||||
if (activated && !selected) {
|
||||
return ValidationState.ERROR_NO_DESCRIPTION;
|
||||
} else if (!activated && !selected) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import android.text.TextUtils;
|
|||
import java.io.Serializable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import ru.touchin.roboswag.core.utils.Optional;
|
||||
import ru.touchin.roboswag.core.utils.pairs.NonNullPair;
|
||||
import ru.touchin.templates.validation.ValidationState;
|
||||
import ru.touchin.templates.validation.validators.EditTextValidator;
|
||||
|
|
@ -77,9 +78,10 @@ public class EditTextValidationController<TModel extends Serializable>
|
|||
@Nullable
|
||||
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
|
||||
private NonNullPair<Boolean, Observable<ValidationState>> getValidationPair(final boolean activated,
|
||||
@Nullable final String text,
|
||||
@NonNull Optional<String> optionalText,
|
||||
@Nullable final Boolean focusIn,
|
||||
final boolean showError) {
|
||||
final String text = optionalText.get();
|
||||
if (focusIn == null && TextUtils.isEmpty(text) && !activated && !showError) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -98,8 +100,7 @@ public class EditTextValidationController<TModel extends Serializable>
|
|||
/**
|
||||
* If we don't want to show error when focus is lost.
|
||||
*
|
||||
* @param showErrorOnFocusOut show an error or don't show an error.
|
||||
*
|
||||
* @param showErrorOnFocusOut show an error or don't show an error.
|
||||
*/
|
||||
public void setShowErrorOnFocusOut(final boolean showErrorOnFocusOut) {
|
||||
this.showErrorOnFocusOut = showErrorOnFocusOut;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import ru.touchin.templates.validation.validators.Validator;
|
|||
* Created by Ilia Kurtov on 24/01/2017.
|
||||
* {@link ValidationController} for models that have the same modal as wrapper model. You can use it when you simply need to be sure
|
||||
* that user have selected some item and it is not null.
|
||||
* @param <TModel> type of the model.
|
||||
*
|
||||
* @param <TModel> type of the model.
|
||||
* @param <TValidator> corresponding {@link Validator}
|
||||
*/
|
||||
public class SimpleValidationController<TModel extends Serializable, TValidator extends Validator<TModel, TModel>>
|
||||
|
|
@ -24,6 +25,7 @@ public class SimpleValidationController<TModel extends Serializable, TValidator
|
|||
|
||||
/**
|
||||
* This method validates bounded view.
|
||||
*
|
||||
* @param activatedObservable emits true when we need to show error on empty fields. Eg when user clicks on Done button but he missed some
|
||||
* necessary fields to fill.
|
||||
* @return observable without any concrete type. Simply subscribe to this method to make it works.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.io.Serializable;
|
|||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import ru.touchin.roboswag.core.utils.Optional;
|
||||
import ru.touchin.templates.validation.ValidationState;
|
||||
import ru.touchin.templates.validation.ViewWithError;
|
||||
import ru.touchin.templates.validation.validators.Validator;
|
||||
|
|
@ -53,22 +54,24 @@ public class ValidationController
|
|||
/**
|
||||
* Bind to this observable to connect view and model. If you provide first argument (viewStateObservable) - the connection would be two-way.
|
||||
* If not - one-way. This method changes updates view with current {@link ValidationState}.
|
||||
*
|
||||
* @param viewStateObservable input view state {@link Observable}.
|
||||
* Eg it can be observable with input text from the {@link android.widget.EditText}
|
||||
* @param updateViewAction action that updates current state of the bounded view.
|
||||
* @param viewWithError view that implements {@link ViewWithError} interface and could reacts to the validation errors.
|
||||
* @param updateViewAction action that updates current state of the bounded view.
|
||||
* @param viewWithError view that implements {@link ViewWithError} interface and could reacts to the validation errors.
|
||||
* @return observable without any concrete type. Simply subscribe to this method to make it works.
|
||||
*/
|
||||
@NonNull
|
||||
public Observable<?> modelAndViewUpdating(@Nullable final Observable<TWrapperModel> viewStateObservable,
|
||||
@NonNull final Consumer<TWrapperModel> updateViewAction,
|
||||
@NonNull final Consumer<Optional<TWrapperModel>> updateViewAction,
|
||||
@NonNull final ViewWithError viewWithError) {
|
||||
|
||||
final Observable<?> stateObservable = viewStateObservable != null
|
||||
? viewStateObservable.doOnNext(flag -> getValidator().getWrapperModel().set(flag))
|
||||
: Observable.empty();
|
||||
return Observable
|
||||
.merge(getValidator().getWrapperModel().observe()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnNext(updateViewAction),
|
||||
getValidator().getValidationState().observe()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
@ -84,6 +87,7 @@ public class ValidationController
|
|||
|
||||
/**
|
||||
* Helper function to check if validation state in error state ot not
|
||||
*
|
||||
* @param validationState the state you want to check for the errors.
|
||||
* @return true if validation state is in error and false otherwise.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import android.support.annotation.Nullable;
|
|||
import java.io.Serializable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import ru.touchin.roboswag.core.observables.Changeable;
|
||||
import ru.touchin.roboswag.core.observables.NonNullChangeable;
|
||||
|
|
@ -51,6 +52,7 @@ public abstract class EditTextValidator<TModel extends Serializable> extends Val
|
|||
* This flag needed to force showing errors. You don't want to show final error when you start to enter data in some field at first time.
|
||||
* But if user leaves this view and final check not passed - you need to force to show an error till user not enters correct data and leaves
|
||||
* the view.
|
||||
*
|
||||
* @return {@link NonNullChangeable} with current state of the flag - do we need to show errors from final checks while user types.
|
||||
*/
|
||||
@NonNull
|
||||
|
|
@ -60,6 +62,7 @@ public abstract class EditTextValidator<TModel extends Serializable> extends Val
|
|||
|
||||
/**
|
||||
* Use this method to get or set final check.
|
||||
*
|
||||
* @return final check.
|
||||
*/
|
||||
@NonNull
|
||||
|
|
@ -69,6 +72,7 @@ public abstract class EditTextValidator<TModel extends Serializable> extends Val
|
|||
|
||||
/**
|
||||
* Use this method to get or set primary check.
|
||||
*
|
||||
* @return primary check.
|
||||
*/
|
||||
@NonNull
|
||||
|
|
@ -104,21 +108,16 @@ public abstract class EditTextValidator<TModel extends Serializable> extends Val
|
|||
primaryCheck.observe().observeOn(Schedulers.computation()),
|
||||
(finalCheck, primaryCheck) -> {
|
||||
try {
|
||||
return validateText(finalCheck, primaryCheck, text, fullCheck);
|
||||
return validateText(finalCheck.get(), primaryCheck.get(), text, fullCheck);
|
||||
} catch (final Throwable exception) {
|
||||
return new HalfNullablePair<>(ValidationState.ERROR_CONVERSION, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Observable<ValidationState> processChecks(@NonNull final String text, final boolean fullCheck) {
|
||||
return createValidationObservable(text, fullCheck)
|
||||
.map(HalfNullablePair::getFirst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates text with primary check.
|
||||
*
|
||||
* @param text - input text.
|
||||
* @return {@link Observable} with the result of the primary check.
|
||||
*/
|
||||
|
|
@ -129,6 +128,7 @@ public abstract class EditTextValidator<TModel extends Serializable> extends Val
|
|||
|
||||
/**
|
||||
* Validates text with final check.
|
||||
*
|
||||
* @param text - input text.
|
||||
* @return {@link Observable} with the result of the final check.
|
||||
*/
|
||||
|
|
@ -140,15 +140,21 @@ public abstract class EditTextValidator<TModel extends Serializable> extends Val
|
|||
/**
|
||||
* Validates text with primary and final check consequentially and returns {@link Observable} with {@link HalfNullablePair} of final state
|
||||
* and resulting model.
|
||||
*
|
||||
* @param text - input text.
|
||||
* @return pair with final {@link ValidationState} that is always not null and a model that we get after converting the text.
|
||||
* Model can be null if validation fails on primary or final checks.
|
||||
* Model can be null if validation fails on primary or final checks.
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public Observable<HalfNullablePair<ValidationState, TModel>> fullValidateAndGetModel(@NonNull final String text) {
|
||||
return createValidationObservable(text, true)
|
||||
.first();
|
||||
return createValidationObservable(text, true);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Observable<ValidationState> processChecks(@NonNull final String text, final boolean fullCheck) {
|
||||
return createValidationObservable(text, fullCheck)
|
||||
.map(HalfNullablePair::getFirst);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,19 +5,21 @@ import android.support.annotation.NonNull;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import ru.touchin.roboswag.core.utils.pairs.HalfNullablePair;
|
||||
import ru.touchin.templates.validation.ValidationState;
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
* Created by Ilia Kurtov on 24/01/2017.
|
||||
* Class that simplifies work with {@link Validator}'s that have the same wrapper model and model type.
|
||||
*
|
||||
* @param <TModel> model that should be bounded with a view.
|
||||
*/
|
||||
public class SameTypeValidator<TModel extends Serializable> extends Validator<TModel, TModel> {
|
||||
|
||||
/**
|
||||
* Simply returns the same model without any converting.
|
||||
*
|
||||
* @param wrapperModel input model.
|
||||
* @return the same model as input parameter.
|
||||
* @throws Throwable - in this case no throwable would be thrown.
|
||||
|
|
@ -31,9 +33,10 @@ public class SameTypeValidator<TModel extends Serializable> extends Validator<TM
|
|||
|
||||
/**
|
||||
* Validates {@link TModel} and returns {@link Observable} with {@link HalfNullablePair} of final state and resulting model.
|
||||
*
|
||||
* @param wrapperModel - not null value that should be validated.
|
||||
* @return pair with final {@link ValidationState} that is always not null and a model that we get after converting the {@link TModel}.
|
||||
* Model can be null if validation fails.
|
||||
* Model can be null if validation fails.
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import android.support.annotation.NonNull;
|
|||
import java.io.Serializable;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import ru.touchin.roboswag.core.observables.Changeable;
|
||||
import ru.touchin.roboswag.core.observables.NonNullChangeable;
|
||||
import ru.touchin.roboswag.core.utils.pairs.HalfNullablePair;
|
||||
|
|
@ -54,6 +55,7 @@ public abstract class Validator<TWrapperModel extends Serializable, TModel exten
|
|||
|
||||
/**
|
||||
* This method converts {@link TWrapperModel} into a {@link TModel}.
|
||||
*
|
||||
* @param wrapperModel - not null value that should be converted into a {@link TModel} object.
|
||||
* @return converted wrapperModel into a {@link TModel}.
|
||||
* @throws Throwable for the cases when converting cannot be processed.
|
||||
|
|
@ -63,6 +65,7 @@ public abstract class Validator<TWrapperModel extends Serializable, TModel exten
|
|||
|
||||
/**
|
||||
* Call this method to get {@link Changeable} with {@link TWrapperModel} inside it that should be connected to its bounded view.
|
||||
*
|
||||
* @return {@link Changeable} with {@link TWrapperModel}.
|
||||
*/
|
||||
@NonNull
|
||||
|
|
@ -72,6 +75,7 @@ public abstract class Validator<TWrapperModel extends Serializable, TModel exten
|
|||
|
||||
/**
|
||||
* Returns current {@link ValidationState} or its successor. Needed to connect with bounded view and react to this state changes.
|
||||
*
|
||||
* @return current validation state.
|
||||
*/
|
||||
@NonNull
|
||||
|
|
@ -82,6 +86,7 @@ public abstract class Validator<TWrapperModel extends Serializable, TModel exten
|
|||
/**
|
||||
* This method needed to get {@link ValidationState} that needed to be shown when bounded view is empty and you need to show to user reminder,
|
||||
* that he or she needs to fill this view.
|
||||
*
|
||||
* @return {@link ValidationState} that should be shown for an empty field.
|
||||
*/
|
||||
@NonNull
|
||||
|
|
@ -90,10 +95,11 @@ public abstract class Validator<TWrapperModel extends Serializable, TModel exten
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates {@link TWrapperModel} and returns {@link Observable} with {@link HalfNullablePair} of final state and resulting model.
|
||||
* Validates {@link TWrapperModel} and returns {@link Single} with {@link HalfNullablePair} of final state and resulting model.
|
||||
*
|
||||
* @param wrapperModel - not null value that should be validated.
|
||||
* @return pair with final {@link ValidationState} that is always not null and a model that we get after converting the {@link TWrapperModel}.
|
||||
* Model can be null if validation fails.
|
||||
* Model can be null if validation fails.
|
||||
*/
|
||||
@NonNull
|
||||
public abstract Observable<HalfNullablePair<ValidationState, TModel>> fullValidateAndGetModel(@NonNull final TWrapperModel wrapperModel);
|
||||
|
|
|
|||
Loading…
Reference in New Issue