1 16 17 package de.schlichtherle.key; 18 19 import de.schlichtherle.util.ThreadLocalLong; 20 21 import java.lang.reflect.Array ; 22 import java.util.Arrays ; 23 24 50 public abstract class AbstractKeyProvider implements KeyProvider { 51 52 private Object key; 53 54 private final ThreadLocalLong invalidated = new ThreadLocalLong(); 55 56 77 protected KeyProvider addToKeyManager(String resourceID) 78 throws NullPointerException , IllegalStateException { 79 return KeyManager.mapKeyProvider(resourceID, this); 80 } 81 82 102 protected KeyProvider removeFromKeyManager(String resourceID) 103 throws NullPointerException , IllegalStateException { 104 return KeyManager.unmapKeyProvider(resourceID); 105 } 106 107 111 117 public synchronized Object getKey() { 118 return key; 119 } 120 121 126 public synchronized void setKey(Object key) { 127 this.key = key; 128 } 129 130 141 protected Object cloneKey() { 142 final Object key = getKey(); 143 if (key == null) 144 return null; 146 final Class c = key.getClass(); 153 if (c.isArray()) { 154 final int l = Array.getLength(key); 155 final Object p = Array.newInstance(c.getComponentType(), l); 156 System.arraycopy(key, 0, p, 0, l); 157 return p; 158 } else if (key instanceof Cloneable ) { 159 try { 160 return key.getClass().getMethod("clone", null).invoke(key, null); 161 } catch (RuntimeException failure) { 162 throw failure; } catch (Exception failure) { 164 } 166 } 167 168 return key; 170 } 171 172 180 protected void resetKey() { 181 final Object key = getKey(); 182 if (key == null) 183 return; 184 185 setKey(null); 186 187 synchronized (key) { 188 if (key instanceof byte[]) 189 Arrays.fill((byte[]) key, (byte) 0); 190 else if (key instanceof char[]) 191 Arrays.fill((char[]) key, (char) 0); 192 else if (key instanceof short[]) 193 Arrays.fill((short[]) key, (short) 0); 194 else if (key instanceof int[]) 195 Arrays.fill((int[]) key, (int) 0); 196 else if (key instanceof long[]) 197 Arrays.fill((long[]) key, (long) 0); 198 else if (key instanceof float[]) 199 Arrays.fill((float[]) key, (float) 0); 200 else if (key instanceof double[]) 201 Arrays.fill((double[]) key, (double) 0); 202 else if (key instanceof boolean[]) 203 Arrays.fill((boolean[]) key, false); 204 else if (key instanceof Object []) 205 Arrays.fill((Object []) key, null); 206 } 207 } 208 209 215 public void reset() { 216 } 219 220 224 237 public Object getCreateKey() throws UnknownKeyException { 238 return cloneKey(); 239 } 240 241 251 public final Object getOpenKey() throws UnknownKeyException { 252 try { 253 return getOpenKeyImpl(); 254 } finally { 255 enforceSuspensionPenalty(); 256 } 257 } 258 259 271 protected Object getOpenKeyImpl() throws UnknownKeyException { 272 return cloneKey(); 273 } 274 275 private void enforceSuspensionPenalty() { 276 final long last = invalidated.getValue(); 277 long delay; 278 InterruptedException interrupted = null; 279 while ((delay = System.currentTimeMillis() - last) < MIN_KEY_RETRY_DELAY) { 280 try { 281 Thread.sleep(MIN_KEY_RETRY_DELAY - delay); 282 } catch (InterruptedException ex) { 283 interrupted = ex; 284 } 285 } 286 if (interrupted != null) 287 Thread.currentThread().interrupt(); 288 } 289 290 299 public final void invalidOpenKey() { 300 invalidated.setValue(System.currentTimeMillis()); 301 invalidOpenKeyImpl(); 302 } 303 304 311 protected abstract void invalidOpenKeyImpl(); 312 } 313 | Popular Tags |