Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class ChangelogBuilder {
private String preferredSQLDialect = "ORACLE";

private PrintWriter outputStream = new PrintWriter(new OutputStreamWriter(System.out, Charset.forName("UTF-8")));
private PrintWriter entityOutputStream = new PrintWriter(new OutputStreamWriter(System.out, Charset.forName("UTF-8")));
private String versionStart = "v0.0.0";
private boolean includeEntityBasedChangelogs;
private final Set<Class<? extends UpgradeStep>> upgradeSteps = new HashSet<>();

public static ChangelogBuilder changelogBuilder(){
Expand Down Expand Up @@ -89,22 +92,54 @@ public ChangelogBuilder withUpgradeSteps(Collection<Class<? extends UpgradeStep>
/**
* Set the {@link PrintWriter} target for this changelog. Default is the
* console.
*
* @deprecated
* @param outputStream The {@link PrintWriter} to output to.
* @return This builder for chaining
*/
@Deprecated
public ChangelogBuilder withOutputTo(PrintWriter outputStream) {
this.outputStream = outputStream;
return this;
}

/**
* Set the {@link PrintWriter} targets for this changelog. Default is the
* console.
*
* @param outputStream The {@link PrintWriter} to output to.
* @param entityOutputStream The {@link PrintWriter} to output entity based changelog to.
* @return This builder for chaining
*/
public ChangelogBuilder withOutputTo(PrintWriter outputStream, PrintWriter entityOutputStream) {
this.entityOutputStream = entityOutputStream;
this.outputStream = outputStream;
return this;
}

/**
* Set the version from which the entity based logs start from
* and sets flag to include entity based changelogs
* depending on versionStart empty or not.
*
* @param versionStart of the entity based logs
* @return This builder for chaining
*/
public ChangelogBuilder withVersionStart(String versionStart) {
this.versionStart = versionStart;
includeEntityBasedChangelogs = versionStart != null && !versionStart.isBlank();
return this;
}

/**
* Produces the Changelog based on the given input settings.
*/
public void produceChangelog() {
HumanReadableStatementProducer producer = new HumanReadableStatementProducer(upgradeSteps, includeDataChanges, preferredSQLDialect);
producer.produceFor(new ChangelogStatementConsumer(outputStream));
if(includeEntityBasedChangelogs) {
producer.produceFor(new ChangelogStatementConsumer(outputStream), new EntityHumanReadableStatementConsumer(versionStart, entityOutputStream));
} else {
producer.produceFor(new ChangelogStatementConsumer(outputStream));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import org.alfasoftware.morf.upgrade.HumanReadableStatementConsumer;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;

/**
* Class to consume strings produced by the human readable statement generator and
Expand All @@ -29,48 +28,14 @@
*/
class ChangelogStatementConsumer implements HumanReadableStatementConsumer {

/**
* Line width to apply wrapping at.
*/
private static final int LINE_LENGTH = 132;

private final PrintWriter outputStream;
private final ConsumerUtils utils;


ChangelogStatementConsumer(PrintWriter outputStream) {
this.outputStream = outputStream;
}


/**
* Writes one or more lines of text, applying line wrapping.
*/
private void writeWrapped(final String text) {

// Handle the case of multiple lines
if (text.contains(System.lineSeparator())) {
for (String line : text.split(System.lineSeparator())) {
writeWrapped(line);
}
return;
}

// Write anything below the wrapping limit
if (text.length() < LINE_LENGTH) {
outputStream.println(text);
return;
}

// Measure the indent to use on the split lines
int indent = 0;
while (indent < text.length() && text.charAt(indent) == ' ') {
indent++;
}
indent += 2;

// Split the line, preserving the indent on new lines
final String firstLineIndent = text.substring(0, indent);
final String lineSeparator = System.lineSeparator() + StringUtils.repeat(" ", indent);
outputStream.println(firstLineIndent + WordUtils.wrap(text.substring(indent), LINE_LENGTH - indent, lineSeparator, false));
utils = new ConsumerUtils(outputStream);
}


Expand All @@ -83,13 +48,13 @@ public void versionStart(String versionNumber) {

@Override
public void upgradeStepStart(String name, String description, String jiraId) {
writeWrapped("* " + jiraId + ": " + description);
utils.writeWrapped("* " + jiraId + ": " + description);
}


@Override
public void schemaChange(String description) {
writeWrapped(" o " + description);
utils.writeWrapped(" o " + description);
}


Expand All @@ -107,7 +72,7 @@ public void versionEnd(String versionNumber) {

@Override
public void dataChange(final String description) {
writeWrapped(" o " + description);
utils.writeWrapped(" o " + description);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.alfasoftware.morf.changelog;

import java.io.PrintWriter;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;

public class ConsumerUtils {

/**
* Line width to apply wrapping at.
*/
private static final int LINE_LENGTH = 132;;
private final PrintWriter outputStream;

public ConsumerUtils(PrintWriter outputStream) {
this.outputStream = outputStream;
}

public void writeWrapped(String text) {
String output = "";
// Handle the case of multiple lines
if (text.contains(System.lineSeparator())) {
for (String line : text.split(System.lineSeparator())) {
writeWrapped(line);
}
return;
}

// Write anything below the wrapping limit
if (text.length() < LINE_LENGTH) {
output = text;
outputStream.println(output);
return;
}

// Measure the indent to use on the split lines
int indent = 0;
while (indent < text.length() && text.charAt(indent) == ' ') {
indent++;
}
indent += 2;

// Split the line, preserving the indent on new lines
final String firstLineIndent = text.substring(0, indent);
final String lineSeparator = System.lineSeparator() + StringUtils.repeat(" ", indent);
output = firstLineIndent + WordUtils.wrap(text.substring(indent), LINE_LENGTH - indent, lineSeparator, false);
outputStream.println(output);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.alfasoftware.morf.changelog;

import java.io.PrintWriter;

import org.alfasoftware.morf.upgrade.HumanReadableStatementConsumer;
import org.apache.commons.lang3.StringUtils;

/**
* Class to consume strings produced by the entity human readable statement generator and
* passes them to the target output stream after applying word-wrapping logic.
*
* @author Copyright (c) Alfa Financial Software 2026
*/
public class EntityHumanReadableStatementConsumer implements HumanReadableStatementConsumer {
private final ConsumerUtils utils;
private final PrintWriter outputStream;
private final String versionStart;


public EntityHumanReadableStatementConsumer(String versionStart, PrintWriter outputStream) {
utils = new ConsumerUtils(outputStream);
this.versionStart = versionStart;
this.outputStream = outputStream;
}

public String getVersionStart() {
return versionStart;
}

public void entityStart(String entityStart) {
outputStream.println(entityStart);
outputStream.println(StringUtils.repeat("=", entityStart.length()));
}

public void entityEnd(String entityEnd) {
// nothing to write
}

/**
* @see HumanReadableStatementConsumer#upgradeStepStart(String, String, String)
*/
@Override
public void upgradeStepStart(String name, String description, String jiraId) {
utils.writeWrapped("* " + jiraId + ": " + description);
}

/**
* @see HumanReadableStatementConsumer#upgradeStepEnd(String)
*/
@Override
public void upgradeStepEnd(String name) {
outputStream.println();
}

/**
* @see HumanReadableStatementConsumer#schemaChange(String)
*/
@Override
public void schemaChange(String description) {
utils.writeWrapped(" o " + description);
}

/**
* @see HumanReadableStatementConsumer#dataChange(String)
*/
@Override
public void dataChange(String description) {
utils.writeWrapped(" o " + description);
}

/**
* @see HumanReadableStatementConsumer#versionStart(String)
*/
@Override
public void versionStart(String versionNumber) {
outputStream.println(versionNumber);
outputStream.println(StringUtils.repeat("=", versionNumber.length()));
}

/**
* @see HumanReadableStatementConsumer#versionEnd(String)
*/
@Override
public void versionEnd(String versionNumber) {
//nothing to write
}
}
Loading