
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