2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.editor;
44
import java.lang.ref.WeakReference;
45
import javax.swing.text.Position;
49
* Multipurpose mark that can be used
50
* both as the traditional swing mark
53
* @author Miloslav Metelka
57
final class MultiMark extends WeakReference<BasePosition> implements Runnable {
59
/** Whether mark has a backward (or forward) bias */
60
static final int BACKWARD_BIAS = 1;
62
/** Whether mark was disposed and can no longer be used */
63
static final int VALID = 2;
65
/** Storage of the marks uses this flag
66
* to indicate that the diposed mark was physically removed
67
* from the underlying array.
69
static final int REMOVED = 4;
71
/** Whether mark behaves so that it conforms to the behavior
72
* of the swing positions. This behavior requires the mark
73
* to keep its offset to be zero once the mark
74
* reaches the zero offset (by removal in the document).
76
static final int COMPATIBLE = 8;
78
/** Whether the compatible mark has zero offset regardless of
79
* what MarkVector.getOffset() would return.
81
static final int ZERO = 16;
83
/** Offset at which the mark is located in the document. */
86
/** Composition of the flags */
89
/** Mark vector that hosts this mark. */
90
private MarkVector markVector;
92
/** Construct compatible mark */
93
MultiMark(BasePosition pos, MarkVector markVector, int offset) {
94
this(pos, markVector, offset,
95
(offset != 0) ? COMPATIBLE : (COMPATIBLE | ZERO | BACKWARD_BIAS));
98
/** Construct bias mark */
99
MultiMark(BasePosition pos, MarkVector markVector, int offset, Position.Bias bias) {
100
this(pos, markVector, offset,
101
(bias == Position.Bias.Backward) ? BACKWARD_BIAS : 0);
104
/** Construct new mark. The mark is invalid by default.
106
private MultiMark(BasePosition pos, MarkVector markVector, int offset, int flags) {
107
super(pos, org.openide.util.Utilities.activeReferenceQueue());
111
this.markVector = markVector;
112
this.rawOffset = offset; // will be corrected once the mark is inserted
116
/** @return the bias of this mark. It will be either
117
* {@link javax.swing.text.Position.Bias.Forward}
118
* or {@link javax.swing.text.Position.Bias.Backward}.
120
public Position.Bias getBias() {
121
return ((flags & BACKWARD_BIAS) != 0)
122
? Position.Bias.Backward
123
: Position.Bias.Forward;
126
/** Get the position of this mark */
127
public int getOffset() {
128
synchronized (markVector) {
129
if ((flags & VALID) != 0) {
130
return ((flags & ZERO) == 0)
131
? markVector.getOffset(rawOffset)
133
} else { // already disposed
134
throw new IllegalStateException();
140
// Called by Utilities.activeReferenceQueue() once the BasePosition
141
// is no longer reachable
146
/** Mark will no longer represent a valid place in the document.
147
* Attempts to use the mark will result into throwing of
148
* {@link java.lang.IllegalStateException}.
149
* @throws IllegalStateException if the mark was already disposed before.
151
public void dispose() {
152
synchronized (markVector) {
153
if ((flags & VALID) != 0) {
155
markVector.notifyMarkDisposed();
156
} else { // already disposed before
157
throw new IllegalStateException();
162
/** @return true if this mark was not disposed yet.
164
public boolean isValid() {
165
synchronized(markVector) {
166
return ((flags & VALID) != 0);
170
public @Override String toString() {
171
StringBuffer sb = new StringBuffer();
172
synchronized(markVector) {
173
if ((flags & VALID) != 0) {
174
sb.append("offset=" + getOffset()); // NOI18N
176
sb.append("removed"); // NOI18N
178
sb.append(", bias="); // NOI18N
179
sb.append(getBias());
181
return sb.toString();
185
public String toStringDetail() {
186
StringBuffer sb = new StringBuffer();
187
synchronized(markVector) {
188
sb.append(System.identityHashCode(this));
189
sb.append(" ("); // NOI18N
190
sb.append(rawOffset);
191
sb.append(" -> "); // NOI18N
192
if ((flags & VALID) != 0) {
193
sb.append(getOffset());
196
sb.append(markVector.getOffset(rawOffset));
199
sb.append(", "); // NOI18N
200
sb.append(((flags & BACKWARD_BIAS) != 0) ? 'B' : 'F');
201
if ((flags & VALID) != 0) {
204
if ((flags & REMOVED) != 0) {
207
if ((flags & COMPATIBLE) != 0) {
210
if ((flags & ZERO) != 0) {
215
return sb.toString();