Skip to content

Commit

Permalink
gs-reactor: Use Observable<Boolean> to define TagSwitcher
Browse files Browse the repository at this point in the history
  • Loading branch information
fducroquet committed Oct 4, 2017
1 parent f24f3bc commit d534c26
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,7 @@ public static <T> Observable<T> prevFromObservableValue(final ObservableValue<T>

private static <T> Observable<Optional<T>> fromNullableObservableValue(final ObservableValue<T> fxObservable) {
return Observable.create((ObservableEmitter<Optional<T>> emitter) -> {
if (fxObservable.getValue() != null) {
emitter.onNext(Optional.of(fxObservable.getValue()));
}
emitter.onNext(Optional.ofNullable(fxObservable.getValue()));

final ChangeListener<T> listener = (observableValue, prev, current) -> {
emitter.onNext(Optional.ofNullable(current));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.io.File;

import org.genericsystem.api.core.Snapshot;
import org.genericsystem.common.Generic;
import org.genericsystem.common.Root;
import org.genericsystem.cv.comparator.ImgFilterFunction;
import org.genericsystem.cv.model.Doc;
Expand All @@ -15,133 +14,123 @@
import org.genericsystem.cv.model.ZoneGeneric.ZoneInstance;
import org.genericsystem.cv.model.ZoneText;
import org.genericsystem.cv.model.ZoneText.ZoneTextInstance;
import org.genericsystem.defaults.tools.RxJavaHelpers;
import org.genericsystem.ir.DistributedVerticle;
import org.genericsystem.reactor.Context;
import org.genericsystem.reactor.Tag;
import org.genericsystem.reactor.context.TagSwitcher;

import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import io.reactivex.Observable;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;

public class DocPropertiesSwitcher {

private static final String ZONES_FILE_BASE_PATH = DistributedVerticle.BASE_PATH + "/classes/";

public static class DOC_CLASS_EMPTY implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isDocClassEmpty(context, false);
}
}

public static class DOC_CLASS_NOT_EMPTY implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isDocClassEmpty(context, true);
}
}

public static class SUPERVISION_AVAILABLE implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isSupervisionAvailable(context, false);
}
}

public static class SUPERVISION_NOT_AVAILABLE implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isSupervisionAvailable(context, true);
}
}

public static class DOC_DEZONED implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isClassZoneFilePresent(context, false);
}
}

public static class DOC_NOT_DEZONED implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isClassZoneFilePresent(context, true);
}
}

public static class DOC_OCRD implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isDocOcrd(context, false);
}
}

public static class DOC_NOT_OCRD implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isDocOcrd(context, true);
}
}

public static class DOC_SUPERVISED implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isDocSupervised(context, false);
}
}

public static class DOC_NOT_SUPERVISED implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
return isDocSupervised(context, true);
}
}

public static ObservableValue<Boolean> isDocClassEmpty(Context context, boolean reverse) {
public static Observable<Boolean> isDocClassEmpty(Context context, boolean reverse) {
DocClassInstance currentDocClass = (DocClassInstance) context.getGeneric();
Doc doc = context.getGeneric().getRoot().find(Doc.class);
ObservableList<Generic> docInstances = currentDocClass.getHolders(doc).toObservableList();
BooleanBinding binding = Bindings.createBooleanBinding(() -> {
return null == docInstances || docInstances.isEmpty();
}, docInstances);
return reverse ? binding.not() : binding;
return currentDocClass.getHolders(doc).setOnChanged().map(set -> reverse ? !set.isEmpty() : set.isEmpty());
}

public static ObservableValue<Boolean> isSupervisionAvailable(Context context, boolean reverse) {
public static Observable<Boolean> isSupervisionAvailable(Context context, boolean reverse) {
DocClassInstance currentDocClass = (DocClassInstance) context.getGeneric();
BooleanBinding binding = getBooleanBinding(currentDocClass.getValue().toString());
return reverse ? binding.not() : binding;
Observable<Boolean> binding = getBooleanBinding(currentDocClass.getValue().toString());
return reverse ? binding.map(bool -> !bool) : binding;
}

public static ObservableValue<Boolean> isClassZoneFilePresent(Context context, boolean reverse) {
public static Observable<Boolean> isClassZoneFilePresent(Context context, boolean reverse) {
DocInstance currentDoc = (DocInstance) context.getGeneric();
DocClassInstance docClassInstance = currentDoc.getDocClass();
BooleanBinding binding = getBooleanBinding(docClassInstance.getValue().toString());
return reverse ? binding.not() : binding;
Observable<Boolean> binding = getBooleanBinding(docClassInstance.getValue().toString());
return reverse ? binding.map(bool -> !bool) : binding;
}

private static BooleanBinding getBooleanBinding(String docClass) {
private static Observable<Boolean> getBooleanBinding(String docClass) {
ObjectProperty<File> file = new SimpleObjectProperty<>(new File(ZONES_FILE_BASE_PATH + docClass + "/zones/zones.json"));
BooleanBinding binding = Bindings.createBooleanBinding(() -> {
return null != file.get() && file.get().exists();
}, file);
return binding;
return RxJavaHelpers.optionalValuesOf(file).map(opt -> opt.isPresent() && opt.get().exists());
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public static ObservableValue<Boolean> isDocOcrd(Context context, boolean reverse) {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Observable<Boolean> isDocOcrd(Context context, boolean reverse) {
DocInstance currentDoc = (DocInstance) context.getGeneric();
Root root = currentDoc.getRoot();
ZoneText zoneText = root.find(ZoneText.class);
ZoneGeneric zoneGeneric = root.find(ZoneGeneric.class);
// The original image should ALWAYS exist
ImgFilterInstance imgFilterInstance = ((ImgFilter) root.find(ImgFilter.class)).getImgFilter(ImgFilterFunction.ORIGINAL.getName());
ObservableList<ZoneTextInstance> zoneTextInstances = (ObservableList) currentDoc.getHolders(zoneText).toObservableList();
BooleanBinding binding = Bindings.createBooleanBinding(() -> {
Observable<Boolean> obs = currentDoc.getHolders(zoneText).setOnChanged().map(zoneTextInstances -> {
Snapshot<ZoneInstance> zoneInstances = (Snapshot) currentDoc.getDocClass().getHolders(zoneGeneric);
// Consider the document as not OCR'd when the class was not de-zoned
if (zoneInstances.isEmpty())
Expand All @@ -153,25 +142,17 @@ public static ObservableValue<Boolean> isDocOcrd(Context context, boolean revers
return null != zti;
});
}
}, zoneTextInstances);
return reverse ? binding.not() : binding;
});
return reverse ? obs.map(bool -> !bool) : obs;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static ObservableValue<Boolean> isDocSupervised(Context context, boolean reverse) {
public static Observable<Boolean> isDocSupervised(Context context, boolean reverse) {
// TODO: will a document be considered as not supervised if a field needs to be left empty?
DocInstance currentDoc = (DocInstance) context.getGeneric();
Root root = currentDoc.getRoot();
ZoneText zoneText = root.find(ZoneText.class);
ObservableList<ZoneTextInstance> zoneTextInstances = (ObservableList) currentDoc.getHolders(zoneText).toObservableList().filtered(zt -> "reality".equals(((ZoneTextInstance) zt).getImgFilter().getValue()));
BooleanBinding binding = Bindings.createBooleanBinding(() -> {
if (zoneTextInstances.isEmpty()) {
return false;
} else {
// If any field is empty, return false otherwise true
return !zoneTextInstances.stream().anyMatch(g -> "".equals(g.getValue().toString()));
}
}, zoneTextInstances);
return reverse ? binding.not() : binding;
Observable<Boolean> obs = currentDoc.getHolders(zoneText).filter(zt -> "reality".equals(((ZoneTextInstance) zt).getImgFilter().getValue()))
.setOnChanged().map(zoneTextInstances -> !zoneTextInstances.isEmpty() && !zoneTextInstances.stream().anyMatch(g -> "".equals(g.getValue().toString())));
return reverse ? obs.map(bool -> !bool) : obs;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.genericsystem.ir.app.gui.utils;

import org.genericsystem.defaults.tools.RxJavaHelpers;
import org.genericsystem.reactor.Context;
import org.genericsystem.reactor.Tag;
import org.genericsystem.reactor.context.TagSwitcher;

import javafx.beans.binding.Bindings;
import io.reactivex.Observable;
import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue;

public class PageSwitcher {

Expand All @@ -16,17 +16,17 @@ public class PageSwitcher {

public static class HOME_PAGE implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
Property<String> pageProperty = tag.getContextProperty(PAGE, context);
return Bindings.createBooleanBinding(() -> HOME_PAGE.equals(pageProperty.getValue()), pageProperty);
return RxJavaHelpers.optionalValuesOf(pageProperty).map(opt -> opt.isPresent() && HOME_PAGE.equals(opt.get()));
}
}

public static class FILTERS_STATISTICS implements TagSwitcher {
@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
Property<String> pageProperty = tag.getContextProperty(PAGE, context);
return Bindings.createBooleanBinding(() -> FILTERS_STATISTICS.equals(pageProperty.getValue()), pageProperty);
return RxJavaHelpers.optionalValuesOf(pageProperty).map(opt -> opt.isPresent() && FILTERS_STATISTICS.equals(opt.get()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import org.genericsystem.api.core.Snapshot;
import org.genericsystem.common.Generic;
import org.genericsystem.defaults.tools.RxJavaHelpers;
import org.genericsystem.quiz.model.Answer;
import org.genericsystem.quiz.model.Description;
import org.genericsystem.quiz.model.Question;
Expand All @@ -16,9 +17,7 @@
import org.genericsystem.reactor.context.TagSwitcher;

import io.reactivex.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue;

public class QuizExtractors {

Expand Down Expand Up @@ -69,23 +68,23 @@ public Generic apply(Generic[] generics) {
public static class FILTER_QUIZ implements TagSwitcher {

@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
if (tag.getContextProperty(QuizContextAction.SELECTED_QUIZ, context) == null)
tag.getRootTag().createNewContextProperty(QuizContextAction.SELECTED_QUIZ, context.getRootContext());
Property<Generic> selectedQuiz = tag.getContextProperty(QuizContextAction.SELECTED_QUIZ, context);
return Bindings.createBooleanBinding(() -> selectedQuiz.getValue() == null || context.getGeneric().getComponent(1).equals(selectedQuiz.getValue()), selectedQuiz);
return RxJavaHelpers.optionalValuesOf(selectedQuiz).map(optQuiz -> !optQuiz.isPresent() || context.getGeneric().getComponent(1).equals(optQuiz.get()));
}
}

public static class FILTER_USER implements TagSwitcher {

@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
if (tag.getContextProperty(QuizContextAction.SELECTED_USER, context) == null)
tag.getRootTag().createNewContextProperty(QuizContextAction.SELECTED_USER, context.getRootContext());
Property<String> selectedUser = tag.getContextProperty(QuizContextAction.SELECTED_USER, context);
return Bindings.createBooleanBinding(() -> selectedUser.getValue() == null || selectedUser.getValue().trim().isEmpty() ||
((String) context.getGeneric().getComponent(0).getValue()).trim().toLowerCase().contains(selectedUser.getValue().trim().toLowerCase()), selectedUser);
return RxJavaHelpers.optionalValuesOf(selectedUser).map(optUser -> !optUser.isPresent() || optUser.get().trim().isEmpty()
|| ((String) context.getGeneric().getComponent(0).getValue()).trim().toLowerCase().contains(optUser.get().trim().toLowerCase()));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package org.genericsystem.quiz.utils;

import org.genericsystem.common.Generic;
import org.genericsystem.defaults.tools.RxJavaHelpers;
import org.genericsystem.quiz.model.Quiz;
import org.genericsystem.quiz.model.ScoreUserQuiz;
import org.genericsystem.reactor.Context;
import org.genericsystem.reactor.Tag;
import org.genericsystem.reactor.context.TagSwitcher;

import javafx.beans.binding.Bindings;
import io.reactivex.Observable;
import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue;

public class QuizTagSwitcher {

Expand All @@ -21,7 +21,7 @@ public class QuizTagSwitcher {
public static class QUIZ_NOT_DONE implements TagSwitcher {

@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
Property<Generic> loggedUser = tag.getLoggedUserProperty(context);
Generic quiz = context.getGeneric();

Expand All @@ -30,37 +30,36 @@ public ObservableValue<Boolean> apply(Context context, Tag tag) {

Generic scoreUser = quiz.getLink(context.getRootContext().find(ScoreUserQuiz.class), loggedUser.getValue());

return Bindings.createBooleanBinding(() -> scoreUser == null, loggedUser);
return RxJavaHelpers.optionalValuesOf(loggedUser).map(optUser -> scoreUser == null);
}

}

// ************* NAVIGATION ENTRE LES PAGES **********************

public static class HOME_PAGE implements TagSwitcher {

@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
Property<String> pageProperty = tag.getContextProperty(PAGE, context);
return Bindings.createBooleanBinding(() -> HOME_PAGE.equals(pageProperty.getValue()), pageProperty);
return RxJavaHelpers.valuesOf(pageProperty).map(page -> HOME_PAGE.equals(page));
}
}

public static class QUESTION_PAGE implements TagSwitcher {

@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
Property<String> pageProperty = tag.getContextProperty(PAGE, context);
return Bindings.createBooleanBinding(() -> QUESTION_PAGE.equals(pageProperty.getValue()), pageProperty);
return RxJavaHelpers.valuesOf(pageProperty).map(page -> QUESTION_PAGE.equals(page));
}
}

public static class RESULT_PAGE implements TagSwitcher {

@Override
public ObservableValue<Boolean> apply(Context context, Tag tag) {
public Observable<Boolean> apply(Context context, Tag tag) {
Property<String> pageProperty = tag.getContextProperty(PAGE, context);
return Bindings.createBooleanBinding(() -> RESULT_PAGE.equals(pageProperty.getValue()), pageProperty);
return RxJavaHelpers.valuesOf(pageProperty).map(page -> RESULT_PAGE.equals(page));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import com.sun.javafx.collections.ObservableListWrapper;

import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
Expand Down Expand Up @@ -36,7 +38,8 @@ static class FilteredTagChildren extends FilteredChildren<Tag> {
if (child.getMetaBinding() != null)
return new ObservableValue[] {};
ObservableList<TagSwitcher> result = new ObservableListWrapper<>(child.getObservableSwitchers(), s -> {
ObservableValue<Boolean> selector = context.getCache().safeSupply(() -> s.apply(context, child));
Property<Boolean> selector = new SimpleBooleanProperty();
context.getHtmlDomNode(tag).getDisposables().add(context.getCache().safeSupply(() -> s.apply(context, child)).subscribe(bool -> selector.setValue(bool)));
selectorsByChildAndSwitcher.get(child).put(s, selector);
return new ObservableValue[] { selector };
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public Observable<IndexedSubContext> buildFilteredChildren(Context context, Tag
@SuppressWarnings("unchecked")
private Observable<IndexedSubContext> buildObservableBySubContext(Snapshot<Context> snapshot, Context subContext, Tag childTag, int index) {
return RxJavaHelpers.changesOf(childTag.getObservableSwitchers()).switchMap(list -> list.isEmpty() ? Observable.just(new IndexedSubContext(subContext, true, index)) :
Observable.combineLatest(list.stream().map(switcher -> RxJavaHelpers.valuesOf(switcher.apply(subContext, childTag))).toArray(Observable[]::new),
Observable.combineLatest(list.stream().map(switcher -> switcher.apply(subContext, childTag)).toArray(Observable[]::new),
args -> new IndexedSubContext(subContext, Arrays.stream(args).allMatch(v -> Boolean.TRUE.equals(v)), index)).distinctUntilChanged())
.mergeWith(snapshot.getRemovals().filter(context -> context.equals(subContext)).map(context -> new IndexedSubContext(context, false, -1)))
.takeUntil(indexedContext -> ((IndexedSubContext) indexedContext).getIndex() < 0);
Expand Down
Loading

0 comments on commit d534c26

Please sign in to comment.