001: /*
002: * SyntaxDocument.java - Document that can be tokenized
003: * Copyright (C) 1999 Slava Pestov
004: *
005: * You may use and modify this package for any purpose. Redistribution is
006: * permitted, in both source and binary form, provided that this notice
007: * remains intact in all source distributions of this package.
008: */
009:
010: package org.syntax.jedit;
011:
012: import javax.swing.event.DocumentEvent;
013: import javax.swing.text.BadLocationException;
014: import javax.swing.text.Element;
015: import javax.swing.text.PlainDocument;
016: import javax.swing.text.Segment;
017: import javax.swing.undo.UndoableEdit;
018:
019: import org.syntax.jedit.tokenmarker.TokenMarker;
020:
021: import com.eviware.soapui.SoapUI;
022:
023: /**
024: * A document implementation that can be tokenized by the syntax highlighting
025: * system.
026: *
027: * @author Slava Pestov
028: * @version $Id$
029: */
030: public class SyntaxDocument extends PlainDocument {
031: /**
032: * Returns the token marker that is to be used to split lines
033: * of this document up into tokens. May return null if this
034: * document is not to be colorized.
035: */
036: public TokenMarker getTokenMarker() {
037: return tokenMarker;
038: }
039:
040: /**
041: * Sets the token marker that is to be used to split lines of
042: * this document up into tokens. May throw an exception if
043: * this is not supported for this type of document.
044: * @param tm The new token marker
045: */
046: public void setTokenMarker(TokenMarker tm) {
047: tokenMarker = tm;
048: if (tm == null)
049: return;
050: tokenMarker.insertLines(0, getDefaultRootElement()
051: .getElementCount());
052: tokenizeLines();
053: }
054:
055: /**
056: * Reparses the document, by passing all lines to the token
057: * marker. This should be called after the document is first
058: * loaded.
059: */
060: public void tokenizeLines() {
061: tokenizeLines(0, getDefaultRootElement().getElementCount());
062: }
063:
064: /**
065: * Reparses the document, by passing the specified lines to the
066: * token marker. This should be called after a large quantity of
067: * text is first inserted.
068: * @param start The first line to parse
069: * @param len The number of lines, after the first one to parse
070: */
071: public void tokenizeLines(int start, int len) {
072: if (tokenMarker == null
073: || !tokenMarker.supportsMultilineTokens())
074: return;
075:
076: Segment lineSegment = new Segment();
077: Element map = getDefaultRootElement();
078:
079: len += start;
080:
081: try {
082: for (int i = start; i < len; i++) {
083: Element lineElement = map.getElement(i);
084: int lineStart = lineElement.getStartOffset();
085: getText(lineStart, lineElement.getEndOffset()
086: - lineStart - 1, lineSegment);
087: tokenMarker.markTokens(lineSegment, i);
088: }
089: } catch (BadLocationException bl) {
090: SoapUI.logError(bl);
091: }
092: }
093:
094: /**
095: * Starts a compound edit that can be undone in one operation.
096: * Subclasses that implement undo should override this method;
097: * this class has no undo functionality so this method is
098: * empty.
099: */
100: public void beginCompoundEdit() {
101: }
102:
103: /**
104: * Ends a compound edit that can be undone in one operation.
105: * Subclasses that implement undo should override this method;
106: * this class has no undo functionality so this method is
107: * empty.
108: */
109: public void endCompoundEdit() {
110: }
111:
112: /**
113: * Adds an undoable edit to this document's undo list. The edit
114: * should be ignored if something is currently being undone.
115: * @param edit The undoable edit
116: *
117: * @since jEdit 2.2pre1
118: */
119: public void addUndoableEdit(UndoableEdit edit) {
120: }
121:
122: // protected members
123: protected TokenMarker tokenMarker;
124:
125: /**
126: * We overwrite this method to update the token marker
127: * state immediately so that any event listeners get a
128: * consistent token marker.
129: */
130: protected void fireInsertUpdate(DocumentEvent evt) {
131: if (tokenMarker != null) {
132: DocumentEvent.ElementChange ch = evt
133: .getChange(getDefaultRootElement());
134: if (ch != null) {
135: tokenMarker.insertLines(ch.getIndex() + 1, ch
136: .getChildrenAdded().length
137: - ch.getChildrenRemoved().length);
138: }
139: }
140:
141: super .fireInsertUpdate(evt);
142: }
143:
144: /**
145: * We overwrite this method to update the token marker
146: * state immediately so that any event listeners get a
147: * consistent token marker.
148: */
149: protected void fireRemoveUpdate(DocumentEvent evt) {
150: if (tokenMarker != null) {
151: DocumentEvent.ElementChange ch = evt
152: .getChange(getDefaultRootElement());
153: if (ch != null) {
154: tokenMarker.deleteLines(ch.getIndex() + 1, ch
155: .getChildrenRemoved().length
156: - ch.getChildrenAdded().length);
157: }
158: }
159:
160: super.fireRemoveUpdate(evt);
161: }
162: }
|