1 16 17 package de.schlichtherle.key; 18 19 import java.awt.GraphicsEnvironment ; 20 import java.lang.reflect.UndeclaredThrowableException ; 21 import java.util.*; 22 23 60 public abstract class KeyManager { 61 62 private static volatile KeyManager keyManager; 63 64 67 private static final Map providers = new HashMap(); 68 69 private final Map providerTypes = new HashMap(); 70 71 75 109 public static synchronized KeyManager getInstance() { 110 if (keyManager != null) 111 return keyManager; 112 113 final String cn = System.getProperty( 114 "de.schlichtherle.key.KeyManager", 115 getDefaultKeyManagerClassName()); 116 try { 117 final Class c = Thread.currentThread() 118 .getContextClassLoader().loadClass(cn); 119 keyManager = (KeyManager) c.newInstance(); 120 } catch (ClassNotFoundException failure) { 121 throw new UndeclaredThrowableException (failure); 122 } catch (InstantiationException failure) { 123 throw new UndeclaredThrowableException (failure); 124 } catch (IllegalAccessException failure) { 125 throw new UndeclaredThrowableException (failure); 126 } 127 128 return keyManager; 129 } 130 131 private static String getDefaultKeyManagerClassName() { 132 if (GraphicsEnvironment.isHeadless()) { 133 try { 134 Class.forName("java.io.Console"); 135 return "de.schlichtherle.key.passwd.console.PromptingKeyManager"; 136 } catch (ClassNotFoundException noJSE6ConsoleAvailable) { 137 } 139 } 140 141 return "de.schlichtherle.key.passwd.swing.PromptingKeyManager"; 142 } 143 144 151 public static void setInstance(final KeyManager keyManager) { 152 KeyManager.keyManager = keyManager; 153 } 154 155 163 static final synchronized KeyProvider mapKeyProvider( 164 String resourceID, 165 KeyProvider provider) 166 throws NullPointerException { 167 if (resourceID == null || provider == null) 168 throw new NullPointerException (); 169 return (KeyProvider) providers.put(resourceID, provider); 170 } 171 172 180 static synchronized final KeyProvider unmapKeyProvider(String resourceID) 181 throws NullPointerException { 182 if (resourceID == null) 183 throw new NullPointerException (); 184 return (KeyProvider) providers.remove(resourceID); 185 } 186 187 198 public static synchronized boolean resetKeyProvider(final String resourceID) { 199 final KeyProvider provider = (KeyProvider) providers.get(resourceID); 200 if (provider instanceof AbstractKeyProvider) { 201 final AbstractKeyProvider skp = (AbstractKeyProvider) provider; 202 skp.reset(); 203 return true; 204 } 205 return false; 206 } 207 208 219 public static synchronized boolean resetAndRemoveKeyProvider(final String resourceID) { 220 final KeyProvider provider = (KeyProvider) providers.get(resourceID); 221 if (provider instanceof AbstractKeyProvider) { 222 final AbstractKeyProvider skp = (AbstractKeyProvider) provider; 223 skp.reset(); 224 final KeyProvider result = skp.removeFromKeyManager(resourceID); 225 assert provider == result; 226 return true; 227 } else if (provider != null) { 228 final KeyProvider previous = unmapKeyProvider(resourceID); 229 assert provider == previous; 230 return true; 231 } 232 return false; 233 } 234 235 241 public static void resetKeyProviders() { 242 forEachKeyProvider(new KeyProviderCommand() { 243 public void run(String resourceID, KeyProvider provider) { 244 if (provider instanceof AbstractKeyProvider) { 245 ((AbstractKeyProvider) provider).reset(); 246 } 247 } 248 }); 249 } 250 251 254 public static final void resetAndClearKeyProviders() { 255 resetAndRemoveKeyProviders(); 256 } 257 258 274 public static synchronized void resetAndRemoveKeyProviders() { 275 class ResetAndRemoveKeyProvider implements KeyProviderCommand { 276 IllegalStateException ise = null; 277 278 public void run(String resourceID, KeyProvider provider) { 279 if (provider instanceof AbstractKeyProvider) { 280 final AbstractKeyProvider skp = (AbstractKeyProvider) provider; 281 skp.reset(); 282 try { 283 skp.removeFromKeyManager(resourceID); } catch (IllegalStateException exc) { 285 ise = exc; } 287 } else { 288 final KeyProvider previous = unmapKeyProvider(resourceID); 289 assert provider == previous; 290 } 291 } 292 } 293 294 final ResetAndRemoveKeyProvider cmd = new ResetAndRemoveKeyProvider(); 295 forEachKeyProvider(cmd); 296 if (cmd.ise != null) 297 throw cmd.ise; 298 } 299 300 305 protected static synchronized void forEachKeyProvider( 306 final KeyProviderCommand command) { 307 final Set entrySet = providers.entrySet(); 311 final int n = entrySet.size(); 312 final Map.Entry[] entries 313 = (Map.Entry[]) entrySet.toArray(new Map.Entry[n]); 314 for (int i = 0; i < n; i++) { 315 final Map.Entry entry = entries[i]; 316 final String resourceID = (String ) entry.getKey(); 317 final KeyProvider provider = (KeyProvider) entry.getValue(); 318 command.run(resourceID, provider); 319 } 320 } 321 322 326 protected interface KeyProviderCommand { 327 void run(String resourceID, KeyProvider provider); 328 } 329 330 352 public static synchronized boolean moveKeyProvider( 353 final String oldResourceID, 354 final String newResourceID) 355 throws NullPointerException , IllegalStateException { 356 if (oldResourceID == null || newResourceID == null) 357 throw new NullPointerException (); 358 359 final KeyProvider provider = (KeyProvider) providers.get(oldResourceID); 360 if (provider == null) 361 return false; 362 363 if (provider instanceof AbstractKeyProvider) { 364 final AbstractKeyProvider skp = (AbstractKeyProvider) provider; 365 skp.removeFromKeyManager(oldResourceID); 367 try { 368 skp.addToKeyManager(newResourceID); 369 } catch (RuntimeException failure) { 370 skp.addToKeyManager(oldResourceID); 371 throw failure; 372 } 373 } else { 374 unmapKeyProvider(oldResourceID); 375 mapKeyProvider(newResourceID, provider); 376 } 377 378 return true; 379 } 380 381 385 390 public KeyManager() { 391 } 392 393 420 protected final synchronized void mapKeyProviderType( 421 final Class forKeyProviderType, 422 final Class useKeyProviderType) { 423 if (!KeyProvider.class.isAssignableFrom(forKeyProviderType) 424 || !forKeyProviderType.isAssignableFrom(useKeyProviderType) 425 || forKeyProviderType == useKeyProviderType) 426 throw new IllegalArgumentException ( 427 useKeyProviderType.getName() 428 + " must be a subclass or implementation of " 429 + forKeyProviderType.getName() + "!"); 430 try { 431 useKeyProviderType.getConstructor(null); 432 } catch (NoSuchMethodException noPublicNullaryConstructor) { 433 final IllegalArgumentException iae = new IllegalArgumentException ( 434 useKeyProviderType.getName() + " (no public nullary constructor)"); 435 iae.initCause(noPublicNullaryConstructor); 436 throw iae; 437 } 438 providerTypes.put(forKeyProviderType, useKeyProviderType); 439 } 440 441 454 abstract public KeyProvider getKeyProvider(String resourceID) 455 throws NullPointerException ; 456 457 516 public synchronized KeyProvider getKeyProvider( 517 final String resourceID, 518 Class keyProviderType) 519 throws NullPointerException , ClassCastException , IllegalArgumentException { 520 if (resourceID == null) 521 throw new NullPointerException (); 522 523 synchronized (KeyManager.class) { 524 KeyProvider provider = (KeyProvider) providers.get(resourceID); 525 if (provider == null) { 526 final Object value = providerTypes.get(keyProviderType); 527 if (value != null) 528 keyProviderType = (Class ) value; 529 try { 530 provider = (KeyProvider) keyProviderType.newInstance(); 531 } catch (InstantiationException failure) { 532 IllegalArgumentException iae = new IllegalArgumentException ( 533 keyProviderType.getName()); 534 iae.initCause(failure); 535 throw iae; 536 } catch (IllegalAccessException failure) { 537 IllegalArgumentException iae = new IllegalArgumentException ( 538 keyProviderType.getName()); 539 iae.initCause(failure); 540 throw iae; 541 } 542 setKeyProvider(resourceID, provider); 543 } 544 545 return provider; 546 } 547 } 548 549 575 public void setKeyProvider( 576 final String resourceID, 577 final KeyProvider provider) 578 throws NullPointerException , IllegalStateException { 579 581 582 if (provider instanceof AbstractKeyProvider) { 583 ((AbstractKeyProvider) provider).addToKeyManager(resourceID); 584 } else { 585 mapKeyProvider(resourceID, provider); 586 } 587 } 588 } 589 | Popular Tags |