All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.atlassian.bamboo.specs.codegen.BambooSpecsGenerator Maven / Gradle / Ivy
package com.atlassian.bamboo.specs.codegen;
import com.atlassian.bamboo.specs.api.BambooSpec;
import com.atlassian.bamboo.specs.api.codegen.CodeEmitter;
import com.atlassian.bamboo.specs.api.codegen.CodeGenerationContext;
import com.atlassian.bamboo.specs.api.codegen.CodeGenerationException;
import com.atlassian.bamboo.specs.api.exceptions.PropertiesValidationException;
import com.atlassian.bamboo.specs.api.model.EntityProperties;
import com.atlassian.bamboo.specs.api.validators.common.ImporterUtils;
import com.atlassian.bamboo.specs.codegen.emitters.value.ValueEmitterFactory;
import com.atlassian.bamboo.specs.util.BambooServer;
import com.atlassian.bamboo.specs.util.BambooSpecProperties;
import com.atlassian.bamboo.specs.util.Yamlizator;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import javax.annotation.concurrent.Immutable;
import java.io.File;
import java.io.FileInputStream;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* Code generator for any Bamboo Spec entities, such us plan or deployment project.
*/
public class BambooSpecsGenerator {
private final Map entityByName = new LinkedHashMap<>();
private final CodeGenerationContext context = new CodeGenerationContext();
public interface CodeSupplier {
String generateCode() throws CodeGenerationException;
}
public BambooSpecsGenerator() {
}
public BambooSpecsGenerator(final EntityProperties entityProperties) throws PropertiesValidationException {
this();
addEntity("rootObject", entityProperties);
}
public BambooSpecsGenerator addEntity(final String entityName, final EntityProperties entityProperties) throws PropertiesValidationException {
ImporterUtils.checkNotNull("entity name", entityName);
ImporterUtils.checkNotNull("entity", entityProperties);
if (entityByName.putIfAbsent(entityName, entityProperties) != null) {
throw new PropertiesValidationException(String.format("Entity with name %s already defined.", entityName));
}
return this;
}
private StringBuilder classDeclaration(@NotNull Set annotations, @NotNull String className, @NotNull CodeSupplier body) throws CodeGenerationException {
final StringBuilder builder = new StringBuilder();
//open class
for (final Class annotation : annotations) {
String annotationName = context.importClassName(annotation);
builder.append("@").append(annotationName).append(context.newLine());
}
builder.append("public class ")
.append(className)
.append(" {");
context.incIndentation();
builder.append(body.generateCode());
//close class
context.decIndentation();
builder.append(context.newLine());
builder.append("}");
context.decIndentation();
builder.append(context.newLine());
builder.append("}");
return builder;
}
private String buildCode(String url, String className) throws CodeGenerationException {
final String mainObjectName = getMainObjectName(className);
final StringBuilder builder = classDeclaration(Collections.singleton(BambooSpec.class), className, () -> {
final StringBuilder bodyBuilder = new StringBuilder();
for (final String entityName : entityByName.keySet()) {
insertCreationMethod(bodyBuilder, entityName, entityByName.get(entityName));
}
bodyBuilder.append(context.newLine());
bodyBuilder.append(context.newLine());
bodyBuilder.append("public static void main(String... argv) {");
context.incIndentation();
bodyBuilder.append(context.newLine());
bodyBuilder.append("//By default credentials are read from the '.credentials' file.").append(context.newLine());
bodyBuilder.append(context.importClassName(BambooServer.class))
.append(" bambooServer = new BambooServer(\"")
.append(url)
.append("\");");
bodyBuilder.append(context.newLine());
bodyBuilder.append("final ").append(className).append(" " + mainObjectName + " = new ").append(className).append("();");
for (final String entityName : entityByName.keySet()) {
bodyBuilder.append(context.newLine()).append(context.newLine());
insertPublishingCode(bodyBuilder, mainObjectName, entityName, entityByName.get(entityName));
}
return bodyBuilder.toString();
});
return builder.toString();
}
private String getMainObjectName(String className) {
String candidate = StringUtils.uncapitalize(className);
if (!className.equals(candidate)) {
return candidate;
}
return "mainObj";
}
private void insertCreationMethod(final StringBuilder builder,
final String entityName,
final EntityProperties entity) throws CodeGenerationException {
if (!(entity instanceof Comment)) {
builder.append(context.newLine()).append(context.newLine());
final String builderClassName = context.importClassName(BuilderClassProvider.findBuilderClass(entity.getClass()));
builder.append("public ")
.append(builderClassName)
.append(" ")
.append(entityName)
.append("() {");
context.incIndentation();
builder.append(context.newLine());
final CodeEmitter codeEmitter = ValueEmitterFactory.emitterFor(entity);
final String entityCodeRightSide = codeEmitter.emitCode(context, entity);
builder.append("final ").append(builderClassName);
builder.append(String.format(" %s = %s;", entityName, entityCodeRightSide));
builder.append(context.newLine());
builder.append("return ").append(entityName).append(";");
context.decIndentation();
builder.append(context.newLine());
builder.append("}");
}
}
private void insertPublishingCode(final StringBuilder builder,
final String classVariable,
final String entityName,
final EntityProperties entity) throws CodeGenerationException {
if (entity instanceof Comment) {
final Comment comment = (Comment) entity;
if (comment.newLineBefore) {
builder.append(context.newLine());
}
builder.append("// ").append(comment.comment);
if (comment.newLineAfter) {
builder.append(context.newLine());
}
} else {
final CodeEmitter codeEmitter = ValueEmitterFactory.emitterFor(entity);
final String entityCodeRightSide = classVariable + "." + entityName + "()";
builder.append("final ").append(context.importClassName(BuilderClassProvider.findBuilderClass(entity.getClass())));
builder.append(String.format(" %s = %s;", entityName, entityCodeRightSide));
builder.append(context.newLine());
builder.append(String.format("bambooServer.publish(%s);", entityName));
}
}
public String emitCode() throws CodeGenerationException {
return emitCode("http://localhost:8085");
}
public String emitCode(@NotNull String bambooServerUrl) throws CodeGenerationException {
return emitCode(bambooServerUrl, "", "PlanSpec");
}
public String emitCode(@NotNull String bambooServerUrl, @NotNull String packageName, @NotNull String className) throws CodeGenerationException {
final String main = buildCode(bambooServerUrl, className);
final StringBuilder codeBuilder = new StringBuilder();
//imports
if (StringUtils.isNotBlank(packageName)) {
codeBuilder.append("package ").append(packageName).append(";\n\n");
}
for (String anImport : context.getImports()) {
codeBuilder.append("import ").append(anImport).append(";\n");
}
codeBuilder.append("\n");
codeBuilder.append(main);
return codeBuilder.toString();
}
/**
* Represents a comment in Bamboo Specs.
* Note: Only to be used with {@link BambooSpecsGenerator#addEntity(String, EntityProperties)}
*/
@Immutable
public static class Comment implements EntityProperties {
private String comment;
private boolean newLineBefore;
private boolean newLineAfter;
private Comment() {
}
public Comment(final String comment) {
this(comment, true, true);
}
public Comment(final String comment, final boolean newLineBefore, final boolean newLineAfter) {
this.comment = comment;
this.newLineBefore = newLineBefore;
this.newLineAfter = newLineAfter;
}
@Override
public String toString() {
return comment;
}
@Override
public void validate() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Comment comment1 = (Comment) o;
return newLineBefore == comment1.newLineBefore &&
newLineAfter == comment1.newLineAfter &&
Objects.equals(comment, comment1.comment);
}
@Override
public int hashCode() {
return Objects.hash(comment, newLineBefore, newLineAfter);
}
}
public static void main(String... argv) {
if (argv.length < 1) {
System.out.println("File argument missing");
return;
}
String filePath = argv[0];
try {
BambooSpecProperties o = (BambooSpecProperties) Yamlizator.getYaml().load(new FileInputStream(new File(filePath)));
String javaCode = new BambooSpecsGenerator(o.getRootEntity()).emitCode();
System.out.print(javaCode);
} catch (Exception e) {
e.printStackTrace();
}
}
}