⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtfreader.java

📁 java实现读取RTF文本,对采用RTF加密的文本可做解码参考
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      InputStream charsetStream;      charsetStream = (InputStream)java.security.AccessController.	              doPrivileged(new java.security.PrivilegedAction() {	  public Object run() {	      return RTFReader.class.getResourceAsStream		                     ("charsets/" + name + ".txt");	  }      });      set = readCharset(charsetStream);      defineCharacterSet(name, set);    }    return set;}/** Parses a character set from an InputStream. The character set * must contain 256 decimal integers, separated by whitespace, with * no punctuation. B- and C- style comments are allowed. * * @returns the newly read character set */static char[] readCharset(InputStream strm)     throws IOException{    char[] values = new char[256];    int i;    StreamTokenizer in = new StreamTokenizer(new BufferedReader(           // new InputStreamReader(strm, "ISO-8859-1")));           new InputStreamReader(strm, "gb2312")));    in.eolIsSignificant(false);    in.commentChar('#');    in.slashSlashComments(true);    in.slashStarComments(true);    i = 0;    while (i < 256) {	int ttype;	try {	    ttype = in.nextToken();	} catch (Exception e) {	    throw new IOException("Unable to read from character set file (" + e + ")");	}	if (ttype != in.TT_NUMBER) {//	    System.out.println("Bad token: type=" + ttype + " tok=" + in.sval);	    throw new IOException("Unexpected token in character set file");//	    continue;	}	values[i] = (char)(in.nval);	i++;    }    return values;}static char[] readCharset(java.net.URL href)     throws IOException{    return readCharset(href.openStream());}/** An interface (could be an entirely abstract class) describing *  a destination. The RTF reader always has a current destination *  which is where text is sent. * *  @see RTFReader */interface Destination {    void handleBinaryBlob(byte[] data);    void handleText(String text);    boolean handleKeyword(String keyword);    boolean handleKeyword(String keyword, int parameter);    void begingroup();    void endgroup(Dictionary oldState);    void close();}/** This data-sink class is used to implement ignored destinations *  (e.g. {\*\blegga blah blah blah} ) *  It accepts all keywords and text but does nothing with them. */class DiscardingDestination implements Destination{    public void handleBinaryBlob(byte[] data)    {	/* Discard binary blobs. */    }    public void handleText(String text)    {	/* Discard text. */    }    public boolean handleKeyword(String text)    {	/* Accept and discard keywords. */	return true;    }    public boolean handleKeyword(String text, int parameter)    {	/* Accept and discard parameterized keywords. */	return true;    }    public void begingroup()    {	/* Ignore groups --- the RTFReader will keep track of the	   current group level as necessary */    }    public void endgroup(Dictionary oldState)    {	/* Ignore groups */    }    public void close()    {	/* No end-of-destination cleanup needed */    }}/** Reads the fonttbl group, inserting fonts into the RTFReader's *  fontTable dictionary. */class FonttblDestination implements Destination{    int nextFontNumber;    Object fontNumberKey = null;    String nextFontFamily;    public void handleBinaryBlob(byte[] data)    { /* Discard binary blobs. */ }    public void handleText(String text)    {        int semicolon = text.indexOf(';');        String fontName;        if (semicolon > -1)            fontName = text.substring(0, semicolon);        else            fontName = text;        /* TODO: do something with the font family. */        if (nextFontNumber == -1            && fontNumberKey != null) {            //font name might be broken across multiple calls            fontName = fontTable.get(fontNumberKey) + fontName;        } else {            fontNumberKey = Integer.valueOf(nextFontNumber);        }        fontTable.put(fontNumberKey, fontName);	nextFontNumber = -1;	nextFontFamily = null;        return;    }    public boolean handleKeyword(String keyword)    {	if (keyword.charAt(0) == 'f') {	    nextFontFamily = keyword.substring(1);	    return true;	}	return false;    }    public boolean handleKeyword(String keyword, int parameter)    {	if (keyword.equals("f")) {	    nextFontNumber = parameter;	    return true;	}	return false;    }    /* Groups are irrelevant. */    public void begingroup() {}    public void endgroup(Dictionary oldState) {}    /* currently, the only thing we do when the font table ends is       dump its contents to the debugging log. */    public void close()    {        Enumeration nums = fontTable.keys();        warning("Done reading font table.");        while(nums.hasMoreElements()) {            Integer num = (Integer)nums.nextElement();            warning("Number " + num + ": " + fontTable.get(num));        }    }}/** Reads the colortbl group. Upon end-of-group, the RTFReader's *  color table is set to an array containing the read colors. */class ColortblDestination implements Destination{    int red, green, blue;    Vector proTemTable;    public ColortblDestination()    {	red = 0;	green = 0;	blue = 0;	proTemTable = new Vector();    }    public void handleText(String text)    {        int index = 0;        for (index = 0; index < text.length(); index ++) {            if (text.charAt(index) == ';') {                Color newColor;		newColor = new Color(red, green, blue);		proTemTable.addElement(newColor);            }        }    }    public void close()    {	int count = proTemTable.size();        warning("Done reading color table, " + count + " entries.");	colorTable = new Color[count];	proTemTable.copyInto(colorTable);    }    public boolean handleKeyword(String keyword, int parameter)    {        if (keyword.equals("red"))	    red = parameter;	else if (keyword.equals("green"))	    green = parameter;	else if (keyword.equals("blue"))	    blue = parameter;	else	    return false;	return true;    }    /* Colortbls don't understand any parameterless keywords */    public boolean handleKeyword(String keyword) { return false; }    /* Groups are irrelevant. */    public void begingroup() {}    public void endgroup(Dictionary oldState) {}    /* Shouldn't see any binary blobs ... */    public void handleBinaryBlob(byte[] data) {}}/** Handles the stylesheet keyword. Styles are read and sorted *  into the three style arrays in the RTFReader. */class StylesheetDestination    extends DiscardingDestination    implements Destination{    Dictionary definedStyles;    public StylesheetDestination()    {	definedStyles = new Hashtable();    }    public void begingroup()    {	setRTFDestination(new StyleDefiningDestination());    }    public void close()    {        Vector chrStyles, pgfStyles, secStyles;	chrStyles = new Vector();	pgfStyles = new Vector();	secStyles = new Vector();	Enumeration styles = definedStyles.elements();	while(styles.hasMoreElements()) {	    StyleDefiningDestination style;	    Style defined;	    style = (StyleDefiningDestination)styles.nextElement();	    defined = style.realize();	    warning("Style "+style.number+" ("+style.styleName+"): "+defined);	    String stype = (String)defined.getAttribute(Constants.StyleType);	    Vector toSet;	    if (stype.equals(Constants.STSection)) {	        toSet = secStyles;	    } else if (stype.equals(Constants.STCharacter)) {	        toSet = chrStyles;	    } else {	        toSet = pgfStyles;	    }	    if (toSet.size() <= style.number)	        toSet.setSize(style.number + 1);	    toSet.setElementAt(defined, style.number);	}	if (!(chrStyles.isEmpty())) {	    Style[] styleArray = new Style[chrStyles.size()];	    chrStyles.copyInto(styleArray);	    characterStyles = styleArray;	}	if (!(pgfStyles.isEmpty())) {	    Style[] styleArray = new Style[pgfStyles.size()];	    pgfStyles.copyInto(styleArray);	    paragraphStyles = styleArray;	}	if (!(secStyles.isEmpty())) {	    Style[] styleArray = new Style[secStyles.size()];	    secStyles.copyInto(styleArray);	    sectionStyles = styleArray;	}/* (old debugging code)	int i, m;	if (characterStyles != null) {	  m = characterStyles.length;	  for(i=0;i<m;i++)	    warnings.println("chrStyle["+i+"]="+characterStyles[i]);	} else warnings.println("No character styles.");	if (paragraphStyles != null) {	  m = paragraphStyles.length;	  for(i=0;i<m;i++)	    warnings.println("pgfStyle["+i+"]="+paragraphStyles[i]);	} else warnings.println("No paragraph styles.");	if (sectionStyles != null) {	  m = characterStyles.length;	  for(i=0;i<m;i++)	    warnings.println("secStyle["+i+"]="+sectionStyles[i]);	} else warnings.println("No section styles.");*/    }    /** This subclass handles an individual style */    class StyleDefiningDestination	extends AttributeTrackingDestination	implements Destination    {	final int STYLENUMBER_NONE = 222;	boolean additive;	boolean characterStyle;	boolean sectionStyle;	public String styleName;	public int number;	int basedOn;	int nextStyle;	boolean hidden;	Style realizedStyle;	public StyleDefiningDestination()	{	    additive = false;	    characterStyle = false;	    sectionStyle = false;	    styleName = null;	    number = 0;	    basedOn = STYLENUMBER_NONE;	    nextStyle = STYLENUMBER_NONE;	    hidden = false;	}	public void handleText(String text)	{	    if (styleName != null)		styleName = styleName + text;	    else		styleName = text;	}	public void close() {            int semicolon = (styleName == null) ? 0 : styleName.indexOf(';');	    if (semicolon > 0)		styleName = styleName.substring(0, semicolon);	    definedStyles.put(Integer.valueOf(number), this);	    super.close();	}	public boolean handleKeyword(String keyword)	{	    if (keyword.equals("additive")) {		additive = true;		return true;	    }	    if (keyword.equals("shidden")) {		hidden = true;		return true;	    }	    return super.handleKeyword(keyword);	}	public boolean handleKeyword(String keyword, int parameter)	{	    if (keyword.equals("s")) {		characterStyle = false;		sectionStyle = false;		number = parameter;	    } else if (keyword.equals("cs")) {		characterStyle = true;		sectionStyle = false;		number = parameter;	    } else if (keyword.equals("ds")) {		characterStyle = false;		sectionStyle = true;		number = parameter;	    } else if (keyword.equals("sbasedon")) {		basedOn = parameter;	    } else if (keyword.equals("snext")) {		nextStyle = parameter;	    } else {		return super.handleKeyword(keyword, parameter);	    }	    return true;	}	public Style realize()	{	    Style basis = null;	    Style next = null;	    if (realizedStyle != null)		return realizedStyle;	    if (basedOn != STYLENUMBER_NONE) {		StyleDefiningDestination styleDest;		styleDest = (StyleDefiningDestination)definedStyles.get(Integer.valueOf(basedOn));		if (styleDest != null && styleDest != this) {		    basis = styleDest.realize();		}	    }	    /* NB: Swing StyleContext doesn't allow distinct styles with	       the same name; RTF apparently does. This may confuse the	       user. */	    realizedStyle = target.addStyle(styleName, basis);	    if (characterStyle) {		realizedStyle.addAttributes(currentTextAttributes());		realizedStyle.addAttribute(Constants.StyleType,					   Constants.STCharacter);	    } else if (sectionStyle) {		realizedStyle.addAttributes(currentSectionAttributes());	        realizedStyle.addAttribute(Constants.StyleType,					   Constants.STSection);	    } else { /* must be a paragraph style */		realizedStyle.addAttributes(currentParagraphAttributes());	        realizedStyle.addAttribute(Constants.StyleType,					   Constants.STParagraph);	    }	    if (nextStyle != STYLENUMBER_NONE) {		StyleDefiningDestination styleDest;		styleDest = (StyleDefiningDestination)definedStyles.get(Integer.valueOf(nextStyle));		if (styleDest != null) {		    next = styleDest.realize();		}	    }	    if (next != null)		realizedStyle.addAttribute(Constants.StyleNext, next);	    realizedStyle.addAttribute(Constants.StyleAdditive,				       Boolean.valueOf(additive));	    realizedStyle.addAttribute(Constants.StyleHidden,				       Boolean.valueOf(hidden));	    return realizedStyle;	}    }}/** Handles the info group. Currently no info keywords are recognized *  so this is a subclass of DiscardingDestination. */class InfoDestination    extends DiscardingDestination    implements Destination{}/** RTFReader.TextHandlingDestination is an abstract RTF destination *  which simply tracks the attributes specified by the RTF control words *  in internal form and can produce acceptable AttributeSets for the *  current character, paragraph, and section attributes. It is up *  to the subclasses to determine what is done with the actual text. */abstract class AttributeTrackingDestination implements Destination{    /** This is the "chr" element of parserState, cached for     *  more efficient use */    MutableAttributeSet characterAttributes;    /** This is the "pgf" element of parserState, cached for     *  more efficient use */    MutableAttributeSet paragraphAttributes;    /** This is the "sec" element of parserState, cached for     *  more efficient use */    MutableAttributeSet sectionAttributes;    public AttributeTrackingDestination()    {	characterAttributes = rootCharacterAttributes();	parserState.put("chr", characterAttributes);	paragraphAttributes = rootParagraphAttributes();	parserState.put("pgf", paragraphAttributes);	sectionAttributes = rootSectionAttributes();	parserState.put("sec", sectionAttributes);    }    abstract public void handleText(String text);    public void handleBinaryBlob(byte[] data)    {        /* This should really be in TextHandlingDestination, but	 * since *nobody* does anything with binary blobs, this	 * is more convenient. */	warning("Unexpected binary data in RTF file.");    }    public void begingroup()    {	AttributeSet characterParent = currentTextAttributes();	AttributeSet paragraphParent = currentParagraphAttributes();	AttributeSet sectionParent = currentSectionAttributes();	/* It would probably be more efficient to use the	 * resolver property of the attributes set for	 * implementing rtf groups,	 * but that's needed for styles. */	/* update the cached attribute dictionaries */	characterAttributes = new SimpleAttributeSet();	characterAttributes.addAttributes(characterParent);	parserState.put("chr", characterAttributes);	paragraphAttributes = new SimpleAttributeSet();	paragraphAttributes.addAttributes(paragraphParent);	parserState.put("pgf", paragraphAttributes);	sectionAttributes = new SimpleAttributeSet();	sectionAttributes.addAttributes(sectionParent);	parserState.put("sec", sectionAttributes);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -