/** * * Copyright (c) 2006-2017, Speedment, Inc. All Rights Reserved. * * 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.speedment.runtime.core.stream.action; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.BaseStream; import java.util.stream.Stream; import static com.speedment.common.invariant.NullUtil.requireNonNullElements; import static java.util.Objects.requireNonNull; /** * * @param <T> input {@code BaseStream} type * @param <R> output (return) {@code BaseStream} type * * @author Per Minborg * @since 2.1.0 */ public abstract class Action<T extends BaseStream<?, T>, R extends BaseStream<?, R>> implements Supplier<Function<T, R>> { private final Function<T, R> mapper; @SuppressWarnings("rawtypes") private final Class<? extends BaseStream> resultStreamClass; private final Map<Verb, Set<Property>> streamImpacts; protected Action(Function<T, R> mapper, @SuppressWarnings("rawtypes") Class<? extends BaseStream> resultStreamClass, BasicAction basicAction) { this.mapper = requireNonNull(mapper); this.resultStreamClass = requireNonNull(resultStreamClass); this.streamImpacts = new HashMap<>(); set(basicAction); } @Override public Function<T, R> get() { return mapper; } @SuppressWarnings("rawtypes") public Class<? extends BaseStream> resultStreamClass() { return resultStreamClass; } protected final void set(BasicAction basicAction) { requireNonNull(basicAction); basicAction.statements().forEach(this::set); } protected final void set(Verb verb, Property property) { requireNonNull(verb); requireNonNull(property); aquireSet(verb).add(property); } protected final void set(Statement statement) { requireNonNull(statement); set(statement.getVerb(), statement.getProperty()); } protected final void set(Statement firstStatement, Statement... otherStatements) { requireNonNull(firstStatement); requireNonNullElements(otherStatements); set(firstStatement); Stream.of(otherStatements).forEach(this::set); } public boolean is(Verb verb, Property property) { requireNonNull(verb); requireNonNull(property); return aquireSet(verb).contains(property); } public boolean is(Statement statement) { requireNonNull(statement); return aquireSet(statement.getVerb()).contains(statement.getProperty()); } public boolean is(Statement firstStatement, Statement... otherStatements) { requireNonNull(firstStatement); requireNonNullElements(otherStatements); if (!is(firstStatement)) { return false; } return Stream.of(otherStatements).allMatch(this::is); } protected final Set<Property> aquireSet(Verb verb) { requireNonNull(verb); return streamImpacts.computeIfAbsent(verb, v -> EnumSet.noneOf(Property.class)); } @Override public String toString() { final String className = getClass().getSimpleName(); final int index = className.lastIndexOf(Action.class.getSimpleName()); if (index > 0) { return className.substring(0, index); } return className; } }