/* * Lilith - a log event viewer. * Copyright (C) 2007-2013 Joern Huxhorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.huxhorn.lilith.swing; import de.huxhorn.sulky.conditions.And; import de.huxhorn.sulky.conditions.Condition; import de.huxhorn.sulky.conditions.ConditionGroup; import de.huxhorn.sulky.conditions.ConditionWrapper; import de.huxhorn.sulky.conditions.Not; import de.huxhorn.sulky.conditions.Or; import de.huxhorn.sulky.formatting.SimpleXml; import java.util.List; public class TextPreprocessor { private static final int MAX_LINE_LENGTH = 100; private static final int MAX_LINES = 40; private static final String TAB_REPLACEMENT = " "; private static final String LINE_TRUNCATION = "[..]"; private static final String INDENT = " "; public static String cropLine(String text) { return cropLine(text, MAX_LINE_LENGTH, LINE_TRUNCATION); } public static String cropToSingleLine(String text) { return cropLine(text, 0, null); } private static String cropLine(String text, int maxLineLength, String lineTruncationMarker) { if(text == null) { return null; } StringBuilder result = new StringBuilder(); int newlineIndex = text.indexOf('\n'); if(newlineIndex > -1) { int newlineCounter = 0; for(int i = 0; i < text.length(); i++) { if(text.charAt(i) == '\n') { newlineCounter++; } } appendTruncated(text.subSequence(0, newlineIndex), result, maxLineLength, lineTruncationMarker); if(newlineCounter == 1) { result.append(" [+1 line]"); } else if(newlineCounter > 1) { result.append(" [+").append(newlineCounter).append(" lines]"); } } else { appendTruncated(text, result, maxLineLength, lineTruncationMarker); } return result.toString(); } public static String cropTextBlock(String text) { return cropTextBlock(text, MAX_LINE_LENGTH, LINE_TRUNCATION, MAX_LINES, TAB_REPLACEMENT); } private static String cropTextBlock(String text, int maxLineLength, String lineTruncationMarker, int maxLines, String tabReplacement) { if(text == null) { return null; } // crop to a sane size, e.g. 80x25 characters StringBuilder result=new StringBuilder(); StringBuilder lineBuilder=new StringBuilder(); int lineCounter = 0; for(int i=0;i<text.length();i++) { char current = text.charAt(i); if(current == '\t') { if(tabReplacement != null) { lineBuilder.append(tabReplacement); } else { lineBuilder.append('\t'); } } else if(current == '\n') { if(lineCounter < maxLines) { appendTruncated(lineBuilder, result, maxLineLength, lineTruncationMarker); result.append('\n'); } lineBuilder.setLength(0); lineCounter++; } else if(current != '\r') { lineBuilder.append(current); } } if(lineCounter >= maxLines) { int remaining = lineCounter - maxLines + 1; result.append("[.. ").append(remaining).append(" more lines ..]"); } else { appendTruncated(lineBuilder, result, maxLineLength, lineTruncationMarker); } return result.toString(); } private static void appendTruncated(CharSequence sourceBuilder, StringBuilder targetBuilder, int maxLineLength, String lineTruncationMarker) { if(maxLineLength < 1 || sourceBuilder.length() <= maxLineLength) { targetBuilder.append(sourceBuilder); return; } if(lineTruncationMarker == null) { targetBuilder.append(sourceBuilder.subSequence(0, maxLineLength)); } else { targetBuilder.append(sourceBuilder.subSequence(0, maxLineLength - lineTruncationMarker.length())); targetBuilder.append(lineTruncationMarker); } } public static String wrapWithPre(String text) { if(text == null) { return null; } text = SimpleXml.escape(text); text = text.replace("\n", "<br>"); return "<tt><pre>" + text + "</pre></tt>"; } public static String preformattedTooltip(String text) { if(text == null) { return null; } return "<html>" + wrapWithPre(text) + "</html>"; } public static String formatCondition(Condition condition) { if(condition == null) { return null; } StringBuilder result = new StringBuilder(); formatCondition(condition, result, 0); return result.toString(); } private static void formatCondition(Condition condition, StringBuilder result, int indent) { if(condition == null) { appendIndent(result, indent); result.append("null"); } else if(condition instanceof ConditionWrapper) { ConditionWrapper wrapper = (ConditionWrapper)condition; String operator; if(wrapper instanceof Not) { operator = "!"; } else { // Unknown wrapper. Improvise. operator = wrapper.getClass().getSimpleName(); } Condition c = wrapper.getCondition(); appendIndent(result, indent); result.append(operator).append("("); if(c == null) { result.append("null"); } else { result.append("\n"); formatCondition(c, result, indent+1); appendIndent(result, indent); } result.append(")"); } else if(condition instanceof ConditionGroup) { ConditionGroup group = (ConditionGroup) condition; String operator; if(group instanceof And) { operator = "&&"; } else if(group instanceof Or) { operator = "||"; } else { // Unknown group. Improvise. operator = group.getClass().getSimpleName(); } List<Condition> conditions = group.getConditions(); appendIndent(result, indent); result.append("("); if(conditions == null || conditions.isEmpty()) { result.append("[").append(operator).append(" without conditions.]"); } else { result.append("\n"); boolean first = true; for(Condition current : conditions) { if(first) { first = false; } else { appendIndent(result, indent+1); result.append(operator).append("\n"); } formatCondition(current, result, indent+1); } appendIndent(result, indent); } result.append(")"); } else { // an "ordinary" condition. appendIndent(result, indent); result.append(condition); } if(indent > 0) { result.append("\n"); } } private static void appendIndent(StringBuilder result, int indent) { for(int i=0;i<indent;i++) { result.append(INDENT); } } }