package liquibase.serializer.core.string; import liquibase.changelog.ChangeLogChild; import liquibase.changelog.ChangeSet; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.serializer.ChangeLogSerializer; import liquibase.serializer.LiquibaseSerializable; import liquibase.util.StringUtils; import java.io.*; import java.util.*; public class StringChangeLogSerializer implements ChangeLogSerializer { private static final int INDENT_LENGTH = 4; private FieldFilter fieldFilter; public StringChangeLogSerializer() { this(new FieldFilter()); } public StringChangeLogSerializer(FieldFilter fieldFilter) { this.fieldFilter = fieldFilter; } @Override public String[] getValidFileExtensions() { return new String[]{"txt"}; } @Override public String serialize(LiquibaseSerializable object, boolean pretty) { return object.getSerializedObjectName() + ":" + serializeObject(object, 1); } private String serializeObject(LiquibaseSerializable objectToSerialize, int indent) { try { StringBuffer buffer = new StringBuffer(); buffer.append("["); SortedSet<String> values = new TreeSet<String>(); for (String field : objectToSerialize.getSerializableFields()) { Object value = objectToSerialize.getSerializableFieldValue(field); if (value == null) { continue; } if (!fieldFilter.include(objectToSerialize, field, value)) { continue; } if (value instanceof LiquibaseSerializable) { values.add(indent(indent) + serializeObject((LiquibaseSerializable) value, indent + 1)); } else { if (value != null) { if (value instanceof Map) { values.add(indent(indent) + field + "=" + serializeObject((Map) value, indent + 1)); } else if (value instanceof Collection) { values.add(indent(indent) + field + "=" + serializeObject((Collection) value, indent + 1)); } else if (value instanceof Object[]) { values.add(indent(indent) + field + "=" + serializeObject((Object[]) value, indent + 1)); } else { String valueString = value.toString(); if (value instanceof Double || value instanceof Float) { //java 6 adds additional zeros to the end of doubles and floats if (valueString.contains(".")) { valueString = valueString.replaceFirst("(\\.[0-9]+)0+$","$1"); valueString = valueString.replaceFirst("\\.0+$", ""); } } values.add(indent(indent) + field + "=\"" + valueString + "\""); } } } } if (values.size() > 0) { buffer.append("\n"); buffer.append(StringUtils.join(values, "\n")); buffer.append("\n"); } buffer.append(indent(indent - 1)).append("]"); return buffer.toString().replace("\r\n", "\n").replace("\r", "\n"); //standardize all newline chars } catch (Exception e) { throw new UnexpectedLiquibaseException(e); } } private String indent(int indent) { return StringUtils.repeat(" ", INDENT_LENGTH * indent); } private String serializeObject(Object[] collection, int indent) { if (collection.length == 0) { return "[]"; } String returnString = "[\n"; for (Object object : collection) { if (object instanceof LiquibaseSerializable) { returnString += indent(indent) + serializeObject((LiquibaseSerializable) object, indent + 1) + ",\n"; } else { returnString += indent(indent) + object.toString() + ",\n"; } } returnString = returnString.replaceFirst(",$", ""); returnString += indent(indent - 1) + "]"; return returnString; } private String serializeObject(Collection collection, int indent) { if (collection.size() == 0) { return "[]"; } String returnString = "[\n"; for (Object object : collection) { if (object instanceof LiquibaseSerializable) { returnString += indent(indent) + serializeObject((LiquibaseSerializable) object, indent + 1) + ",\n"; } else { returnString += indent(indent) + object.toString() + ",\n"; } } returnString = returnString.replaceFirst(",$", ""); returnString += indent(indent - 1) + "]"; return returnString; } private String serializeObject(Map collection, int indent) { if (collection.size() == 0) { return "[]"; } String returnString = "{\n"; for (Object key : new TreeSet(collection.keySet())) { returnString += indent(indent) + key.toString() + "=\"" + collection.get(key) + "\",\n"; } returnString = returnString.replaceFirst(",$", ""); returnString += indent(indent - 1) + "}"; return returnString; } @Override public <T extends ChangeLogChild> void write(List<T> children, OutputStream out) throws IOException { } @Override public void append(ChangeSet changeSet, File changeLogFile) throws IOException { } @Override public int getPriority() { return PRIORITY_DEFAULT; } public static class FieldFilter { public boolean include(Object obj, String field, Object value) { return true; } } }