UnaryOperator<Key> op = checkForCloneMethod(type, type); if (op != null) return op; op = checkForCopyCtor(type, type); if (op != null) return op; if (PrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, DSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, DSAPrivateKey.class); if (op != null) return op; return RawDSAPrivateKey::new; } else if (ECPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, ECPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, ECPrivateKey.class); if (op != null) return op; return RawECPrivateKey::new; } else if (RSAMultiPrimePrivateCrtKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; return RawRSAMultiPrimePrivateCrtKey::new; } else if (RSAPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAPrivateKey.class); if (op != null) return op;
/** * Attempt to create a safe clone of the given key object. * This algorithm first checks to see if the key's class implements {@link Destroyable}; if not, it is returned as-is. * Next it checks to see if the key has been destroyed; if so, it is returned as-is. * Next it determines if the key actually implements the {@link Destroyable} interface; if not, it is returned as-is. * Then it determines if there is a public {@code clone} method that returns a compatible type; if so, that method is used. * Then it determines if the key implements a known key interface; if so, a raw implementation of that interface is produced. * Last it checks to see if the key is some other unknown {@link SecretKey} type; if so, it captures its value using a {@link SecretKeySpec}. * If none of these checks succeed, an exception is thrown. * * @param expectType the expected result type (must not be {@code null}) * @param key the key object * @return the cloned key, or the original if the key type is not destroyable */ public static <T extends Key> T cloneKey(Class<T> expectType, T key) { Assert.checkNotNullParam("expectType", expectType); if (key instanceof Destroyable) { // medium path if (((Destroyable) key).isDestroyed()) { return expectType.cast(key); } else { return expectType.cast(CLONER_CREATOR.get(key.getClass()).apply(key)); } } else { // fast path return expectType.cast(key); } }
private UnaryOperator<Key> checkForCopyCtor(final Class<?> declType, final Class<?> paramType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findConstructor(declType, MethodType.methodType(void.class, paramType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
UnaryOperator<Key> op = checkForCloneMethod(type, type); if (op != null) return op; op = checkForCopyCtor(type, type); if (op != null) return op; if (PrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, DSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, DSAPrivateKey.class); if (op != null) return op; return RawDSAPrivateKey::new; } else if (ECPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, ECPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, ECPrivateKey.class); if (op != null) return op; return RawECPrivateKey::new; } else if (RSAMultiPrimePrivateCrtKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; return RawRSAMultiPrimePrivateCrtKey::new; } else if (RSAPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAPrivateKey.class); if (op != null) return op;
UnaryOperator<Key> op = checkForCloneMethod(type, type); if (op != null) return op; op = checkForCopyCtor(type, type); if (op != null) return op; if (PrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, DSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, DSAPrivateKey.class); if (op != null) return op; return RawDSAPrivateKey::new; } else if (ECPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, ECPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, ECPrivateKey.class); if (op != null) return op; return RawECPrivateKey::new; } else if (RSAMultiPrimePrivateCrtKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; return RawRSAMultiPrimePrivateCrtKey::new; } else if (RSAPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAPrivateKey.class); if (op != null) return op;
UnaryOperator<Key> op = checkForCloneMethod(type, type); if (op != null) return op; op = checkForCopyCtor(type, type); if (op != null) return op; if (PrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, DSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, DSAPrivateKey.class); if (op != null) return op; return RawDSAPrivateKey::new; } else if (ECPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, ECPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, ECPrivateKey.class); if (op != null) return op; return RawECPrivateKey::new; } else if (RSAMultiPrimePrivateCrtKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAMultiPrimePrivateCrtKey.class); if (op != null) return op; return RawRSAMultiPrimePrivateCrtKey::new; } else if (RSAPrivateKey.class.isAssignableFrom(type)) { op = checkForCloneMethod(type, RSAPrivateKey.class); if (op != null) return op; op = checkForCopyCtor(type, RSAPrivateKey.class); if (op != null) return op;
/** * Attempt to create a safe clone of the given key object. * This algorithm first checks to see if the key's class implements {@link Destroyable}; if not, it is returned as-is. * Next it checks to see if the key has been destroyed; if so, it is returned as-is. * Next it determines if the key actually implements the {@link Destroyable} interface; if not, it is returned as-is. * Then it determines if there is a public {@code clone} method that returns a compatible type; if so, that method is used. * Then it determines if the key implements a known key interface; if so, a raw implementation of that interface is produced. * Last it checks to see if the key is some other unknown {@link SecretKey} type; if so, it captures its value using a {@link SecretKeySpec}. * If none of these checks succeed, an exception is thrown. * * @param expectType the expected result type (must not be {@code null}) * @param key the key object * @return the cloned key, or the original if the key type is not destroyable */ public static <T extends Key> T cloneKey(Class<T> expectType, T key) { Assert.checkNotNullParam("expectType", expectType); if (key instanceof Destroyable) { // medium path if (((Destroyable) key).isDestroyed()) { return expectType.cast(key); } else { return expectType.cast(CLONER_CREATOR.get(key.getClass()).apply(key)); } } else { // fast path return expectType.cast(key); } }
/** * Attempt to create a safe clone of the given key object. * This algorithm first checks to see if the key's class implements {@link Destroyable}; if not, it is returned as-is. * Next it checks to see if the key has been destroyed; if so, it is returned as-is. * Next it determines if the key actually implements the {@link Destroyable} interface; if not, it is returned as-is. * Then it determines if there is a public {@code clone} method that returns a compatible type; if so, that method is used. * Then it determines if the key implements a known key interface; if so, a raw implementation of that interface is produced. * Last it checks to see if the key is some other unknown {@link SecretKey} type; if so, it captures its value using a {@link SecretKeySpec}. * If none of these checks succeed, an exception is thrown. * * @param expectType the expected result type (must not be {@code null}) * @param key the key object * @return the cloned key, or the original if the key type is not destroyable */ public static <T extends Key> T cloneKey(Class<T> expectType, T key) { Assert.checkNotNullParam("expectType", expectType); if (key instanceof Destroyable) { // medium path if (((Destroyable) key).isDestroyed()) { return expectType.cast(key); } else { return expectType.cast(CLONER_CREATOR.get(key.getClass()).apply(key)); } } else { // fast path return expectType.cast(key); } }
/** * Attempt to create a safe clone of the given key object. * This algorithm first checks to see if the key's class implements {@link Destroyable}; if not, it is returned as-is. * Next it checks to see if the key has been destroyed; if so, it is returned as-is. * Next it determines if the key actually implements the {@link Destroyable} interface; if not, it is returned as-is. * Then it determines if there is a public {@code clone} method that returns a compatible type; if so, that method is used. * Then it determines if the key implements a known key interface; if so, a raw implementation of that interface is produced. * Last it checks to see if the key is some other unknown {@link SecretKey} type; if so, it captures its value using a {@link SecretKeySpec}. * If none of these checks succeed, an exception is thrown. * * @param expectType the expected result type (must not be {@code null}) * @param key the key object * @return the cloned key, or the original if the key type is not destroyable */ public static <T extends Key> T cloneKey(Class<T> expectType, T key) { Assert.checkNotNullParam("expectType", expectType); if (key instanceof Destroyable) { // medium path if (((Destroyable) key).isDestroyed()) { return expectType.cast(key); } else { return expectType.cast(CLONER_CREATOR.get(key.getClass()).apply(key)); } } else { // fast path return expectType.cast(key); } }
private UnaryOperator<Key> checkForCopyCtor(final Class<?> declType, final Class<?> paramType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findConstructor(declType, MethodType.methodType(void.class, paramType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCloneMethod(final Class<?> declType, final Class<?> returnType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findVirtual(declType, "clone", MethodType.methodType(returnType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCopyCtor(final Class<?> declType, final Class<?> paramType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findConstructor(declType, MethodType.methodType(void.class, paramType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCopyCtor(final Class<?> declType, final Class<?> paramType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findConstructor(declType, MethodType.methodType(void.class, paramType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCloneMethod(final Class<?> declType, final Class<?> returnType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findVirtual(declType, "clone", MethodType.methodType(returnType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCloneMethod(final Class<?> declType, final Class<?> returnType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findVirtual(declType, "clone", MethodType.methodType(returnType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCloneMethod(final Class<?> declType, final Class<?> returnType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findVirtual(declType, "clone", MethodType.methodType(returnType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }