All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.sundr.codegen.api.CodeGenerator Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2015 The original authors.
 *
 * 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 io.sundr.codegen.api;

import java.io.IOException;
import java.io.Writer;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import io.sundr.utils.Predicates;

public class CodeGenerator {

  private final Class type;
  private final Function output;
  private final Function identifier;
  private final Function renderer;
  private final Predicate skip;
  private final Consumer onSkip;

  private final Consumer ignore = t -> {
  };
  private final Set generated = new HashSet<>();

  public static class Builder {

    private final Class type;
    private final Function output;
    private final Function identifier;
    private final Function renderer;
    private final Predicate skip;
    private final Consumer onSkip;

    private Builder(Class type) {
      this(type, null, null, null, null, null);
    }

    private Builder(Class type, Function output, Function identifier, Function renderer,
        Predicate skip,
        Consumer onSkip) {
      this.type = type;
      this.output = output;
      this.identifier = identifier;
      this.renderer = renderer;
      this.skip = skip;
      this.onSkip = onSkip;
    }

    public Builder withOutput(Output output) {
      return withOutput(output.getFunction());
    }

    public Builder withOutput(Function output) {
      return new Builder<>(type, output, identifier, renderer, skip, onSkip);
    }

    public Builder withIdentifier(Identifier identifier) {
      return withIdentifier(identifier.getFunction());
    }

    public Builder withIdentifier(Function identifier) {
      return new Builder<>(type, output, identifier, renderer, skip, onSkip);
    }

    public Builder withRenderer(Renderer renderer) {
      return withRenderer(renderer.getFunction());
    }

    public Builder withRenderer(Function renderer) {
      return new Builder<>(type, output, identifier, renderer, skip, onSkip);
    }

    public Builder skipping(Predicate skip) {
      return new Builder<>(type, output, identifier, renderer, skip, onSkip);
    }

    public CodeGenerator build() {
      return new CodeGenerator<>(type, output, identifier, renderer, skip, onSkip);
    }

    public boolean generate(T... items) {
      return build().generate(items);
    }
  }

  private CodeGenerator(Class type, Function output, Function identifier, Function renderer,
      Predicate skip, Consumer onSkip) {
    this.type = type;
    this.output = output != null ? output : new SystemOutput().getFunction();
    this.identifier = identifier != null ? identifier
        : Identifiers.findIdentifier(type).map(Identifier::getFunction).orElse(o -> String.valueOf(o.hashCode()));
    this.renderer = renderer != null ? renderer
        : Renderers.findRenderer(type).map(Renderer::getFunction)
            .orElseThrow(() -> new IllegalStateException("Renderer should not be null."));
    this.skip = skip != null ? skip : Predicates.distinct(t -> this.identifier.apply(t));
    this.onSkip = onSkip != null ? onSkip : ignore;
  }

  public static  Builder newGenerator(Class type) {
    return new Builder(type);
  }

  /**
   * Generate one or more items
   *
   * @param items the items to generate
   * @return true if generation was succesful, false otherwise
   */
  public boolean generate(T... items) {
    //Function like skip, onSkip, writer etc may need to access the specified Identifier.
    //So, let's wrap all code that may need the identifier into a lambda and ensure that the Identifiers is accessible to the lambda
    //using Indentifiers.getIdentifier().
    return Identifiers.withIdentifier(identifier).call(() -> {
      for (T item : items) {
        String id = identifier.apply(item);
        if (skip.test(item)) {
          onSkip.accept(item);
          continue;
        }
        //Only generate each file once ...
        if (generated.contains(id)) {
          continue;
        }
        try (Writer writer = output.apply(item)) {
          writer.write(renderer.apply(item));
          generated.add(id);
        } catch (IOException e) {
          return false;
        }
      }
      return true;
    });

  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy