1 19 20 package org.netbeans.editor; 21 22 import java.util.Comparator ; 23 import java.util.Enumeration ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 import javax.swing.text.BadLocationException ; 27 import javax.swing.text.Element ; 28 import javax.swing.text.Position ; 29 30 36 37 38 41 public class Mark { 42 43 private static final MarkComparator MARK_COMPARATOR = new MarkComparator(); 44 45 46 private BaseDocument doc; 47 48 49 private MultiMark multiMark; 50 51 55 private Position.Bias bias; 56 57 58 public Mark() { 59 this(Position.Bias.Forward); 60 } 61 62 public Mark(Position.Bias bias) { 63 this.bias = bias; 64 } 65 66 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 { 77 BaseDocument ldoc = this.doc; 78 if (ldoc != null) { 79 throw new InvalidMarkException("Mark already inserted: mark=" + this + ", class=" + this.getClass()); } 82 83 this.doc = doc; 84 ldoc = this.doc; 85 Map docMarks = ldoc.marks; 86 synchronized (docMarks) { 87 if (multiMark != null) { 88 throw new IllegalStateException ("Mark already inserted: mark=" + this + ", class=" + this.getClass()); } 91 92 if (offset < 0 || offset > ldoc.getLength() + 1) { throw new BadLocationException ("Invalid offset", offset); } 95 96 multiMark = doc.marksStorage.createBiasMark(offset, bias); 97 doc.marksStorage.insert(multiMark); 98 docMarks.put(multiMark, this); 99 } 101 } 102 103 private void checkMarks(Map docMarks) { 104 for (Iterator it = docMarks.entrySet().iterator(); it.hasNext();) { 105 Map.Entry me = (Map.Entry )it.next(); 106 MultiMark mm = (MultiMark)me.getKey(); 107 Mark m = (Mark)me.getValue(); 108 109 if (m.multiMark != mm) { 110 throw new IllegalStateException ("m.class" + m.getClass() + " mapped to wrong mark=" + mm); } 112 } 113 } 114 115 void move(BaseDocument doc, int newOffset) throws InvalidMarkException, BadLocationException { 116 dispose(); 117 insert(doc, newOffset); 118 } 119 120 121 public final int getOffset() throws InvalidMarkException { 122 BaseDocument ldoc = doc; 123 if (ldoc != null) { 124 Map 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 138 public final int getLine() throws InvalidMarkException { 139 BaseDocument ldoc = doc; 140 if (ldoc != null) { 141 Map docMarks = ldoc.marks; 142 synchronized (docMarks) { 143 if (multiMark != null) { 144 int offset = multiMark.getOffset(); 145 Element 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 161 public final boolean getInsertAfter() { 162 return (bias == Position.Bias.Backward); 163 } 164 165 167 public final boolean getBackwardBias() { 168 return getInsertAfter(); 169 } 170 171 175 public final Position.Bias getBias() { 176 return bias; 177 } 178 179 int getBiasAsInt() { 180 return (bias == Position.Bias.Backward) ? -1 : +1; 181 } 182 183 187 public final void dispose() { 188 BaseDocument ldoc = doc; 189 if (ldoc != null) { 190 Map docMarks = ldoc.marks; 191 synchronized (docMarks) { 192 if (multiMark != null) { 193 if (docMarks.remove(multiMark) != this) { 194 throw new IllegalStateException ("Mark cannot be disposed mark=" + this + ", class=" + getClass()); } 196 197 multiMark.dispose(); 198 multiMark = null; 199 200 202 this.doc = null; 203 204 return; 205 } 206 } 207 } 208 209 throw new IllegalStateException ("Mark already disposed: mark=" + this + ", class=" + this.getClass()); } 212 213 216 public final void remove() throws InvalidMarkException { 217 dispose(); 218 } 219 220 221 227 public final int compare(int pos) throws InvalidMarkException { 228 return getOffset() - pos; 229 } 230 231 240 protected void removeUpdateAction(int pos, int len) { 241 } 242 243 244 247 public final boolean isValid() { 248 BaseDocument ldoc = doc; 249 if (ldoc != null) { 250 Map docMarks = ldoc.marks; 251 synchronized (docMarks) { 252 return (multiMark != null && multiMark.isValid()); 253 } 254 } 255 256 return false; 257 } 258 259 260 public String toString() { 261 return "offset=" + (isValid() ? Integer.toString(multiMark.getOffset()) : "<invalid>") + ", bias=" + bias; } 264 265 private static final class MarkComparator implements Comparator { 266 267 public int compare(Object o1, Object 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 (e.toString()); 279 } 280 } 281 282 } 283 284 } 285 | Popular Tags |