Skip to content

Commit

Permalink
Actor entity introduced (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
xdcrafts committed Jan 16, 2017
1 parent e59fd2d commit cab0fc1
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2017 Vadim Dubs https://github.com/xdcrafts
*
* 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.
*/

package com.github.xdcrafts.flower.core;

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

/**
* Actor is a function that takes function, initializing action context, and provides result of type T.
* @param <T> return type
*/
public interface Actor<T> extends Function<Consumer<Map>, T> {

/**
* Apply actor's action to map context initialized by supported closure.
* @param contextInitializer closure that fills context with data to process
* @return value of type T produced from map context
*/
@Override
T apply(Consumer<Map> contextInitializer);

/**
* Call apply without any initializer function provided.
*/
default T apply() {
return apply(ctx -> {
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2017 Vadim Dubs https://github.com/xdcrafts
*
* 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.
*/

package com.github.xdcrafts.flower.core.impl;

import com.github.xdcrafts.flower.core.Action;
import com.github.xdcrafts.flower.core.Actor;

import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* Default implementation of Actor.
* @param <T> return type;
*/
public class DefaultActor<T> implements Actor<T> {

private final Supplier<Map> contextFactory;
private final Action action;
private final Function<Map, T> conclusion;
private final Function<Map, T> body;

public DefaultActor(
Supplier<Map> contextFactory,
Action action,
Function<Map, T> conclusion
) {
if (contextFactory == null) {
throw new IllegalArgumentException("ContextFactory can not be null.");
}
if (action == null) {
throw new IllegalArgumentException("Action can not be null.");
}
if (conclusion == null) {
throw new IllegalArgumentException("Conclusion can not be null.");
}
this.contextFactory = contextFactory;
this.action = action;
this.conclusion = conclusion;
this.body = this.action.andThen(this.conclusion);
}

@Override
public T apply(Consumer<Map> contextInitializer) {
final Map ctx = this.contextFactory.get();
if (contextInitializer != null) {
contextInitializer.accept(ctx);
}
return this.body.apply(ctx);
}

@Override
public String toString() {
return "DefaultActor{"
+ "contextFactory=" + this.contextFactory
+ ", action=" + this.action
+ ", conclusion=" + this.conclusion
+ '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.github.xdcrafts.flower.core;

import com.github.xdcrafts.flower.core.impl.DefaultActor;
import com.github.xdcrafts.flower.core.impl.actions.AwaitAction;
import com.github.xdcrafts.flower.core.impl.actions.DefaultAction;
import com.github.xdcrafts.flower.core.impl.flows.AsyncFlow;
Expand Down Expand Up @@ -49,6 +50,21 @@ public class FlowerTest {

private static final Logger LOGGER = LoggerFactory.getLogger(FlowerTest.class);

private static final class ConclusionValue {
private final boolean success;
private final int steps;
ConclusionValue(boolean success, int steps) {
this.success = success;
this.steps = steps;
}
boolean isSuccess() {
return success;
}
int getSteps() {
return steps;
}
}

@Test
public void test() {
final Middleware counterMiddleware = Middleware.middleware("counterMiddleware", (map, function) -> ctx -> {
Expand Down Expand Up @@ -90,11 +106,19 @@ public void test() {
"complexFlow",
Arrays.asList(simpleAsyncFlow, awaitAction, thirdAction)
);
final Map result = complexFlow.apply(new ConcurrentHashMap());
assertTrue(getUnsafe(result, Boolean.class, "data", "first"));
assertTrue(getUnsafe(result, Boolean.class, "data", "second"));
assertTrue(getUnsafe(result, Boolean.class, "data", "third"));
assertEquals(3, getUnsafe(result, AtomicInteger.class, "meta", "dummy").longValue());
final Actor<ConclusionValue> actor = new DefaultActor<>(
ConcurrentHashMap::new,
complexFlow,
ctx -> new ConclusionValue(
getUnsafe(ctx, Boolean.class, "data", "first")
&& getUnsafe(ctx, Boolean.class, "data", "second")
&& getUnsafe(ctx, Boolean.class, "data", "third"),
getUnsafe(ctx, AtomicInteger.class, "meta", "dummy").intValue()
)
);
final ConclusionValue result = actor.apply();
assertTrue(result.isSuccess());
assertEquals(3, result.getSteps());
}

@Test
Expand Down

0 comments on commit cab0fc1

Please sign in to comment.