📄 quotefilter.java
字号:
/** * $RCSfile: QuoteFilter.java,v $ * $Revision: 1.2 $ * $Date: 2002/04/01 17:50:14 $ * * Copyright (C) 1999-2002 CoolServlets, Inc. All rights reserved. * * This software is the proprietary information of CoolServlets, Inc. * Use is subject to license terms. */package com.jivesoftware.forum.filter;import com.jivesoftware.forum.*;import com.jivesoftware.util.StringUtils;import java.io.*;import java.util.*;/** * A ForumMessageFilter that highlights quoted messages * based upon the level of indentation - very similar to * how groups.google.com highlights quotes. * * @author Bruce Ritchie */public class QuoteFilter extends ForumMessageFilter { private ArrayList quoteColors; private char quoteChar; private boolean reformatTextEnabled; public QuoteFilter() { quoteColors = new ArrayList(); quoteColors.add("#660066"); quoteColors.add("#007777"); quoteColors.add("#3377ff"); quoteColors.add("#669966"); quoteColors.add("#660000"); quoteChar = '>'; reformatTextEnabled = false; } /** * Clones a new filter that will have the same properties and that * will wrap around the specified message. * * @param message the ForumMessage to wrap the new filter around. */ public ForumMessageFilter clone(ForumMessage message){ QuoteFilter filter = new QuoteFilter(); filter.quoteColors = quoteColors; filter.reformatTextEnabled = reformatTextEnabled; filter.quoteChar = quoteChar; filter.message = message; return filter; } public boolean isCacheable() { return true; } //FROM THE FORUMMESSAGE INTERFACE// /** * Returns the subject of the message with URLs changed to working links if * filtering on the subject is enabled. * * @return the filtered message subject. */ public String getSubject() { return message.getSubject(); } /** * Returns the body of the message with quoted lines quoted appropriately. * * @return the filtered message body. */ public String getBody() { return parseQuotes(message.getBody()); } //OTHER METHODS// public String getQuoteColors() { StringBuffer sb = new StringBuffer(); for(int x=0; x < quoteColors.size(); x++) { sb.append(quoteColors.get(x).toString()); if (x != quoteColors.size()-1) { sb.append(","); } } return sb.toString(); } public void setQuoteColors(String prefix) { if (prefix != null) { quoteColors = new ArrayList(); StringTokenizer st = new StringTokenizer(prefix, ","); while (st.hasMoreTokens()) { quoteColors.add(st.nextToken()); } } } public boolean isReformatTextEnabled() { return reformatTextEnabled; } public void setReformatTextEnabled(boolean enabled) { reformatTextEnabled = enabled; } public String getQuoteChar() { return new Character(quoteChar).toString(); } public void setQuoteChar(String c) { if (c != null) { quoteChar = c.trim().charAt(0); } } /** * This method takes a string which may contain quotes lines * and quotes the lines accordingly. It does this * by adding the prefix line postfix according to the appropriate * quote level. An arbitrary level of quotes are available to be set, and * once those are used up it restarts from the beginning of the list * * @param input the text to be converted. * @returns the input string with the quoted lines handled accordingly. */ private String parseQuotes(String input) { // Check if the string is null or zero length -- if so, return // what was sent in. if (input == null || input.length() == 0) { return input; } StringBuffer sb = new StringBuffer(input.length() + 512); BufferedReader br = new BufferedReader(new StringReader(input), 1024); ArrayList lines = new ArrayList(); String line; char chars[]; try { while ((line = br.readLine()) != null) { lines.add(line); } br.close(); } catch (IOException e) { /* ignore */ } // correct text formatting if requested if (reformatTextEnabled) { reformatText(lines); } for (int c = 0; c < lines.size(); c++) { line = (String) lines.get(c); chars = StringUtils.replace(line, ">", ">").toCharArray(); if (isQuoted(chars)) { int count = countQuotes(chars) - 1; sb.append("<font color=\""); sb.append(quoteColors.get(count % quoteColors.size()).toString()); sb.append("\">"); sb.append(line); // for all following lines that have the same quote level // just append them to the buffer, we'll append the quotePostfix // at the end. This saves on needless html being generated and // reduces the size of the final html page. (Every little bit // counts) for (int g = c+1; g < lines.size(); g++) { line = (String) lines.get(g); chars = StringUtils.replace(line, ">", ">").toCharArray(); if (isQuoted(chars) && (countQuotes(chars) - 1 == count)) { sb.append("\n").append(line); c = g; } else { break; } } sb.append("</font>").append("\n"); } else { sb.append(line).append("\n"); } } return sb.toString(); } /** * This method takes a list of strings (one per line) and * through some heuristics attempts to correct for badly wrapped * lines.<p> * * This is allows for: <p> * * <ul> * <li>Making the text easier to read</li> * <li>Restoring the text format as close as possible to the original * formatting of the text prior to being reformatted by a MUA such as * Microsoft Outlook. MUA's often wrap lines of length > 76 characters * regardless of whether they are quoted or not.</li> * </ul> * * @param lines an arraylist of strings, one line/arraylist entry */ private void reformatText(ArrayList lines) { char chars[]; int count; int readAhead; boolean isHTMLFilterActive = false; for (int c = 0; c < lines.size(); c++) { chars = getLineAsChar(lines, c); // if this isn't a quoted line, skip it if (!isQuoted(chars)) { continue; } // check to see if we substituted any > text if (chars.length < ((String) lines.get(c)).length()) { isHTMLFilterActive = true; } count = countQuotes(chars); readAhead = (lines.size() <= c + count + 1) ? lines.size() : c + count + 1; LinkedList l = new LinkedList(); // For each quoted line, read ahead (n-1 quotes) lines to see // if the following lines are actually wrapped text from the // current quoted line. // // Notes: - If any of the following lines do not have < n quotes // (no quote acceptable), they are not wrapped text. However // if prior following lines fulfill all the other criteria, // they are wrapped text // - If any of the following lines have more than 2 words, // they are not wrapped text // - If any consecutive following lines have the same number // of quotes, they are not wrapped text // - If any of the following lines have less quotes than the // previous following lines, they are not wrapped text // - If the following line has no characters, they are not // wrapped text for (int g = c+1; g < readAhead; g++) { chars = getLineAsChar(lines, g); l.addLast(chars); // rule 1 if (isQuoted(chars) && countQuotes(chars) > count) { // System.err.println("Too many quotes - " + new String(chars)); l.removeLast(); break; } // rule 2 if (countWords(chars) > 2) { // System.err.println("Too many words - " + new String(chars)); l.removeLast(); break; } // rule 3 if (countQuotes(chars) == count) { // System.err.println("same number of quotes - " + new String(chars)); l.removeLast(); break; } // rule 4 if (!checkQuoteConsistency(l)) { // System.err.println("Quote Inconsistent - " + new String(chars)); l.removeLast(); break; } // rule 5 if (new String(chars).trim().length() < 1) { // System.err.println("Empty line - " + new String(chars)); l.removeLast(); break; } } // we have wrapped text if (l.size() > 0) { Iterator iter = l.iterator(); StringBuffer sb = new StringBuffer(l.size()+1 * 80); String line = (String) lines.get(c); if (isHTMLFilterActive) { line = StringUtils.replace(line, ">", ">"); } sb.append(line); while (iter.hasNext()) { chars = (char[]) iter.next(); sb.append(" "); sb.append(stripQuotes(chars)); lines.remove(c+1); } lines.set(c, sb.toString()); } } } private char[] getLineAsChar(ArrayList lines, int number) { String line = (String) lines.get(number); return StringUtils.replace(line, ">", ">").toCharArray(); } private int countWords(char[] chars) { String line = stripQuotes(chars).trim(); int count = 0; for (int x=0; x < line.length(); x++) { if (line.charAt(x) == ' ') { count++; } } return count + 1; } private boolean checkQuoteConsistency(LinkedList l) { for (int c = l.size()-1; c > 0; c--) { for (int g = 0; g < c; g++) { if (countQuotes((char[]) l.get(c)) < countQuotes((char[]) l.get(g))) { return false; } } } return true; } private boolean isQuoted(char[] chars) { for (int c = 0; c < chars.length; c++) { if (chars[c] == quoteChar) { return true; } else if (chars[c] != ' ') { return false; } } return false; } private int countQuotes(char[] chars) { int quoteCount = 0; for (int c = 0; c < chars.length; c++) { if (chars[c] == quoteChar) { quoteCount++; } else if (chars[c] == ' ') { continue; } else { return quoteCount; } } return quoteCount; } private String stripQuotes(char[] line) { StringBuffer sb = new StringBuffer(new String(line)); boolean start = false; for (int c = 0; c < sb.length(); c++) { if (!start && sb.charAt(c) == quoteChar) { sb.deleteCharAt(c); if (c > 0) { c--; } } else if (!start && sb.charAt(c) != ' ') { start = true; } } return sb.toString().trim(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -