diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index 8b9510164d7..7c21e92731d 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -816,4 +816,25 @@ public class TypeUtil int result = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(value - 1)); return result > 0 ? result : Integer.MAX_VALUE; } + + /** + * Test is a method has been declared on the class of an instance + * @param object The object to check + * @param methodName The method name + * @param args The arguments to the method + * @return {@code true} iff {@link Class#getDeclaredMethod(String, Class[])} can be called on the + * {@link Class} of the object, without throwing {@link NoSuchMethodException}. + */ + public static boolean isDeclaredMethodOn(Object object, String methodName, Class... args) + { + try + { + object.getClass().getDeclaredMethod(methodName, args); + return true; + } + catch (NoSuchMethodException e) + { + return false; + } + } } diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index 83cf59cd1d8..ee5772c5d6c 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -77,6 +77,7 @@ import javax.net.ssl.X509ExtendedTrustManager; import javax.net.ssl.X509TrustManager; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -86,6 +87,7 @@ import org.eclipse.jetty.util.resource.ResourceFactory; import org.eclipse.jetty.util.resource.Resources; import org.eclipse.jetty.util.security.CertificateUtils; import org.eclipse.jetty.util.security.CertificateValidator; +import org.eclipse.jetty.util.security.Credential; import org.eclipse.jetty.util.security.Password; import org.eclipse.jetty.util.thread.AutoLock; import org.slf4j.Logger; @@ -157,9 +159,9 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du private Resource _trustStoreResource; private String _trustStoreProvider; private String _trustStoreType; - private Password _keyStorePassword; - private Password _keyManagerPassword; - private Password _trustStorePassword; + private Credential _keyStoreCredential; + private Credential _keyManagerCredential; + private Credential _trustStoreCredential; private String _sslProvider; private String _sslProtocol = "TLS"; private String _secureRandomAlgorithm; @@ -811,46 +813,42 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du public String getKeyStorePassword() { - return _keyStorePassword == null ? null : _keyStorePassword.toString(); + return _keyStoreCredential == null ? null : _keyStoreCredential.toString(); } /** - * @param password The password for the key store. If null is passed and - * a keystore is set, then - * the {@link #getPassword(String)} is used to - * obtain a password either from the {@value #PASSWORD_PROPERTY} - * system property. + * @param password The password for the key store. If null is passed then + * {@link #getCredential(String)} is used to obtain a password from + * the {@value #PASSWORD_PROPERTY} system property. */ public void setKeyStorePassword(String password) { - _keyStorePassword = password == null ? getPassword(PASSWORD_PROPERTY) : newPassword(password); + _keyStoreCredential = password == null ? getCredential(PASSWORD_PROPERTY) : newCredential(password); } public String getKeyManagerPassword() { - return _keyManagerPassword == null ? null : _keyManagerPassword.toString(); + return _keyManagerCredential == null ? null : _keyManagerCredential.toString(); } /** * @param password The password (if any) for the specific key within the key store. - * If null is passed and the {@value #KEYPASSWORD_PROPERTY} system property is set, - * then the {@link #getPassword(String)} is used to + * If null is passed then {@link #getCredential(String)} is used to * obtain a password from the {@value #KEYPASSWORD_PROPERTY} system property. */ public void setKeyManagerPassword(String password) { - _keyManagerPassword = password == null ? getPassword(KEYPASSWORD_PROPERTY) : newPassword(password); + _keyManagerCredential = password == null ? getCredential(KEYPASSWORD_PROPERTY) : newCredential(password); } /** * @param password The password for the truststore. If null is passed then - * the {@link #getPassword(String)} is used to - * obtain a password from the {@value #PASSWORD_PROPERTY} + * {@link #getCredential(String)} is used to obtain a password from the {@value #PASSWORD_PROPERTY} * system property. */ public void setTrustStorePassword(String password) { - _trustStorePassword = password == null ? getPassword(PASSWORD_PROPERTY) : newPassword(password); + _trustStoreCredential = password == null ? getCredential(PASSWORD_PROPERTY) : newCredential(password); } /** @@ -1133,7 +1131,7 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du */ protected KeyStore loadKeyStore(Resource resource) throws Exception { - String storePassword = Objects.toString(_keyStorePassword, null); + String storePassword = Objects.toString(_keyStoreCredential, null); return CertificateUtils.getKeyStore(resource, getKeyStoreType(), getKeyStoreProvider(), storePassword); } @@ -1148,12 +1146,12 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du { String type = Objects.toString(getTrustStoreType(), getKeyStoreType()); String provider = Objects.toString(getTrustStoreProvider(), getKeyStoreProvider()); - Password passwd = _trustStorePassword; + Credential passwd = _trustStoreCredential; if (resource == null || resource.equals(_keyStoreResource)) { resource = _keyStoreResource; if (passwd == null) - passwd = _keyStorePassword; + passwd = _keyStoreCredential; } return CertificateUtils.getKeyStore(resource, type, provider, Objects.toString(passwd, null)); } @@ -1180,7 +1178,7 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du if (keyStore != null) { KeyManagerFactory keyManagerFactory = getKeyManagerFactoryInstance(); - keyManagerFactory.init(keyStore, _keyManagerPassword == null ? (_keyStorePassword == null ? null : _keyStorePassword.toString().toCharArray()) : _keyManagerPassword.toString().toCharArray()); + keyManagerFactory.init(keyStore, _keyManagerCredential == null ? (_keyStoreCredential == null ? null : _keyStoreCredential.toString().toCharArray()) : _keyManagerCredential.toString().toCharArray()); managers = keyManagerFactory.getKeyManagers(); if (managers != null) @@ -1615,7 +1613,9 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du * * @param realm the realm * @return the Password object + * @deprecated use {#link getCredential} instead. */ + @Deprecated(since = "12.0.13", forRemoval = true) protected Password getPassword(String realm) { String password = System.getProperty(realm); @@ -1627,12 +1627,43 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du * * @param password the password string * @return the new Password object + * @deprecated use {#link newCredential} instead. */ + @Deprecated(since = "12.0.13", forRemoval = true) public Password newPassword(String password) { return new Password(password); } + /** + * Returns the credential object for the given realm. + * + * @param realm the realm + * @return the Credential object + */ + protected Credential getCredential(String realm) + { + if (TypeUtil.isDeclaredMethodOn(this, "getPassword", String.class)) + return getPassword(realm); + + String password = System.getProperty(realm); + return password == null ? null : newCredential(password); + } + + /** + * Creates a new Credential object. + * + * @param password the password string + * @return the new Credential object + */ + public Credential newCredential(String password) + { + if (TypeUtil.isDeclaredMethodOn(this, "newPassword", String.class)) + return newPassword(password); + + return Credential.getCredential(password); + } + public SSLServerSocket newSslServerSocket(String host, int port, int backlog) throws IOException { checkIsStarted(); diff --git a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java index 8432153365c..c57c079c937 100644 --- a/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java +++ b/jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java @@ -267,4 +267,34 @@ public class TypeUtilTest assertThat(TypeUtil.ceilToNextPowerOfTwo(5), is(8)); assertThat(TypeUtil.ceilToNextPowerOfTwo(Integer.MAX_VALUE - 1), is(Integer.MAX_VALUE)); } + + public static class Base + { + protected String methodA(String arg) + { + return "a" + arg.length(); + } + + protected String methodB(String arg) + { + return "b" + arg.length(); + } + } + + public static class Example extends Base + { + @Override + protected String methodB(String arg) + { + return "B" + arg; + } + } + + @Test + public void testIsMethodDeclaredOn() + { + Example example = new Example(); + assertFalse(TypeUtil.isDeclaredMethodOn(example, "methodA", String.class)); + assertTrue(TypeUtil.isDeclaredMethodOn(example, "methodB", String.class)); + } }