1
2
3
4
5
6
7
8
9
10 package org.syntax.jedit;
11
12 import javax.swing.event.DocumentEvent;
13 import javax.swing.text.BadLocationException;
14 import javax.swing.text.Element;
15 import javax.swing.text.PlainDocument;
16 import javax.swing.text.Segment;
17 import javax.swing.undo.UndoableEdit;
18
19 import org.syntax.jedit.tokenmarker.TokenMarker;
20
21 import com.eviware.soapui.SoapUI;
22
23 /***
24 * A document implementation that can be tokenized by the syntax highlighting
25 * system.
26 *
27 * @author Slava Pestov
28 * @version $Id$
29 */
30 public class SyntaxDocument extends PlainDocument
31 {
32 /***
33 * Returns the token marker that is to be used to split lines
34 * of this document up into tokens. May return null if this
35 * document is not to be colorized.
36 */
37 public TokenMarker getTokenMarker()
38 {
39 return tokenMarker;
40 }
41
42 /***
43 * Sets the token marker that is to be used to split lines of
44 * this document up into tokens. May throw an exception if
45 * this is not supported for this type of document.
46 * @param tm The new token marker
47 */
48 public void setTokenMarker(TokenMarker tm)
49 {
50 tokenMarker = tm;
51 if(tm == null)
52 return;
53 tokenMarker.insertLines(0,getDefaultRootElement()
54 .getElementCount());
55 tokenizeLines();
56 }
57
58 /***
59 * Reparses the document, by passing all lines to the token
60 * marker. This should be called after the document is first
61 * loaded.
62 */
63 public void tokenizeLines()
64 {
65 tokenizeLines(0,getDefaultRootElement().getElementCount());
66 }
67
68 /***
69 * Reparses the document, by passing the specified lines to the
70 * token marker. This should be called after a large quantity of
71 * text is first inserted.
72 * @param start The first line to parse
73 * @param len The number of lines, after the first one to parse
74 */
75 public void tokenizeLines(int start, int len)
76 {
77 if(tokenMarker == null || !tokenMarker.supportsMultilineTokens())
78 return;
79
80 Segment lineSegment = new Segment();
81 Element map = getDefaultRootElement();
82
83 len += start;
84
85 try
86 {
87 for(int i = start; i < len; i++)
88 {
89 Element lineElement = map.getElement(i);
90 int lineStart = lineElement.getStartOffset();
91 getText(lineStart,lineElement.getEndOffset()
92 - lineStart - 1,lineSegment);
93 tokenMarker.markTokens(lineSegment,i);
94 }
95 }
96 catch(BadLocationException bl)
97 {
98 SoapUI.logError( bl );
99 }
100 }
101
102 /***
103 * Starts a compound edit that can be undone in one operation.
104 * Subclasses that implement undo should override this method;
105 * this class has no undo functionality so this method is
106 * empty.
107 */
108 public void beginCompoundEdit() {}
109
110 /***
111 * Ends a compound edit that can be undone in one operation.
112 * Subclasses that implement undo should override this method;
113 * this class has no undo functionality so this method is
114 * empty.
115 */
116 public void endCompoundEdit() {
117 }
118
119 /***
120 * Adds an undoable edit to this document's undo list. The edit
121 * should be ignored if something is currently being undone.
122 * @param edit The undoable edit
123 *
124 * @since jEdit 2.2pre1
125 */
126 public void addUndoableEdit(UndoableEdit edit) {}
127
128
129 protected TokenMarker tokenMarker;
130
131 /***
132 * We overwrite this method to update the token marker
133 * state immediately so that any event listeners get a
134 * consistent token marker.
135 */
136 protected void fireInsertUpdate(DocumentEvent evt)
137 {
138 if(tokenMarker != null)
139 {
140 DocumentEvent.ElementChange ch = evt.getChange(
141 getDefaultRootElement());
142 if(ch != null)
143 {
144 tokenMarker.insertLines(ch.getIndex() + 1,
145 ch.getChildrenAdded().length -
146 ch.getChildrenRemoved().length);
147 }
148 }
149
150 super.fireInsertUpdate(evt);
151 }
152
153 /***
154 * We overwrite this method to update the token marker
155 * state immediately so that any event listeners get a
156 * consistent token marker.
157 */
158 protected void fireRemoveUpdate(DocumentEvent evt)
159 {
160 if(tokenMarker != null)
161 {
162 DocumentEvent.ElementChange ch = evt.getChange(
163 getDefaultRootElement());
164 if(ch != null)
165 {
166 tokenMarker.deleteLines(ch.getIndex() + 1,
167 ch.getChildrenRemoved().length -
168 ch.getChildrenAdded().length);
169 }
170 }
171
172 super.fireRemoveUpdate(evt);
173 }
174 }