package org.jboss.windup.config; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import org.apache.commons.lang3.SystemUtils; import org.jboss.windup.config.metadata.RuleMetadataType; import org.jboss.windup.util.exception.WindupException; import org.ocpsoft.rewrite.config.Condition; import org.ocpsoft.rewrite.config.Operation; import org.ocpsoft.rewrite.config.Rule; import org.ocpsoft.rewrite.config.RuleBuilder; import org.ocpsoft.rewrite.context.Context; /** * Utils for the Metadata. Will be likely moved to Windup Utils. * * @author <a href="mailto:ozizka@redhat.com">Ondrej Zizka</a> */ public class RuleUtils { private static final int MAX_WIDTH = 80; /** * Describes given {@link Rule} as: * <p> * <code>ID: Phase - Provider [tags ...]".</code> */ public static String prettyPrintRule(Rule rule) { StringBuilder result = new StringBuilder(); if (rule instanceof Context) { final Context context = (Context) rule; RuleProvider provider = (RuleProvider) context.get(RuleMetadataType.RULE_PROVIDER); if (provider != null && provider.getMetadata() != null) { result.append(provider.getMetadata().getPhase().getSimpleName()).append(" - "); result.append(provider.getMetadata().getID()).append(" - "); } if (rule.getId() != null) result.append(rule.getId()); } return result.toString(); } /** * Attempts to create a human-readable String representation of the provided rule. */ public static String ruleToRuleContentsString(Rule originalRule, int indentLevel) { if (originalRule instanceof Context && ((Context) originalRule).containsKey(RuleMetadataType.RULE_XML)) { return (String) ((Context) originalRule).get(RuleMetadataType.RULE_XML); } if (!(originalRule instanceof RuleBuilder)) { return wrap(originalRule.toString(), MAX_WIDTH, indentLevel); } final RuleBuilder rule = (RuleBuilder) originalRule; StringBuilder result = new StringBuilder(); if (indentLevel == 0) result.append("addRule()"); for (Condition condition : rule.getConditions()) { String conditionToString = conditionToString(condition, indentLevel + 1); if (!conditionToString.isEmpty()) { result.append("\n"); insertPadding(result, indentLevel + 1); result.append(".when(").append(wrap(conditionToString, MAX_WIDTH, indentLevel + 2)).append(")"); } } for (Operation operation : rule.getOperations()) { String operationToString = operationToString(operation, indentLevel + 1); if (!operationToString.isEmpty()) { result.append("\n"); insertPadding(result, indentLevel + 1); result.append(".perform(").append(wrap(operationToString, MAX_WIDTH, indentLevel + 2)).append(")"); } } if (rule.getId() != null && !rule.getId().isEmpty()) { result.append("\n"); insertPadding(result, indentLevel); result.append("withId(\"").append(rule.getId()).append("\")"); } if (rule.priority() != 0) { result.append("\n"); insertPadding(result, indentLevel); result.append(".withPriority(").append(rule.priority()).append(")"); } return result.toString(); } private static String conditionToString(Condition condition, int indentLevel) { if (condition instanceof RuleBuilder) return ruleToRuleContentsString((RuleBuilder) condition, indentLevel + 1); return condition == null ? "" : wrap(condition.toString(), MAX_WIDTH, indentLevel + 1); } private static String operationToString(Operation operation, int indentLevel) { if (operation instanceof RuleBuilder) return ruleToRuleContentsString((RuleBuilder) operation, indentLevel + 1); return operation == null ? "" : wrap(operation.toString(), MAX_WIDTH, indentLevel + 2); } private static String wrap(String str, int wrapLength, int indentLevel) { StringBuilder result = new StringBuilder(); try (StringReader sr = new StringReader(str)) { BufferedReader br = new BufferedReader(sr); String line = null; try { while ((line = br.readLine()) != null) { result.append(wrapLine(line, wrapLength, indentLevel)).append("\n"); } } catch (IOException e) { throw new WindupException("Error... while reading a StringReader", e); } } return result.toString(); } private static String wrapLine(String str, int wrapLength, int indentLevel) { if (str == null) { return null; } if (wrapLength < 1) { wrapLength = 1; } int inputLineLength = str.length(); int offset = 0; StringBuilder wrappedLine = new StringBuilder(inputLineLength + 32); StringBuilder filler = new StringBuilder(); while ((inputLineLength - offset) > wrapLength) { if (str.charAt(offset) == '.') { offset++; filler.append('.'); continue; } int spaceToWrapAt = str.lastIndexOf('.', wrapLength + offset); if (spaceToWrapAt >= offset) { // normal case if (wrappedLine.length() > 0) { insertPadding(wrappedLine, indentLevel); } wrappedLine.append(filler); wrappedLine.append(str.substring(offset, spaceToWrapAt)); wrappedLine.append(SystemUtils.LINE_SEPARATOR); offset = spaceToWrapAt; } else { // really long word or URL // wrap really long word one line at a time if (wrappedLine.length() > 0) { insertPadding(wrappedLine, indentLevel); } wrappedLine.append(filler); wrappedLine.append(str.substring(offset, wrapLength + offset)); wrappedLine.append(SystemUtils.LINE_SEPARATOR); offset += wrapLength; } filler.setLength(0); } // Whatever is left in line is short enough to just pass through if (wrappedLine.length() > 0) { insertPadding(wrappedLine, indentLevel); } wrappedLine.append(filler); wrappedLine.append(str.substring(offset)); return wrappedLine.toString(); } private static void insertPadding(StringBuilder sb, int indentLevel) { for (int i = 0; i < indentLevel; i++) { sb.append("\t"); } } }