KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.Comparator JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Map JavaDoc;
26 import javax.swing.text.BadLocationException JavaDoc;
27 import javax.swing.text.Element JavaDoc;
28 import javax.swing.text.Position JavaDoc;
29
30 /**
31 * Marks hold the relative position in the document.
32 *
33 * @author Miloslav Metelka
34 * @version 1.00
35 */

36
37
38 /** Class defining basic type of mark. This is a mark used most frequently.
39 * It's instances are inserted into the leaf plane of the tree.
40 */

41 public class Mark {
42
43     private static final MarkComparator MARK_COMPARATOR = new MarkComparator();
44
45     /** Document to which this mark belongs. */
46     private BaseDocument doc;
47     
48     /** MultiMark to which this mark delegates. */
49     private MultiMark multiMark;
50     
51     /** Bias of the mark. It is either
52      * {@link javax.swing.text.Position.Bias.Forward}
53      * or {@link javax.swing.text.Position.Bias.Backward}
54      */

55     private Position.Bias JavaDoc bias;
56     
57     /** Construct new mark with forward bias. */
58     public Mark() {
59         this(Position.Bias.Forward);
60     }
61
62     public Mark(Position.Bias JavaDoc bias) {
63         this.bias = bias;
64     }
65     
66     /** Construct new mark.
67     * @param backwardBias whether the inserts performed right at the position
68     * of this mark will go after this mark i.e. this mark will not move
69     * forward when inserting right at its position. This flag corresponds
70     * to <tt>Position.Bias.Backward</tt>.
71     */

72     public Mark(boolean backwardBias) {
73         this(backwardBias ? Position.Bias.Backward : Position.Bias.Forward);
74     }
75     
76     void insert(BaseDocument doc, int offset) throws InvalidMarkException, BadLocationException JavaDoc {
77         BaseDocument ldoc = this.doc;
78         if (ldoc != null) {
79             throw new InvalidMarkException("Mark already inserted: mark=" + this // NOI18N
80
+ ", class=" + this.getClass()); // NOI18N
81
}
82
83         this.doc = doc;
84         ldoc = this.doc;
85         Map JavaDoc docMarks = ldoc.marks;
86         synchronized (docMarks) {
87             if (multiMark != null) {
88                 throw new IllegalStateException JavaDoc("Mark already inserted: mark=" + this // NOI18N
89
+ ", class=" + this.getClass()); // NOI18N
90
}
91
92             if (offset < 0 || offset > ldoc.getLength() + 1) { // doc.getEndPosition() is valid
93
throw new BadLocationException JavaDoc("Invalid offset", offset); // NOI18N
94
}
95
96             multiMark = doc.marksStorage.createBiasMark(offset, bias);
97             doc.marksStorage.insert(multiMark);
98             docMarks.put(multiMark, this);
99 // checkMarks(docMarks);
100
}
101     }
102     
103     private void checkMarks(Map JavaDoc docMarks) {
104         for (Iterator JavaDoc it = docMarks.entrySet().iterator(); it.hasNext();) {
105             Map.Entry JavaDoc me = (Map.Entry JavaDoc)it.next();
106             MultiMark mm = (MultiMark)me.getKey();
107             Mark m = (Mark)me.getValue();
108             
109             if (m.multiMark != mm) {
110                 throw new IllegalStateException JavaDoc("m.class" + m.getClass() + " mapped to wrong mark=" + mm); // NOI18N
111
}
112         }
113     }
114     
115     void move(BaseDocument doc, int newOffset) throws InvalidMarkException, BadLocationException JavaDoc {
116         dispose();
117         insert(doc, newOffset);
118     }
119     
120     /** Get the position of this mark */
121     public final int getOffset() throws InvalidMarkException {
122         BaseDocument ldoc = doc;
123         if (ldoc != null) {
124             Map JavaDoc docMarks = ldoc.marks;
125             synchronized (docMarks) {
126                 if (multiMark != null) {
127                     return multiMark.getOffset();
128                 } else {
129                     throw new InvalidMarkException();
130                 }
131             }
132         } else {
133             throw new InvalidMarkException();
134         }
135     }
136
137     /** Get the line number of this mark */
138     public final int getLine() throws InvalidMarkException {
139         BaseDocument ldoc = doc;
140         if (ldoc != null) {
141             Map JavaDoc docMarks = ldoc.marks;
142             synchronized (docMarks) {
143                 if (multiMark != null) {
144                     int offset = multiMark.getOffset();
145                     Element JavaDoc lineRoot = ldoc.getParagraphElement(0).getParentElement();
146                     return lineRoot.getElementIndex(offset);
147
148                 } else {
149                     throw new InvalidMarkException();
150                 }
151             }
152         } else {
153             throw new InvalidMarkException();
154         }
155     }
156
157     /** Get the insertAfter flag.
158      * Replaced by {@link #getBackwardBias()}
159      * @deprecated
160      */

161     public final boolean getInsertAfter() {
162         return (bias == Position.Bias.Backward);
163     }
164     
165     /** @return true if the mark has backward bias or false if it has forward bias.
166      */

167     public final boolean getBackwardBias() {
168         return getInsertAfter();
169     }
170     
171     /** @return the bias of this mark. It will be either
172      * {@link javax.swing.text.Position.Bias.Forward}
173      * or {@link javax.swing.text.Position.Bias.Backward}.
174      */

175     public final Position.Bias JavaDoc getBias() {
176         return bias;
177     }
178     
179     int getBiasAsInt() {
180         return (bias == Position.Bias.Backward) ? -1 : +1;
181     }
182     
183     /** Mark will no longer represent a valid place in the document.
184      * Although it will not be removed from the structure that holds
185      * the marks it will be done later automatically.
186      */

187     public final void dispose() {
188         BaseDocument ldoc = doc;
189         if (ldoc != null) {
190             Map JavaDoc docMarks = ldoc.marks;
191             synchronized (docMarks) {
192                 if (multiMark != null) {
193                     if (docMarks.remove(multiMark) != this) {
194                         throw new IllegalStateException JavaDoc("Mark cannot be disposed mark=" + this + ", class=" + getClass()); // NOI18N
195
}
196
197                     multiMark.dispose();
198                     multiMark = null;
199
200 // checkMarks(docMarks);
201

202                     this.doc = null;
203                     
204                     return;
205                 }
206             }
207         }
208
209         throw new IllegalStateException JavaDoc("Mark already disposed: mark=" + this // NOI18N
210
+ ", class=" + this.getClass()); // NOI18N
211
}
212         
213     /** Remove mark from the structure holding the marks. The mark can
214     * be inserted again into some document.
215     */

216     public final void remove() throws InvalidMarkException {
217         dispose();
218     }
219
220
221     /** Compare this mark to some position.
222      * @param pos tested position
223      * @return zero - if the marks have the same position
224      * less than zero - if this mark is before the position
225      * greater than zero - if this mark is after the position
226      */

227     public final int compare(int pos) throws InvalidMarkException {
228         return getOffset() - pos;
229     }
230
231     /** This function is called from removeUpdater when mark occupies
232      * the removal area. The mark can decide what to do next.
233      * If it doesn't redefine this method it will be simply moved to
234      * the begining of removal area. It is valid to add or remove other mark
235      * from this method. It is even possible (but not very useful)
236      * to add the mark to the removal area. However that mark will not be
237      * notified about current removal.
238      * @deprecated It will not be supported in the future.
239      */

240     protected void removeUpdateAction(int pos, int len) {
241     }
242
243
244     /** @return true if this mark is currently inserted in the document
245      * or false otherwise.
246      */

247     public final boolean isValid() {
248         BaseDocument ldoc = doc;
249         if (ldoc != null) {
250             Map JavaDoc docMarks = ldoc.marks;
251             synchronized (docMarks) {
252                 return (multiMark != null && multiMark.isValid());
253             }
254         }
255         
256         return false;
257     }
258
259     /** Get info about <CODE>Mark</CODE>. */
260     public String JavaDoc toString() {
261         return "offset=" + (isValid() ? Integer.toString(multiMark.getOffset()) : "<invalid>") // NOI18N
262
+ ", bias=" + bias; // NOI18N
263
}
264
265     private static final class MarkComparator implements Comparator JavaDoc {
266         
267         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
268             Mark m1 = ((Mark)o1);
269             Mark m2 = ((Mark)o2);
270             try {
271                 int offDiff = m1.getOffset() - m2.getOffset();
272                 if (offDiff != 0) {
273                     return offDiff;
274                 } else {
275                     return m1.getBiasAsInt() - m2.getBiasAsInt();
276                 }
277             } catch (InvalidMarkException e) {
278                 throw new IllegalStateException JavaDoc(e.toString());
279             }
280         }
281
282     }
283
284 }
285
Popular Tags