1 19 20 package org.netbeans.modules.editor.lib2; 21 22 import java.beans.PropertyChangeListener ; 23 import java.beans.PropertyChangeSupport ; 24 import java.lang.ref.WeakReference ; 25 import java.util.ArrayList ; 26 import java.util.Iterator ; 27 import javax.swing.text.JTextComponent ; 28 import javax.swing.text.Document ; 29 30 39 public class DocumentsRegistry { 40 41 42 public static final String DOCUMENT_ID_PROP = "id"; 44 45 public static final String COMPONENT_ID_PROP = "componentId"; 47 private static final WeakReference [] EMPTY = new WeakReference [0]; 48 49 50 private static WeakReference [] docRefs = EMPTY; 51 52 53 private static int docRefsCount; 54 55 56 private static final ArrayList <Integer > docAct = new ArrayList <Integer >(); 57 58 59 private static WeakReference [] compRefs = EMPTY; 60 61 62 private static int compRefsCount; 63 64 65 private static final ArrayList <Integer > compAct = new ArrayList <Integer >(); 66 67 68 public static final String PROP_ACTIVE_COMPONENT = "org.netbeans.modules.editor.lib2.DocumentsRegistry.PROP_ACTIVE_COMPONENT"; 70 71 public static final String PROP_ACTIVE_DOCUMENT = "org.netbeans.modules.editor.lib2.DocumentsRegistry.PROP_ACTIVE_DOCUMENT"; 73 74 private static final PropertyChangeSupport PCS = new PropertyChangeSupport (DocumentsRegistry.class); 75 76 private static int consolidateCounter; 77 78 82 public static void addPropertyChangeListener(PropertyChangeListener l) { 83 PCS.addPropertyChangeListener(l); 84 } 85 86 90 public static void removePropertyChangeListener(PropertyChangeListener l) { 91 PCS.removePropertyChangeListener(l); 92 } 93 94 98 public static synchronized int getID(Document doc) { 99 Integer i = getIDInteger(doc); 100 return (i != null) ? i.intValue() : -1; 101 } 102 103 107 public static synchronized int getID(JTextComponent c) { 108 return getIDImpl(c); 109 } 110 111 117 public static synchronized Document getDocument(int docID) { 118 if (docID < 0 || docID >= docRefsCount) { 119 return null; 120 } 121 122 WeakReference wr = docRefs[docID]; 123 return (wr != null) ? (Document )wr.get() : null; 124 } 125 126 132 public static synchronized JTextComponent getComponent(int compID) { 133 if (compID < 0 || compID >= compRefsCount) { 134 return null; 135 } 136 137 WeakReference wr = compRefs[compID]; 138 return (wr != null) ? (JTextComponent )wr.get() : null; 139 } 140 141 145 public static synchronized int addDocument(Document doc) { 146 Integer docID = getIDInteger(doc); 147 if (docID != null) { return docID.intValue(); 149 } 150 151 if (docRefsCount >= docRefs.length) { 152 docRefs = realloc(docRefs); 153 } 154 155 docRefs[docRefsCount] = new WeakReference <Document >(doc); 156 doc.putProperty(DOCUMENT_ID_PROP, new Integer (docRefsCount)); 157 return docRefsCount++; 158 } 159 160 165 public static synchronized int addComponent(JTextComponent c) { 166 int compID = getIDImpl(c); 167 if (compID != -1) { 168 if (compRefs[compID] == null) { compRefs[compID] = new WeakReference <JTextComponent >(c); 170 } 171 return compID; } 173 174 if (compRefsCount >= compRefs.length) { 175 compRefs = realloc(compRefs); 176 } 177 178 compRefs[compRefsCount] = new WeakReference <JTextComponent >(c); 179 c.putClientProperty(COMPONENT_ID_PROP, new Integer (compRefsCount)); 180 return compRefsCount++; 181 } 182 183 189 public static synchronized int removeComponent(JTextComponent c) { 190 int compID = getIDImpl(c); 191 192 if (compID != -1) { 193 compRefs[compID] = null; 194 for (int i = compAct.size() - 1; i >= 0; i--) { 196 if (compAct.get(i) == compID) { 197 compAct.remove(i); 198 break; 199 } 200 } 201 } 202 203 return compID; 204 } 205 206 209 public static void activate(JTextComponent c) { 210 boolean activated = true; 211 synchronized (DocumentsRegistry.class) { 212 int compID = getIDImpl(c); 213 if (compID == -1) { return; 215 } 216 217 int actSize = compAct.size(); 218 int ind = 0; 219 while (ind < actSize) { 220 int id = compAct.get(ind); 221 if (id == compID) { if (ind == 0) { 223 break; 224 } 225 compAct.add(0, compAct.remove(ind)); 226 activated = true; 227 break; 228 } 229 230 ind++; 231 } 232 233 if (ind == actSize) { 234 compAct.add(0, compID); 235 activated = true; 236 } 237 238 if (doActivate(c.getDocument())) { 240 activated = true; 241 } 242 } 243 244 if (activated) { 245 PCS.firePropertyChange(PROP_ACTIVE_COMPONENT, null, c); 246 } 247 } 248 249 254 public static void activate(Document doc) { 255 boolean activated; 256 synchronized (DocumentsRegistry.class) { 257 activated = doActivate(doc); 258 } 259 260 if (activated) { 261 PCS.firePropertyChange(PROP_ACTIVE_DOCUMENT, null, doc); 262 } 263 } 264 265 public static synchronized Document getMostActiveDocument() { 266 return getValidDoc(0, true); 267 } 268 269 public static synchronized Document getLeastActiveDocument() { 270 int lastInd = docAct.size() - 1; 271 return getValidDoc(lastInd, false); 272 } 273 274 public static Document getLessActiveDocument(Document doc) { 275 return getLessActiveDocument(getID(doc)); 276 } 277 278 public static synchronized Document getLessActiveDocument(int docID) { 279 return getNextActiveDoc(docID, true); 280 } 281 282 public static Document getMoreActiveDocument(Document doc) { 283 return getMoreActiveDocument(getID(doc)); 284 } 285 286 public static synchronized Document getMoreActiveDocument(int docID) { 287 return getNextActiveDoc(docID, false); 288 } 289 290 295 public static synchronized Iterator getDocumentIterator() { 296 consolidate(); 297 298 ArrayList <Document > docList = new ArrayList <Document >(); 299 int actSize = docAct.size(); 300 for (int i = 0; i < actSize; i++) { 301 int ind = docAct.get(i); 302 WeakReference wr = docRefs[ind]; 303 if (wr != null) { 304 Object doc = wr.get(); 305 if (doc != null) { 306 docList.add((Document )doc); 307 } 308 } 309 } 310 311 return docList.iterator(); 312 } 313 314 public static synchronized JTextComponent getMostActiveComponent() { 315 return getValidComp(0, true); 316 } 317 318 public static synchronized JTextComponent getLeastActiveComponent() { 319 int lastInd = compAct.size() - 1; 320 return getValidComp(lastInd, false); 321 } 322 323 public static JTextComponent getLessActiveComponent(JTextComponent c) { 324 return getLessActiveComponent(getID(c)); 325 } 326 327 public static synchronized JTextComponent getLessActiveComponent(int compID) { 328 return getNextActiveComp(compID, true); 329 } 330 331 public static JTextComponent getMoreActiveComponent(JTextComponent c) { 332 return getMoreActiveComponent(getID(c)); 333 } 334 335 public static synchronized JTextComponent getMoreActiveComponent(int compID) { 336 return getNextActiveComp(compID, false); 337 } 338 339 342 public static synchronized Iterator getComponentIterator() { 343 consolidate(); 344 345 ArrayList <JTextComponent > compList = new ArrayList <JTextComponent >(); 346 int actSize = compAct.size(); 347 for (int i = 0; i < actSize; i++) { 348 int ind = compAct.get(i); 349 WeakReference wr = compRefs[ind]; 350 if (wr != null) { 351 Object comp = wr.get(); 352 if (comp != null) { 353 compList.add((JTextComponent ) comp); 354 } 355 } 356 } 357 358 return compList.iterator(); 359 } 360 361 private static WeakReference [] realloc(WeakReference [] refs) { 362 WeakReference [] tmp = new WeakReference [refs.length * 2 + 4]; 363 System.arraycopy(refs, 0, tmp, 0, refs.length); 364 return tmp; 365 } 366 367 private static void consolidate() { 368 while (++consolidateCounter >= 20) { consolidateCounter = 0; 370 371 for (int i = docAct.size() - 1; i >= 0; i--) { 373 int ind = docAct.get(i); 374 WeakReference wr = docRefs[ind]; 375 if (wr != null) { 376 if (wr.get() == null) { docAct.remove(i); 378 docRefs[ind] = null; 379 } 380 } 381 } 382 383 for (int i = compAct.size() - 1; i >= 0; i--) { 385 int ind = compAct.get(i); 386 WeakReference wr = compRefs[ind]; 387 if (wr != null) { 388 if (wr.get() == null) { compAct.remove(i); 390 compRefs[ind] = null; 391 } 392 } 393 } 394 } 395 } 396 397 private static int getIDImpl(JTextComponent c) { 398 Integer id = c == null ? null : (Integer )c.getClientProperty(COMPONENT_ID_PROP); 399 return id == null ? -1 : id.intValue(); 400 } 401 402 private static Integer getIDInteger(Document doc) { 403 if (doc == null) { 404 return null; 405 } 406 407 return (Integer )doc.getProperty(DOCUMENT_ID_PROP); 408 } 409 410 private static boolean doActivate(Document doc) { 411 Integer docIDInteger = getIDInteger(doc); 412 413 if (docIDInteger == null) { 414 return false; } 416 417 int docID = (docIDInteger != null) ? docIDInteger.intValue() : -1; 418 419 int size = docAct.size(); 420 for (int ind = 0; ind < size; ind++) { 421 int id = docAct.get(ind); 422 if (id == docID) { 423 if (ind == 0) { return false; 425 } 426 427 docAct.add(0, docAct.remove(ind)); 428 return true; 429 } 430 } 431 432 docAct.add(0, docIDInteger); 433 return true; 434 } 435 436 private static Document getValidDoc(int ind, boolean forward) { 437 consolidate(); 438 439 int actSize = docAct.size(); 440 while (ind >= 0 && ind < actSize) { 441 int docID = docAct.get(ind); 442 WeakReference wr = docRefs[docID]; 443 Document doc = (wr != null) ? (Document )wr.get() : null; 444 if (doc != null) { 445 return doc; 446 } 447 ind += forward ? +1 : -1; 448 } 449 return null; 450 } 451 452 private static Document getNextActiveDoc(int docID, boolean forward) { 453 consolidate(); 454 455 int actSize = docAct.size(); 456 int ind = forward ? 0 : (actSize - 1); 457 while (ind >= 0 && ind < actSize) { 458 if (docAct.get(ind) == docID) { 459 ind += forward ? +1 : -1; return getValidDoc(ind, forward); 461 } 462 ind += forward ? +1 : -1; 463 } 464 return null; 465 } 466 467 private static JTextComponent getValidComp(int ind, boolean forward) { 468 consolidate(); 469 470 int actSize = compAct.size(); 471 while (ind >= 0 && ind < actSize) { 472 int compID = compAct.get(ind); 473 WeakReference wr = compRefs[compID]; 474 JTextComponent c = (wr != null) ? (JTextComponent )wr.get() : null; 475 if (c != null) { 476 return c; 477 } 478 ind += forward ? +1 : -1; 479 } 480 return null; 481 } 482 483 private static JTextComponent getNextActiveComp(int compID, boolean forward) { 484 int actSize = compAct.size(); 485 int ind = forward ? 0 : (actSize - 1); 486 while (ind >= 0 && ind < actSize) { 487 if (compAct.get(ind) == compID) { 488 ind += forward ? +1 : -1; 489 return getValidComp(ind, forward); 490 } 491 ind += forward ? +1 : -1; 492 } 493 return null; 494 } 495 496 497 public static synchronized String registryToString() { 498 StringBuffer sb = new StringBuffer (); 499 sb.append("Document References:\n"); for (int i = 0; i < docRefsCount; i++) { 501 WeakReference wr = docRefs[i]; 502 sb.append("docRefs[" + i + "]=" + ((wr != null) ? wr.get() : "null") + "\n"); } 504 sb.append("Component References:\n"); for (int i = 0; i < compRefsCount; i++) { 506 WeakReference wr = (WeakReference )compRefs[i]; 507 sb.append("compRefs[" + i + "]=" + ((wr != null) ? wr.get() : "null") + "\n"); } 509 sb.append("\nActive Document Indexes:\n"); for (int i = 0; i < docAct.size(); i++) { 511 sb.append(docAct.get(i)); 512 if (i != docAct.size() - 1) { 513 sb.append(", "); } 515 } 516 sb.append("\nActive Component Indexes:\n"); for (int i = 0; i < compAct.size(); i++) { 518 sb.append(compAct.get(i)); 519 if (i != compAct.size() - 1) { 520 sb.append(", "); } 522 } 523 524 return sb.toString(); 525 } 526 527 private DocumentsRegistry() { 528 } 530 } 531 | Popular Tags |