import java.io.*; import java.util.*; //import BufferLoad; /** * This type represents a chunk of text containing * a question and answer section, known as an faq. * The text is not 'marked up' particularly, or at least * only in a minimalistic way. * * @see FaqItem, Question, Answer * @author http://bumble.sf.net */ public class FAQ extends Object { //-------------------------------------------- private static String NEWLINE = System.getProperty("line.separator"); //-------------------------------------------- private boolean isGood; //-------------------------------------------- private String errors; //-------------------------------------------- private String title; //-------------------------------------------- private Vector faqItems; //-------------------------------------------- private Date startTime; //-------------------------------------------- private Date finishTime; //-------------------------------------------- public static String INDICATOR = "[faq]"; //-------------------------------------------- public static String TERMINATOR = "[/faq]"; public FAQ() { this.errors = ""; this.faqItems = new Vector(); this.title = ""; } //-------------------------------------------- public FAQ(String sText) { this(); this.loadData(sText); } //-------------------------------------------- /** return the number of milliseconds taken to load. */ public long getLoadDuration() { if (this.finishTime == null) { return 0; } if (this.startTime == null) { return 0; } return this.finishTime.getTime() - this.startTime.getTime(); } //-------------------------------------------- public void setTitle(String sTitle) { this.title = sTitle; } //-------------------------------------------- public String getTitle() { return this.title; } //-------------------------------------------- public static boolean recognize(String sText) { if (!sText.endsWith(FAQ.INDICATOR)) { return false; } //-- allow a single quote character to escape the //-- faq indicator. //-- if (sText.endsWith("'" + FAQ.INDICATOR)) { return false; } return true; } //-------------------------------------------- public void loadData(String sText) { this.startTime = new Date(); this.isGood = this.isFAQ(sText); if (!this.isGood) { this.finishTime = new Date(); return; } String sFaqContents = sText.trim().substring(FAQ.INDICATOR.length()); StringReader srText = new StringReader(sFaqContents); int iCurrentCharacter = 0; StringBuffer sbText = new StringBuffer(""); while (iCurrentCharacter != -1) { sbText.append((char)iCurrentCharacter); //-- System.out.println("sbText=" + sbText); if (FaqItem.isFaqItem(sbText.toString())) { //-- System.out.println(""); this.faqItems.addElement(new FaqItem(sbText.toString())); //-- //-- push the 'q:' back on the buffer since we are //-- if (sbText.toString().endsWith(Question.INDICATOR)) { sbText.setLength(0); sbText.append(Question.INDICATOR); } else { sbText.setLength(0); } } //-- if faqItem try { iCurrentCharacter = srText.read(); } catch (IOException e) { this.errors = "An IO Exception occurred while reading " + e; this.finishTime = new Date(); return; } } //-- while srText.close(); this.finishTime = new Date(); } //-- m: loadData() //-------------------------------------------- /** checks if this looks like an FAQ */ public static boolean isFAQ(String sText) { if (sText.trim().length() == 0) { return false; } if (!sText.trim().startsWith(FAQ.INDICATOR)) { return false; } if (!sText.trim().endsWith(FAQ.TERMINATOR)) { return false; } //-- allow a single quote to escape the faq //-- terminator tag. if (sText.trim().endsWith("'" + FAQ.TERMINATOR)) { return false; } return true; } //-------------------------------------------- /** is there any data */ public boolean isEmpty() { if (this.faqItems.size() == 0) { return true; } else { return false; } } //-------------------------------------------- /** how many question and answers are there */ public int countItems() { return this.faqItems.size(); } //-------------------------------------------- /** how many answers are there */ public int countAnswers() { int iAnswers = 0; FaqItem fiCurrent = new FaqItem(); Enumeration ii = faqItems.elements(); while (ii.hasMoreElements()) { fiCurrent = (FaqItem)ii.nextElement(); if (fiCurrent.hasAnswer()) { iAnswers++; } } return iAnswers; } //-------------------------------------------- public String toString() { StringBuffer sbReturn = new StringBuffer(""); FaqItem fiCurrent = new FaqItem(); sbReturn.append(FAQ.INDICATOR); sbReturn.append(NEWLINE); Enumeration ii = faqItems.elements(); while (ii.hasMoreElements()) { fiCurrent = (FaqItem)ii.nextElement(); sbReturn.append(fiCurrent.toString()); sbReturn.append(NEWLINE); } sbReturn.append(FAQ.TERMINATOR); return sbReturn.toString(); } //-------------------------------------------- public String printHtml() { StringBuffer sbReturn = new StringBuffer(""); return this.printHtml(true); } //-------------------------------------------- public String printHtml(boolean bIncludeIndex) { StringBuffer sbReturn = new StringBuffer(""); Enumeration ii; FaqItem fiCurrent = new FaqItem(); int iIndex; iIndex = 1; if (!this.title.trim().equals("")) { sbReturn.append("

"); sbReturn.append(this.title); sbReturn.append("

"); sbReturn.append(NEWLINE); } sbReturn.append(""); sbReturn.append(NEWLINE); if (bIncludeIndex) { sbReturn.append(""); sbReturn.append(NEWLINE); sbReturn.append(""); sbReturn.append(NEWLINE); } //-- if sbReturn.append("
"); sbReturn.append(NEWLINE); iIndex = 1; ii = faqItems.elements(); while (ii.hasMoreElements()) { fiCurrent = (FaqItem)ii.nextElement(); sbReturn.append(NEWLINE); if (bIncludeIndex) { sbReturn.append(fiCurrent.printIndexedHtml(iIndex)); //sbReturn.append(""); //sbReturn.append("(*)"); } else { sbReturn.append(fiCurrent.printHtml()); } sbReturn.append(NEWLINE); sbReturn.append(NEWLINE); iIndex++; } sbReturn.append("
"); sbReturn.append(NEWLINE); sbReturn.append("(top)"); return sbReturn.toString(); } //-------------------------------------------- public String printDocBook() { StringBuffer sbReturn = new StringBuffer(""); Enumeration ii; FaqItem fiCurrent = new FaqItem(); int iIndex; iIndex = 1; if (!this.title.trim().equals("")) { //sbReturn.append("

"); //sbReturn.append(this.title); //sbReturn.append("

"); //sbReturn.append(NEWLINE); } sbReturn.append(NEWLINE); sbReturn.append(""); sbReturn.append(NEWLINE); iIndex = 1; ii = faqItems.elements(); while (ii.hasMoreElements()) { fiCurrent = (FaqItem)ii.nextElement(); sbReturn.append(NEWLINE); sbReturn.append(fiCurrent.printDocBook()); sbReturn.append(NEWLINE); iIndex++; } sbReturn.append(NEWLINE); sbReturn.append(""); return sbReturn.toString(); } //-------------------------------------------- public String printReport() { StringBuffer sbReturn = new StringBuffer(""); sbReturn.append(""); sbReturn.append(NEWLINE); sbReturn.append("Faq title >"); sbReturn.append(this.getTitle()); sbReturn.append(NEWLINE); sbReturn.append("Number of items >"); sbReturn.append(this.countItems()); sbReturn.append(NEWLINE); sbReturn.append("Number of answers>"); sbReturn.append(this.countAnswers()); sbReturn.append(NEWLINE); sbReturn.append("Load time >"); sbReturn.append(this.getLoadDuration()); sbReturn.append(NEWLINE); sbReturn.append("last data good >"); sbReturn.append(this.isGood); sbReturn.append(NEWLINE); sbReturn.append("Faq is empty >"); sbReturn.append(this.isEmpty()); sbReturn.append(NEWLINE); sbReturn.append("error messages >"); sbReturn.append(this.errors); sbReturn.append(NEWLINE); return sbReturn.toString(); } //-------------------------------------------- public String print() { StringBuffer sbReturn = new StringBuffer(""); return this.toString(); } //-------------------------------------------- /** a main method for testing */ public static void main(String[] args) throws Exception { StringBuffer sbUsageMessage = new StringBuffer(""); sbUsageMessage.append("test usage: java FAQ faq-file [all]"); sbUsageMessage.append(NEWLINE); if (args.length == 0) { System.out.println(sbUsageMessage); System.exit(-1); } StringBuffer sbTest = new StringBuffer(""); sbTest.append(NEWLINE); if (args.length == 2) { System.out.println("Using data"); System.out.println(NEWLINE); System.out.println(BufferLoad.loadBuffer(args[0])); } FAQ faqTest = new FAQ(BufferLoad.loadBuffer(args[0])); System.out.println(faqTest.printHtml()); if (args.length == 2) { System.out.println(NEWLINE); System.out.println(faqTest.toString()); System.out.println(NEWLINE); System.out.println(faqTest.printReport()); } } //-- main() } //-- FAQ class