~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to editor/libsrc/org/netbeans/editor/MultiMark.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
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]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
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.
 
29
 *
 
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.
 
40
 */
 
41
 
 
42
package org.netbeans.editor;
 
43
 
 
44
import java.lang.ref.WeakReference;
 
45
import javax.swing.text.Position;
 
46
 
 
47
 
 
48
/**
 
49
 * Multipurpose mark that can be used
 
50
 * both as the traditional swing mark
 
51
 * or the bias mark.
 
52
 *
 
53
 * @author Miloslav Metelka
 
54
 * @version 1.00
 
55
 */
 
56
 
 
57
final class MultiMark extends WeakReference<BasePosition> implements Runnable {
 
58
 
 
59
    /** Whether mark has a backward (or forward) bias */
 
60
    static final int BACKWARD_BIAS = 1;
 
61
 
 
62
    /** Whether mark was disposed and can no longer be used */
 
63
    static final int VALID = 2;
 
64
 
 
65
    /** Storage of the marks uses this flag
 
66
     * to indicate that the diposed mark was physically removed
 
67
     * from the underlying array.
 
68
     */
 
69
    static final int REMOVED = 4;
 
70
    
 
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).
 
75
     */
 
76
    static final int COMPATIBLE = 8;
 
77
    
 
78
    /** Whether the compatible mark has zero offset regardless of
 
79
     * what MarkVector.getOffset() would return.
 
80
     */
 
81
    static final int ZERO = 16;
 
82
    
 
83
    /** Offset at which the mark is located in the document. */
 
84
    int rawOffset;
 
85
 
 
86
    /** Composition of the flags */
 
87
    int flags;
 
88
    
 
89
    /** Mark vector that hosts this mark. */
 
90
    private MarkVector markVector;
 
91
    
 
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));
 
96
    }
 
97
    
 
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);
 
102
    }
 
103
        
 
104
    /** Construct new mark. The mark is invalid by default.
 
105
     */
 
106
    private MultiMark(BasePosition pos, MarkVector markVector, int offset, int flags) {
 
107
        super(pos, org.openide.util.Utilities.activeReferenceQueue());
 
108
        if (pos != null) {
 
109
            pos.setMark(this);
 
110
        }
 
111
        this.markVector = markVector;
 
112
        this.rawOffset = offset; // will be corrected once the mark is inserted
 
113
        this.flags = flags;
 
114
    }
 
115
 
 
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}.
 
119
     */
 
120
    public Position.Bias getBias() {
 
121
        return ((flags & BACKWARD_BIAS) != 0)
 
122
            ? Position.Bias.Backward
 
123
            : Position.Bias.Forward;
 
124
    }
 
125
    
 
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)
 
132
                    : 0;
 
133
            } else { // already disposed
 
134
                throw new IllegalStateException();
 
135
            }
 
136
        }
 
137
    }
 
138
    
 
139
    public void run() {
 
140
        // Called by Utilities.activeReferenceQueue() once the BasePosition
 
141
        // is no longer reachable
 
142
        dispose();
 
143
 
 
144
    }
 
145
 
 
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.
 
150
     */
 
151
    public void dispose() {
 
152
        synchronized (markVector) {
 
153
            if ((flags & VALID) != 0) {
 
154
                flags &= ~VALID;
 
155
                markVector.notifyMarkDisposed();
 
156
            } else { // already disposed before
 
157
                throw new IllegalStateException();
 
158
            }
 
159
        }
 
160
    }
 
161
    
 
162
    /** @return true if this mark was not disposed yet.
 
163
     */
 
164
    public boolean isValid() {
 
165
        synchronized(markVector) {
 
166
            return ((flags & VALID) != 0);
 
167
        }
 
168
    }
 
169
 
 
170
    public @Override String toString() {
 
171
        StringBuffer sb = new StringBuffer();
 
172
        synchronized(markVector) {
 
173
            if ((flags & VALID) != 0) {
 
174
                sb.append("offset=" + getOffset()); // NOI18N
 
175
            } else {
 
176
                sb.append("removed"); // NOI18N
 
177
            }
 
178
            sb.append(", bias="); // NOI18N
 
179
            sb.append(getBias());
 
180
            
 
181
            return sb.toString();
 
182
        }
 
183
    }
 
184
 
 
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());
 
194
            } else {
 
195
                sb.append('X');
 
196
                sb.append(markVector.getOffset(rawOffset));
 
197
                sb.append('X');
 
198
            }
 
199
            sb.append(", "); // NOI18N
 
200
            sb.append(((flags & BACKWARD_BIAS) != 0) ? 'B' : 'F');
 
201
            if ((flags & VALID) != 0) {
 
202
                sb.append('V');
 
203
            }
 
204
            if ((flags & REMOVED) != 0) {
 
205
                sb.append('R');
 
206
            }
 
207
            if ((flags & COMPATIBLE) != 0) {
 
208
                sb.append('C');
 
209
            }
 
210
            if ((flags & ZERO) != 0) {
 
211
                sb.append('Z');
 
212
            }
 
213
            sb.append(')');
 
214
 
 
215
            return sb.toString();
 
216
        }
 
217
    }
 
218
 
 
219
 
 
220
}