1 19 20 package org.netbeans.editor; 21 22 import java.util.Map ; 23 import java.util.List ; 24 import java.util.Iterator ; 25 import java.util.HashMap ; 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.logging.Level ; 29 import java.util.logging.Logger ; 30 import org.openide.util.RequestProcessor; 31 32 79 80 public class Settings { 81 82 private static final Logger LOG = Logger.getLogger(Settings.class.getName()); 83 84 87 public static final int CORE_LEVEL = 0; 88 89 94 public static final int SYSTEM_LEVEL = 1; 95 96 102 public static final int EXTENSION_LEVEL = 2; 103 104 107 public static final int OPTION_LEVEL = 3; 108 109 115 public static final int USER_LEVEL = 4; 116 117 118 private static final ArrayList initializerLists = new ArrayList (); 119 private static long initializerListsVersion = 0; 120 private static List [] listsOfInitializers = null; 121 private static long listsOfInitializersVersion = -1; 122 123 124 private static InitializerSorter currentInitializerSorter; 125 126 127 private static final Filter [] NULL_FILTERS = new Filter[0]; 128 private static final String FILTERS_LOCK = new String ("Settings.FILTERS_LOCK"); private static volatile Filter [] filters = NULL_FILTERS; 130 131 132 private static final Map kit2Maps = new HashMap (); 133 134 135 private static final WeakEventListenerList listenerList = new WeakEventListenerList(); 136 137 141 private static final Map NULL_MAP = new HashMap (1); 142 143 private static volatile boolean firingEnabled = true; 144 145 148 private static final HashMap emptyMaps = new HashMap (); 149 150 private static final RequestProcessor PROCESSOR = new RequestProcessor("org.netbeans.editor.Settings.PROCESSOR"); private static final RequestProcessor.Task RESET_TASK = PROCESSOR.create(new Runnable () { 152 public void run() { 153 synchronized (Settings.class) { 154 kit2Maps.clear(); 155 } 156 fireSettingsChange(null, null, null, null); 157 } 158 }); 159 160 private Settings() { 161 } 163 164 165 public static void addInitializer(Initializer i) { 166 addInitializer(i, SYSTEM_LEVEL); 167 reset(); 168 } 169 170 186 public static void addInitializer(Initializer i, int level) { 187 synchronized (initializerLists) { 188 int size = initializerLists.size(); 189 for (int j = size; j <= level; j++) { 190 initializerLists.add(new ArrayList ()); 191 } 192 ((List )initializerLists.get(level)).add(i); 193 194 if (currentInitializerSorter != null) { 196 currentInitializerSorter.sort(initializerLists); 197 } 198 199 initializerListsVersion++; 200 } 201 } 202 203 207 public static void removeInitializer(String name) { 208 synchronized (initializerLists) { 209 Iterator itit = initializerLists.iterator(); 210 while (itit.hasNext()) { 211 Iterator it = ((List )itit.next()).iterator(); 212 while (it.hasNext()) { 213 if (name.equals(((Initializer)it.next()).getName())) { 214 it.remove(); 215 } 216 } 217 } 218 219 if (currentInitializerSorter != null) { 221 currentInitializerSorter.sort(initializerLists); 222 } 223 224 initializerListsVersion++; 225 } 226 } 227 228 229 public static InitializerSorter getInitializerSorter() { 230 synchronized (initializerLists) { 231 return currentInitializerSorter; 232 } 233 } 234 235 236 public static void setInitializerSorter(InitializerSorter initializerSorter) { 237 synchronized (initializerLists) { 238 currentInitializerSorter = initializerSorter; 239 } 240 } 241 242 private static List [] getListsOfInitializers() { 243 synchronized (initializerLists) { 244 if (listsOfInitializersVersion != initializerListsVersion) { 245 List [] lists = (List []) initializerLists.toArray(new List [initializerLists.size()]); 246 247 for (int i = 0; i < lists.length; i++) { 249 lists[i] = Collections.unmodifiableList(new ArrayList (lists[i])); 250 } 251 252 listsOfInitializers = lists; 253 listsOfInitializersVersion = initializerListsVersion; 254 } 255 256 return listsOfInitializers; 257 } 258 } 259 260 270 public static void addFilter(Filter f) { 271 synchronized (FILTERS_LOCK) { 272 if (filters.length == 0) { 273 filters = new Filter [] { f }; 274 } else { 275 Filter [] tmp = new Filter [filters.length + 1]; 276 System.arraycopy(filters, 0, tmp, 0, filters.length); 277 tmp[filters.length] = f; 278 279 filters = tmp; 280 } 281 } 282 } 283 284 public static void removeFilter(Filter f) { 285 synchronized (FILTERS_LOCK) { 286 if (filters.length == 0) { 287 return; 288 } else if (filters.length == 1 && filters[0] == f) { 289 filters = NULL_FILTERS; 290 } else { 291 int idx = -1; 292 for (int i = 0; i < filters.length; i++) { 293 if (filters[i] == f) { 294 idx = i; 295 break; 296 } 297 } 298 299 if (idx != -1) { 300 Filter [] tmp = new Filter [filters.length - 1]; 301 System.arraycopy(filters, 0, tmp, 0, idx); 302 if (idx < tmp.length) { 303 System.arraycopy(filters, idx + 1, tmp, idx, tmp.length - idx); 304 } 305 306 filters = tmp; 307 } 308 } 309 } 310 } 311 312 313 public static Object getValue(Class kitClass, String settingName) { 314 return getValue(kitClass, settingName, true); 315 } 316 317 325 public static synchronized Object getValue(Class kitClass, String settingName, 326 boolean evaluateEvaluators) { 327 Object value = null; 328 Class kc = kitClass; 329 while (true) { 330 Map map = getKitMap(kc, false); 331 if (map != null) { 332 value = map.get(settingName); 333 if (evaluateEvaluators && value instanceof Evaluator) { 334 value = ((Evaluator)value).getValue(kitClass, settingName); 335 } 336 if (value != null) { 337 break; 338 } 339 } 340 if (kc == null) { 341 break; 342 } 343 kc = kc.getSuperclass(); 344 } 345 346 Filter [] currentFilters = filters; 348 for (int i = 0; i < currentFilters.length; i++) { 349 value = currentFilters[i].filterValue(kitClass, settingName, value); 350 } 351 352 return value; 353 } 354 355 356 public static KitAndValue[] getValueHierarchy(Class kitClass, 357 String settingName) { 358 return getValueHierarchy(kitClass, settingName, true); 359 } 360 361 376 public static synchronized KitAndValue[] getValueHierarchy(Class kitClass, 377 String settingName, boolean evaluateEvaluators) { 378 ArrayList kavList = new ArrayList (); 379 Class kc = kitClass; 380 while (true) { 381 Map map = getKitMap(kc, false); 382 if (map != null) { 383 Object value = map.get(settingName); 384 if (evaluateEvaluators && value instanceof Evaluator) { 385 value = ((Evaluator)value).getValue(kitClass, settingName); 386 } 387 if (value != null) { 388 kavList.add(new KitAndValue(kc, value)); 389 } 390 } 391 if (kc == null) { 392 break; 393 } 394 kc = kc.getSuperclass(); 395 } 396 KitAndValue[] kavArray = (KitAndValue[])kavList.toArray( 397 new KitAndValue[kavList.size()]); 398 399 Filter [] currentFilters = filters; 401 for (int i = 0; i < currentFilters.length; i++) { 402 kavArray = currentFilters[i].filterValueHierarchy(kitClass, settingName, kavArray); 403 } 404 405 return kavArray; 406 } 407 408 418 public static void setValue(Class kitClass, String settingName, Object newValue) { 419 Object oldValue; 420 421 synchronized (Settings.class) { 422 Map map = getKitMap(kitClass, true); 423 oldValue = map.get(settingName); 424 if (oldValue == null && newValue == null 425 || (oldValue != null && oldValue.equals(newValue)) 426 ) { 427 return; } 429 if (newValue != null) { 430 map.put(settingName, newValue); 431 } else { 432 map.remove(settingName); 433 } 434 } 435 436 fireSettingsChange(kitClass, settingName, oldValue, newValue); 437 } 438 439 443 public static void touchValue(Class kitClass, String settingName) { 444 fireSettingsChange(kitClass, settingName, null, null); } 446 447 472 public static void propagateValue(Class kitClass, String settingName, Object newValue) { 473 synchronized (Settings.class) { 474 Map map = getKitMap(kitClass, true); 475 if (newValue != null) { 476 map.put(settingName, newValue); 477 } else { 478 map.remove(settingName); 479 } 480 Iterator it = kit2Maps.entrySet().iterator(); 482 while(it.hasNext()) { 483 Map.Entry me = (Map.Entry )it.next(); 484 Class kc = (Class )me.getKey(); 485 if (kitClass != kc && (kitClass == null || kitClass.isAssignableFrom(kc))) { 486 ((Map )me.getValue()).remove(settingName); 487 } 488 } 489 } 490 491 fireSettingsChange(null, settingName, null, null); 492 } 493 494 499 public static void update(Runnable r) { 500 boolean fire = false; 501 502 synchronized (Settings.class) { 503 boolean turnedOff = firingEnabled; 504 firingEnabled = false; 505 try { 506 r.run(); 507 } finally { 508 if (turnedOff) { 509 firingEnabled = true; 510 fire = true; 511 } 512 } 513 } 514 515 if (fire) { 516 fireSettingsChange(null, null, null, null); 517 } 518 } 519 520 527 public static void reset() { 528 RESET_TASK.schedule(1); 529 } 530 531 532 public static String initializersToString() { 533 StringBuffer sb = new StringBuffer (); 534 List [] lists = getListsOfInitializers(); 535 for (int i = 0; i < lists.length; i++) { 536 switch (i) { 538 case CORE_LEVEL: 539 sb.append("CORE_LEVEL"); break; 541 542 case SYSTEM_LEVEL: 543 sb.append("SYSTEM_LEVEL"); break; 545 546 case EXTENSION_LEVEL: 547 sb.append("EXTENSION_LEVEL"); break; 549 550 case OPTION_LEVEL: 551 sb.append("OPTION_LEVEL"); break; 553 554 case USER_LEVEL: 555 sb.append("USER_LEVEL"); break; 557 558 default: 559 sb.append("level " + i); break; 561 } 562 sb.append(":\n"); 564 sb.append(EditorDebug.debugList((List )lists[i])); 566 sb.append('\n'); } 568 569 return sb.toString(); 570 } 571 572 576 public static void addSettingsChangeListener(SettingsChangeListener l) { 577 listenerList.add(SettingsChangeListener.class, l); 578 } 579 580 581 public static void removeSettingsChangeListener(SettingsChangeListener l) { 582 listenerList.remove(SettingsChangeListener.class, l); 583 } 584 585 private static void fireSettingsChange(Class kitClass, String settingName, 586 Object oldValue, Object newValue) { 587 if (firingEnabled) { 588 SettingsChangeListener[] listeners = (SettingsChangeListener[]) 589 listenerList.getListeners(SettingsChangeListener.class); 590 SettingsChangeEvent evt = new SettingsChangeEvent(Settings.class, 591 kitClass, settingName, oldValue, newValue); 592 for (int i = 0; i < listeners.length; i++) { 593 listeners[i].settingsChange(evt); 594 } 595 } 596 } 597 598 599 private static Map getKitMap(Class kitClass, boolean forceCreation) { 600 Map kitMap = (Map )kit2Maps.get(kitClass); 601 if (kitMap == null) { 602 Map emptyMap = (Map ) emptyMaps.get(kitClass); 603 if (emptyMap != null) { 604 return emptyMap; 606 } 607 608 if (emptyMap == null) { 609 if (LOG.isLoggable(Level.FINE)) { 610 emptyMap = new LoggingMap(kitClass, Level.FINE); 611 } else { 612 emptyMap = new HashMap (); 613 } 614 emptyMaps.put(kitClass, emptyMap); 615 } 616 617 List [] lists = getListsOfInitializers(); 619 for (int i = 0; i < lists.length; i++) { 620 Iterator it = ((List ) lists[i]).iterator(); 621 while (it.hasNext()) { 622 Initializer initializer = (Initializer)it.next(); 623 624 try { 626 initializer.updateSettingsMap(kitClass, emptyMap); 627 } catch (Throwable t) { 628 LOG.log(Level.WARNING, null, t); 629 } 630 } 631 } 632 633 if (emptyMap.size() > 0) { 634 kitMap = emptyMap; 635 } 636 637 if (kitMap == null) { kitMap = NULL_MAP; } 640 kit2Maps.put(kitClass, kitMap); 641 emptyMaps.remove(kitClass); 642 } 643 644 if (kitMap == NULL_MAP) { 645 if (!forceCreation) { 646 return null; 647 } else { 648 if (LOG.isLoggable(Level.FINE)) { 649 kitMap = new LoggingMap(kitClass, Level.FINE); } else { 651 kitMap = new HashMap (); 652 } 653 kit2Maps.put(kitClass, kitMap); 654 } 655 } 656 657 return kitMap; 658 } 659 660 661 662 public static class KitAndValue { 663 664 public Class kitClass; 665 666 public Object value; 667 668 public KitAndValue(Class kitClass, Object value) { 669 this.kitClass = kitClass; 670 this.value = value; 671 } 672 673 } 674 675 676 682 public static interface Initializer { 683 684 688 public String getName(); 689 690 697 public void updateSettingsMap(Class kitClass, Map settingsMap); 698 699 } 700 701 702 public static abstract class AbstractInitializer implements Initializer { 703 704 private String name; 705 706 public AbstractInitializer(String name) { 707 this.name = name; 708 } 709 710 public String getName() { 711 return name; 712 } 713 714 public String toString() { 715 return getName(); 716 } 717 718 } 719 720 724 public static interface InitializerSorter { 725 726 public void sort(List initializersList); 727 728 } 729 730 731 public static abstract class FilterInitializerSorter { 732 733 private InitializerSorter delegate; 734 735 public FilterInitializerSorter(InitializerSorter delegate) { 736 this.delegate = delegate; 737 } 738 739 public void sort(List initializersList) { 740 if (delegate != null) { 741 delegate.sort(initializersList); 742 } 743 } 744 745 } 746 747 748 749 757 public static interface Evaluator { 758 759 771 public Object getValue(Class kitClass, String settingName); 772 773 } 774 775 776 784 public static interface Filter { 785 786 791 public Object filterValue(Class kitClass, String settingName, Object value); 792 793 799 public KitAndValue[] filterValueHierarchy(Class kitClass, String settingName, 800 KitAndValue[] kavArray); 801 802 } 803 804 private static final class LoggingMap extends HashMap { 806 807 private Class kitClass; 808 private Level logLevel; 809 810 public LoggingMap(Class kitClass, Level logLevel) { 811 super(); 812 this.kitClass = kitClass; 813 this.logLevel = logLevel; 814 } 815 816 @Override 817 public Object put(Object key,Object value) { 818 if (key != null && 819 (key.equals(SettingsNames.RENDERING_HINTS) || 820 key.equals("textAntialiasing") )) { 822 String msg = "Settings map: put('" + key + "' to '" + value + "') for kitClass=" + kitClass; LOG.log(logLevel, msg, new Throwable ()); 824 } 825 return super.put(key, value); 826 } 827 } } 829 | Popular Tags |