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 of this
34 * document up into tokens. May return null if this document is not to be
35 * 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 this document
44 * up into tokens. May throw an exception if this is not supported for this
45 * type of document.
46 *
47 * @param tm
48 * The new token marker
49 */
50 public void setTokenMarker( TokenMarker tm )
51 {
52 tokenMarker = tm;
53 if( tm == null )
54 return;
55 tokenMarker.insertLines( 0, getDefaultRootElement().getElementCount() );
56 tokenizeLines();
57 }
58
59 /***
60 * Reparses the document, by passing all lines to the token marker. This
61 * should be called after the document is first 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 token marker.
70 * This should be called after a large quantity of text is first inserted.
71 *
72 * @param start
73 * The first line to parse
74 * @param len
75 * The number of lines, after the first one to parse
76 */
77 public void tokenizeLines( int start, int len )
78 {
79 if( tokenMarker == null || !tokenMarker.supportsMultilineTokens() )
80 return;
81
82 Segment lineSegment = new Segment();
83 Element map = getDefaultRootElement();
84
85 len += start;
86
87 try
88 {
89 for( int i = start; i < len; i++ )
90 {
91 Element lineElement = map.getElement( i );
92 int lineStart = lineElement.getStartOffset();
93 getText( lineStart, lineElement.getEndOffset() - lineStart - 1, lineSegment );
94 tokenMarker.markTokens( lineSegment, i );
95 }
96 }
97 catch( BadLocationException bl )
98 {
99 SoapUI.logError( bl );
100 }
101 }
102
103 /***
104 * Starts a compound edit that can be undone in one operation. Subclasses
105 * that implement undo should override this method; this class has no undo
106 * functionality so this method is empty.
107 */
108 public void beginCompoundEdit()
109 {
110 }
111
112 /***
113 * Ends a compound edit that can be undone in one operation. Subclasses that
114 * implement undo should override this method; this class has no undo
115 * functionality so this method is empty.
116 */
117 public void endCompoundEdit()
118 {
119 }
120
121 /***
122 * Adds an undoable edit to this document's undo list. The edit should be
123 * ignored if something is currently being undone.
124 *
125 * @param edit
126 * The undoable edit
127 *
128 * @since jEdit 2.2pre1
129 */
130 public void addUndoableEdit( UndoableEdit edit )
131 {
132 }
133
134
135 protected TokenMarker tokenMarker;
136
137 /***
138 * We overwrite this method to update the token marker state immediately so
139 * that any event listeners get a consistent token marker.
140 */
141 protected void fireInsertUpdate( DocumentEvent evt )
142 {
143 if( tokenMarker != null )
144 {
145 DocumentEvent.ElementChange ch = evt.getChange( getDefaultRootElement() );
146 if( ch != null )
147 {
148 tokenMarker.insertLines( ch.getIndex() + 1, ch.getChildrenAdded().length - ch.getChildrenRemoved().length );
149 }
150 }
151
152 super.fireInsertUpdate( evt );
153 }
154
155 /***
156 * We overwrite this method to update the token marker state immediately so
157 * that any event listeners get a consistent token marker.
158 */
159 protected void fireRemoveUpdate( DocumentEvent evt )
160 {
161 if( tokenMarker != null )
162 {
163 DocumentEvent.ElementChange ch = evt.getChange( getDefaultRootElement() );
164 if( ch != null )
165 {
166 tokenMarker.deleteLines( ch.getIndex() + 1, ch.getChildrenRemoved().length - ch.getChildrenAdded().length );
167 }
168 }
169
170 super.fireRemoveUpdate( evt );
171 }
172 }