/** * * 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.common.codegen.internal; import com.speedment.common.codegen.*; import java.util.LinkedList; import java.util.Optional; import java.util.stream.Stream; import static com.speedment.common.codegen.internal.util.NullUtil.requireNonNulls; import static java.util.Objects.requireNonNull; /** * The default implementation of the {@link Generator} interface. * * @author Emil Forslund */ public class DefaultGenerator implements Generator { private final DependencyManager mgr; private final TransformFactory factory; private final DefaultRenderStack renderStack; private final LinkedList<RenderTree.Builder> renderTreeBuilder; /** * Creates a new generator. This constructor will use a * {@link DefaultDependencyManager} with no parameters to handle any * dependencies. * * @param factory the factory to use */ public DefaultGenerator(TransformFactory factory) { this(new DefaultDependencyManager(), factory); } /** * Creates a new generator. * * @param mgr the dependency manager to use * @param factory the factory to use */ public DefaultGenerator(DependencyManager mgr, TransformFactory factory) { this.factory = requireNonNull(factory); this.mgr = requireNonNull(mgr); this.renderStack = new DefaultRenderStack(); this.renderTreeBuilder = new LinkedList<>(); // Add initial builder. this.renderTreeBuilder.add(RenderTree.builder()); } @Override public DependencyManager getDependencyMgr() { return mgr; } @Override public RenderStack getRenderStack() { return renderStack; } @Override @SuppressWarnings("unchecked") public <A, B> Stream<Meta<A, B>> metaOn(A from, Class<B> to) { requireNonNulls(from, to); if (from instanceof Optional) { throw new UnsupportedOperationException( "Model must not be an Optional!" ); } return BridgeTransform.create(factory, from.getClass(), to) .map(t -> (Transform<A, B>) t) .map(t -> transform(t, from, factory)) .filter(Optional::isPresent) .map(Optional::get) ; } @Override public <A, B> Optional<Meta<A, B>> transform(Transform<A, B> transform, A model, TransformFactory factory) { requireNonNulls(transform, model, factory); final RenderTree.Builder parent = renderTreeBuilder.peek(); final RenderTree.Builder branch = RenderTree.builder(); renderTreeBuilder.push(branch); renderStack.push(model); final Optional<Meta<A, B>> meta = transform .transform(this, model) .map(s -> Meta.builder(model, s) .withTransform(transform) .withFactory(factory) .withRenderTree(branch.build()) .withRenderStack(new DefaultRenderStack(renderStack)) .build() ); meta.ifPresent(parent::withBranch); renderStack.pop(); renderTreeBuilder.pop(); return meta; } }