KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > SyntaxSeg


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.editor;
21
22 import java.lang.ref.WeakReference JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import javax.swing.text.BadLocationException JavaDoc;
25 import javax.swing.text.Segment JavaDoc;
26
27 /**
28 * Encapsulation of a special static segment used
29 * by syntax scanners. Unfortunately document cache cannot
30 * guarantee that its fragment(s) will hold more than one character
31 * at the time so syntax scanning cannot be done by finder. Instead
32 * all the syntax analyzes are done over the syntax segment's data.
33 * Although it's shared across all instances of editors
34 * the loads into it should be fast as they are done from cache fragments
35 * by arraycopy() method.
36 * The syntax segment is separated into the slots because there
37 * can be more scanning necessary at one time.
38 * All the scanning must be done
39 *
40 * @author Miloslav Metelka
41 * @version 1.00
42 */

43 class SyntaxSeg extends Segment JavaDoc {
44
45     private static final char[] EMPTY_CHAR_ARRAY = new char[0];
46
47     private static final int MAX_SLOT_COUNT = 100;
48
49     private static final int REALLOC_INCREMENT = 2048;
50
51     private static ArrayList JavaDoc slotList = new ArrayList JavaDoc();
52
53     static synchronized Slot getFreeSlot() {
54         int cnt = slotList.size();
55         return (cnt > 0) ? (Slot)slotList.remove(cnt - 1) : new Slot();
56     }
57
58     static synchronized void releaseSlot(Slot slot) {
59         slotList.add(slot);
60     }
61
62     /** From this position on, the data in syntax segment must be marked
63     * invalid.
64     */

65     static synchronized void invalidate(BaseDocument doc, int pos) {
66         int cnt = slotList.size();
67         for (int i = 0; i < cnt; i++) {
68             ((Slot)slotList.get(i)).invalidate(doc, pos);
69         }
70     }
71
72     static class Slot extends Segment JavaDoc {
73
74         /** Document from which the data in syntax segment come from */
75         WeakReference JavaDoc segDocRef = new WeakReference JavaDoc(null);
76
77         /** Begining of valid data in syntax segment */
78         int segPos;
79
80         /** Begining of valid data in syntax segment */
81         int segLen;
82
83         Slot() {
84             this.array = EMPTY_CHAR_ARRAY;
85         }
86
87         /** Load the syntax segment if necessary from some location in some
88         * document. For best performance there's no pos or len correctness
89         * checking. Therefore caller must guarantee the correctness.
90         * @return real length that was loaded (syntax segment has limitation
91         * in size)
92         */

93         int load(BaseDocument doc, int pos, int len)
94         throws BadLocationException JavaDoc {
95             if (len <= 0) {
96                 if (len == 0) {
97                     count = 0;
98                     return 0;
99                 }
100                 throw new RuntimeException JavaDoc("len=" + len); // Critical error NOI18N
101
}
102
103             BaseDocument segDoc = (BaseDocument)segDocRef.get();
104             boolean difDoc = (doc != segDoc);
105             if (difDoc) {
106                 segDoc = doc;
107                 segDocRef = new WeakReference JavaDoc(segDoc);
108             }
109
110             if (difDoc // different documents
111
|| pos < segPos // position too low
112
|| pos > segPos + segLen // position too high
113
|| pos - segPos + len > array.length
114                ) { // wouldn't fit
115

116                 // possibly realloc the array
117
if (len > array.length) {
118                     char tmp[] = new char[len + REALLOC_INCREMENT];
119                     array = tmp; // original data are not recopied
120
}
121
122                 segPos = pos;
123                 segLen = len;
124
125                 doc.getChars(pos, array, 0, len); // read chars into array
126

127             } else { // inside array and will fit
128

129                 int endSegPos = segPos + segLen;
130                 int restLen = pos + len - endSegPos;
131                 if (restLen > 0) { // not fully inside
132
doc.getChars(endSegPos, array, segLen, restLen);
133                     segLen += restLen;
134                 }
135
136             }
137
138             offset = pos - segPos;
139             count = len;
140             if (offset < 0 || len < 0) {
141                 throw new BadLocationException JavaDoc("pos=" + pos + ", offset=" + offset // NOI18N
142
+ "len=" + len, offset); // Critical error NOI18N
143
}
144             return len;
145         }
146
147         /** Is the area inside the segment? */
148         boolean isAreaInside(BaseDocument doc, int pos, int len) {
149             return (doc == (BaseDocument)segDocRef.get()
150                     && pos >= segPos && pos + len <= segPos + segLen);
151         }
152
153         /** Invalidate the slot if it contains the data from the given document.
154         * @param doc document in which the change occured
155         * @param pos position in the document where the change occured
156         */

157         void invalidate(BaseDocument doc, int pos) {
158             if (doc == (BaseDocument)segDocRef.get()) {
159                 if (pos < segPos) {
160                     segLen = 0;
161                 } else if (pos < segPos + segLen) {
162                     segLen = pos - segPos;
163                 }
164             }
165         }
166
167     }
168
169 }
170
Popular Tags