Skip to content

Commit

Permalink
Selector: multiselect support added
Browse files Browse the repository at this point in the history
  • Loading branch information
xdcrafts committed Jan 18, 2017
1 parent eee5522 commit a7f7474
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.github.xdcrafts.flower.core;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
Expand All @@ -30,9 +31,9 @@ public interface Selector extends Action {
Collection<Extension> extensions();

/**
* Makes decision about which action should proceed with processing of proposed context.
* Makes decision about which actions should proceed with processing of proposed context.
*/
Action selectAction(Map context);
List<Action> selectAction(Map context);

/**
* Register new extension.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.github.xdcrafts.flower.tools.map.MapDotApi.dotGet;
import static com.github.xdcrafts.flower.tools.map.MapDotApi.dotGetString;

/**
* Implementation of Selector that selects Action based on value of keyword in context.
*/
@SuppressWarnings("unchecked")
public class KeywordSelector extends WithMiddlewareSelectorBase {

/**
Expand Down Expand Up @@ -70,18 +74,31 @@ public Collection<Extension> extensions() {
}

@Override
public Action selectAction(Map context) {
final String keywordValue = dotGetString(context, this.keyword).orElseThrow(
public List<Action> selectAction(Map context) {
final Object keywordValue = dotGet(context, this.keyword).orElseThrow(
() -> new IllegalArgumentException(
"Unable to selectAction request, '" + this.keyword + "' key required"
));
final Action action = this.extensions.get(keywordValue);
if (action == null) {
final Collection<String> keywordValues;
if (keywordValue instanceof String) {
keywordValues = Collections.singletonList((String) keywordValue);
} else if (keywordValue instanceof Collection) {
keywordValues = (Collection<String>) keywordValue;
} else {
throw new IllegalArgumentException("'" + this.keyword + "' should be a String or Collection<String>.");
}
final List<Action> actions = keywordValues
.stream()
.map(value -> Optional.ofNullable(this.extensions.get(value)))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
if (actions.isEmpty()) {
throw new IllegalArgumentException(
"Unable to selectAction request, '" + keywordValue + "' is unknown keyword value."
);
}
return action;
return actions;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.github.xdcrafts.flower.tools.map.MapApi.get;

Expand Down Expand Up @@ -70,13 +71,17 @@ public Collection<Extension> extensions() {
}

@Override
public Action selectAction(Map context) {
for (Predicate<Map> predicate: this.extensions.keySet()) {
if (predicate.test(context)) {
return this.extensions.get(predicate);
}
public List<Action> selectAction(Map context) {
final List<Action> actions = this.extensions
.entrySet()
.stream()
.filter(e -> e.getKey().test(context))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
if (actions.isEmpty()) {
throw new IllegalArgumentException("Unable to selectAction request, no suitable action found.");
}
throw new IllegalArgumentException("Unable to selectAction request, no suitable action found.");
return actions;
}

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

import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
* Abstract class as a base for any Selector implementation.
Expand All @@ -34,6 +35,10 @@ public WithMiddlewareSelectorBase(List<Middleware> middleware) {

@Override
public Map act(Map ctx) {
return selectAction(ctx).apply(ctx);
return selectAction(ctx)
.stream()
.map(a -> (Function<Map, Map>) a)
.reduce(Function.identity(), Function::andThen)
.apply(ctx);
}
}

0 comments on commit a7f7474

Please sign in to comment.