GUACAMOLE-1001: Merge changes adding missing attributes to RADIUS requests.
diff --git a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java
index 777c96b..abcb486 100644
--- a/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java
+++ b/extensions/guacamole-auth-duo/src/main/java/org/apache/guacamole/auth/duo/UserVerificationService.java
@@ -22,16 +22,16 @@
import com.google.inject.Inject;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
-import org.apache.guacamole.GuacamoleClientException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.duo.api.DuoService;
import org.apache.guacamole.auth.duo.conf.ConfigurationService;
import org.apache.guacamole.auth.duo.form.DuoSignedResponseField;
import org.apache.guacamole.form.Field;
+import org.apache.guacamole.language.TranslatableGuacamoleClientException;
+import org.apache.guacamole.language.TranslatableGuacamoleInsufficientCredentialsException;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
-import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
/**
* Service for verifying the identity of a user against Duo.
@@ -95,14 +95,18 @@
Collections.singletonList(signedResponseField));
// Request additional credentials
- throw new GuacamoleInsufficientCredentialsException(
- "LOGIN.INFO_DUO_AUTH_REQUIRED", expectedCredentials);
+ throw new TranslatableGuacamoleInsufficientCredentialsException(
+ "Verification using Duo is required before authentication "
+ + "can continue.", "LOGIN.INFO_DUO_AUTH_REQUIRED",
+ expectedCredentials);
}
// If signed response does not verify this user's identity, abort auth
if (!duoService.isValidSignedResponse(authenticatedUser, signedResponse))
- throw new GuacamoleClientException("LOGIN.INFO_DUO_VALIDATION_CODE_INCORRECT");
+ throw new TranslatableGuacamoleClientException("Provided Duo "
+ + "validation code is incorrect.",
+ "LOGIN.INFO_DUO_VALIDATION_CODE_INCORRECT");
}
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
index ff605b9..646bf20 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java
@@ -21,7 +21,6 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
-import org.apache.guacamole.GuacamoleClientException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.auth.jdbc.security.PasswordPolicyService;
import org.apache.guacamole.auth.jdbc.sharing.user.SharedAuthenticatedUser;
@@ -29,6 +28,7 @@
import org.apache.guacamole.auth.jdbc.user.ModeledUser;
import org.apache.guacamole.auth.jdbc.user.ModeledUserContext;
import org.apache.guacamole.auth.jdbc.user.UserService;
+import org.apache.guacamole.language.TranslatableGuacamoleClientException;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.Credentials;
@@ -104,11 +104,15 @@
// Verify user account is still valid as of today
if (!user.isAccountValid())
- throw new GuacamoleClientException("LOGIN.ERROR_NOT_VALID");
+ throw new TranslatableGuacamoleClientException("User "
+ + "account is no longer valid.",
+ "LOGIN.ERROR_NOT_VALID");
// Verify user account is allowed to be used at the current time
if (!user.isAccountAccessible())
- throw new GuacamoleClientException("LOGIN.ERROR_NOT_ACCESSIBLE");
+ throw new TranslatableGuacamoleClientException("User "
+ + "account may not be used at this time.",
+ "LOGIN.ERROR_NOT_ACCESSIBLE");
}
diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
index 0cfe900..a68f082 100644
--- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
+++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java
@@ -46,12 +46,13 @@
import org.apache.guacamole.auth.jdbc.security.PasswordPolicyService;
import org.apache.guacamole.form.Field;
import org.apache.guacamole.form.PasswordField;
+import org.apache.guacamole.language.TranslatableGuacamoleClientException;
+import org.apache.guacamole.language.TranslatableGuacamoleInsufficientCredentialsException;
import org.apache.guacamole.net.auth.ActivityRecord;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.AuthenticationProvider;
import org.apache.guacamole.net.auth.User;
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
-import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
import org.apache.guacamole.net.auth.permission.ObjectPermission;
import org.apache.guacamole.net.auth.permission.ObjectPermissionSet;
import org.apache.guacamole.net.auth.permission.SystemPermission;
@@ -494,20 +495,25 @@
// Require new password if account is expired
if (newPassword == null || confirmNewPassword == null) {
logger.info("The password of user \"{}\" has expired and must be reset.", username);
- throw new GuacamoleInsufficientCredentialsException("LOGIN.INFO_PASSWORD_EXPIRED", EXPIRED_PASSWORD);
+ throw new TranslatableGuacamoleInsufficientCredentialsException("Password has expired",
+ "LOGIN.INFO_PASSWORD_EXPIRED", EXPIRED_PASSWORD);
}
// New password must be different from old password
if (newPassword.equals(credentials.getPassword()))
- throw new GuacamoleClientException("LOGIN.ERROR_PASSWORD_SAME");
+ throw new TranslatableGuacamoleClientException("New passwords may "
+ + "not be identical to the current password if password "
+ + "reset is required.", "LOGIN.ERROR_PASSWORD_SAME");
// New password must not be blank
if (newPassword.isEmpty())
- throw new GuacamoleClientException("LOGIN.ERROR_PASSWORD_BLANK");
+ throw new TranslatableGuacamoleClientException("Passwords may not "
+ + "be blank.", "LOGIN.ERROR_PASSWORD_BLANK");
// Confirm that the password was entered correctly twice
if (!newPassword.equals(confirmNewPassword))
- throw new GuacamoleClientException("LOGIN.ERROR_PASSWORD_MISMATCH");
+ throw new TranslatableGuacamoleClientException("New password does "
+ + "not match.", "LOGIN.ERROR_PASSWORD_MISMATCH");
// Verify new password does not violate defined policies
passwordPolicyService.verifyPassword(username, newPassword);
diff --git a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectException.java b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectException.java
deleted file mode 100644
index 6e4d5b9..0000000
--- a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/QuickConnectException.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.guacamole.auth.quickconnect;
-
-import org.apache.guacamole.GuacamoleClientException;
-import org.apache.guacamole.language.Translatable;
-import org.apache.guacamole.language.TranslatableMessage;
-
-/**
- * An exception that is thrown by this extension when an error occurs
- * attempting to create and establish a connection with a user-provided
- * URI.
- */
-public class QuickConnectException extends GuacamoleClientException
- implements Translatable {
-
- /**
- * A message that can be passed through the translation service
- * to provide information about the error that occurred.
- */
- private final TranslatableMessage translatableMessage;
-
- /**
- * Create a QuickConnectException with the given message and translationKey.
- * The message will not be passed through the translation system; the
- * translationKey will be passed through the translation system. Both should
- * describe the error.
- *
- * @param message
- * A string describing the error that occurred when trying to create
- * or establish the connection. This will not be passed through the
- * translation system.
- *
- * @param translationKey
- * A key known to the translation system describing the error that
- * occurred when trying to create or establish the connection.
- * This will be passed through the translation system to provide
- * a localized version of the message.
- */
- public QuickConnectException(String message, String translationKey) {
- super(message);
- this.translatableMessage = new TranslatableMessage(translationKey);
- }
-
- /**
- * Create a new QuickConnectException given the human-readable message,
- * which will not be passed through the translation system, and the
- * translatableMessage, which will be passed through the translation system.
- * Both parameters should describe the error preventing the connection
- * from being created or established.
- *
- * @param message
- * The human-readable message describing the error, which will not
- * be passed through the translation system.
- *
- * @param translatableMessage
- * The human-readable message describing the error, which will be
- * passed through the translation system.
- */
- public QuickConnectException(String message, TranslatableMessage translatableMessage) {
- super(message);
- this.translatableMessage = translatableMessage;
- }
-
- @Override
- public TranslatableMessage getTranslatableMessage() {
- return translatableMessage;
- }
-
-}
diff --git a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java
index 3e2e5e5..e5fc8ec 100644
--- a/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java
+++ b/extensions/guacamole-auth-quickconnect/src/main/java/org/apache/guacamole/auth/quickconnect/utility/QCParser.java
@@ -32,7 +32,7 @@
import java.util.regex.Pattern;
import org.apache.guacamole.GuacamoleServerException;
import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.auth.quickconnect.QuickConnectException;
+import org.apache.guacamole.language.TranslatableGuacamoleClientException;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
/**
@@ -78,11 +78,11 @@
try {
qcUri = new URI(uri);
if (!qcUri.isAbsolute())
- throw new QuickConnectException("URI must be absolute.",
+ throw new TranslatableGuacamoleClientException("URI must be absolute.",
"QUICKCONNECT.ERROR_NOT_ABSOLUTE_URI");
}
catch (URISyntaxException e) {
- throw new QuickConnectException("Invalid URI Syntax",
+ throw new TranslatableGuacamoleClientException("Invalid URI Syntax",
"QUICKCONNECT.ERROR_INVALID_URI");
}
@@ -100,7 +100,7 @@
if (protocol != null && !protocol.isEmpty())
qcConfig.setProtocol(protocol);
else
- throw new QuickConnectException("No protocol specified.",
+ throw new TranslatableGuacamoleClientException("No protocol specified.",
"QUICKCONNECT.ERROR_NO_PROTOCOL");
// Check for provided port number
@@ -111,7 +111,7 @@
if (host != null && !host.isEmpty())
qcConfig.setParameter("hostname", host);
else
- throw new QuickConnectException("No host specified.",
+ throw new TranslatableGuacamoleClientException("No host specified.",
"QUICKCONNECT.ERROR_NO_HOST");
// Look for extra query parameters and parse them out.
diff --git a/extensions/guacamole-auth-totp/src/main/java/org/apache/guacamole/auth/totp/user/UserVerificationService.java b/extensions/guacamole-auth-totp/src/main/java/org/apache/guacamole/auth/totp/user/UserVerificationService.java
index 2414ee8..a73d08f 100644
--- a/extensions/guacamole-auth-totp/src/main/java/org/apache/guacamole/auth/totp/user/UserVerificationService.java
+++ b/extensions/guacamole-auth-totp/src/main/java/org/apache/guacamole/auth/totp/user/UserVerificationService.java
@@ -27,19 +27,19 @@
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
-import org.apache.guacamole.GuacamoleClientException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleSecurityException;
import org.apache.guacamole.GuacamoleUnsupportedException;
import org.apache.guacamole.auth.totp.conf.ConfigurationService;
import org.apache.guacamole.auth.totp.form.AuthenticationCodeField;
import org.apache.guacamole.form.Field;
+import org.apache.guacamole.language.TranslatableGuacamoleClientException;
+import org.apache.guacamole.language.TranslatableGuacamoleInsufficientCredentialsException;
import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;
import org.apache.guacamole.net.auth.User;
import org.apache.guacamole.net.auth.UserContext;
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
-import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
import org.apache.guacamole.totp.TOTPGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -249,15 +249,18 @@
// If the user hasn't completed enrollment, request that they do
if (!key.isConfirmed()) {
field.exposeKey(key);
- throw new GuacamoleInsufficientCredentialsException(
+ throw new TranslatableGuacamoleInsufficientCredentialsException(
+ "TOTP enrollment must be completed before "
+ + "authentication can continue",
"TOTP.INFO_ENROLL_REQUIRED", new CredentialsInfo(
Collections.<Field>singletonList(field)
));
}
// Otherwise simply request the user's authentication code
- throw new GuacamoleInsufficientCredentialsException(
- "TOTP.INFO_CODE_REQUIRED", new CredentialsInfo(
+ throw new TranslatableGuacamoleInsufficientCredentialsException(
+ "A TOTP authentication code is required before login can "
+ + "continue", "TOTP.INFO_CODE_REQUIRED", new CredentialsInfo(
Collections.<Field>singletonList(field)
));
@@ -291,7 +294,8 @@
}
// Provided code is not valid
- throw new GuacamoleClientException("TOTP.INFO_VERIFICATION_FAILED");
+ throw new TranslatableGuacamoleClientException("Provided TOTP code "
+ + "is not valid.", "TOTP.INFO_VERIFICATION_FAILED");
}
diff --git a/guacamole-docker/bin/build-guacamole.sh b/guacamole-docker/bin/build-guacamole.sh
index 88087e5..1b0b0ec 100755
--- a/guacamole-docker/bin/build-guacamole.sh
+++ b/guacamole-docker/bin/build-guacamole.sh
@@ -127,6 +127,7 @@
cp extensions/guacamole-auth-radius/target/guacamole-auth-radius*.jar "$DESTINATION/radius"
fi
+#
# Copy OPENID auth extension and schema modifications
#
@@ -136,6 +137,15 @@
fi
#
+# Copy TOTP auth extension if it was built
+#
+
+if [ -f extensions/guacamole-auth-totp/target/guacamole-auth-totp*.jar ]; then
+ mkdir -p "$DESTINATION/totp"
+ cp extensions/guacamole-auth-totp/target/guacamole-auth-totp*.jar "$DESTINATION/totp"
+fi
+
+#
# Copy Duo auth extension if it was built
#
diff --git a/guacamole-docker/bin/start.sh b/guacamole-docker/bin/start.sh
index f5367b4..2763096 100755
--- a/guacamole-docker/bin/start.sh
+++ b/guacamole-docker/bin/start.sh
@@ -369,6 +369,7 @@
set_optional_property "ldap-encryption-method" "$LDAP_ENCRYPTION_METHOD"
set_optional_property "ldap-max-search-results" "$LDAP_MAX_SEARCH_RESULTS"
set_optional_property "ldap-search-bind-dn" "$LDAP_SEARCH_BIND_DN"
+ set_optional_property "ldap-user-attributes" "$LDAP_USER_ATTRIBUTES"
set_optional_property \
"ldap-search-bind-password" \
@@ -537,6 +538,21 @@
}
##
+## Adds properties to guacamole.properties which configure the TOTP two-factor
+## authentication mechanism.
+##
+associate_totp() {
+ # Update config file
+ set_optional_property "totp-issuer" "$TOTP_ISSUER"
+ set_optional_property "totp-digits" "$TOTP_DIGITS"
+ set_optional_property "totp-period" "$TOTP_PERIOD"
+ set_optional_property "totp-mode" "$TOTP_MODE"
+
+ # Add required .jar files to GUACAMOLE_EXT
+ ln -s /opt/guacamole/totp/guacamole-auth-*.jar "$GUACAMOLE_EXT"
+}
+
+##
## Adds properties to guacamole.properties which configure the Duo two-factor
## authentication service. Checks to see if all variables are defined and makes sure
## DUO_APPLICATION_KEY is >= 40 characters.
@@ -707,6 +723,11 @@
exit 1;
fi
+# Use TOTP if specified.
+if [ "$TOTP_ENABLED" = "true" ]; then
+ associate_totp
+fi
+
# Use Duo if specified.
if [ -n "$DUO_API_HOSTNAME" ]; then
associate_duo
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientBadTypeException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientBadTypeException.java
new file mode 100644
index 0000000..e48b1cf
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientBadTypeException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleClientBadTypeException;
+
+/**
+ * A {@link GuacamoleClientBadTypeException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleClientBadTypeException extends GuacamoleClientBadTypeException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleClientBadTypeException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientBadTypeException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientBadTypeException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleClientBadTypeException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientBadTypeException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientBadTypeException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientBadTypeException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleClientBadTypeException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientException.java
new file mode 100644
index 0000000..59818ed
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleClientException;
+
+/**
+ * A {@link GuacamoleClientException} whose associated message is translatable
+ * and can be passed through an arbitrary translation service, producing a
+ * human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleClientException extends GuacamoleClientException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleClientException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleClientException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleClientException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientOverrunException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientOverrunException.java
new file mode 100644
index 0000000..3ad94c8
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientOverrunException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleClientOverrunException;
+
+/**
+ * A {@link GuacamoleClientOverrunException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleClientOverrunException extends GuacamoleClientOverrunException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleClientOverrunException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientOverrunException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientOverrunException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleClientOverrunException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientOverrunException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientOverrunException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientOverrunException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleClientOverrunException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientTimeoutException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientTimeoutException.java
new file mode 100644
index 0000000..6b9ea7e
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientTimeoutException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleClientTimeoutException;
+
+/**
+ * A {@link GuacamoleClientTimeoutException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleClientTimeoutException extends GuacamoleClientTimeoutException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTimeoutException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientTimeoutException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTimeoutException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleClientTimeoutException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTimeoutException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientTimeoutException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTimeoutException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleClientTimeoutException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientTooManyException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientTooManyException.java
new file mode 100644
index 0000000..d1ba1ca
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleClientTooManyException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleClientTooManyException;
+
+/**
+ * A {@link GuacamoleClientTooManyException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleClientTooManyException extends GuacamoleClientTooManyException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTooManyException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientTooManyException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTooManyException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleClientTooManyException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTooManyException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleClientTooManyException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleClientTooManyException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleClientTooManyException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleConnectionClosedException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleConnectionClosedException.java
new file mode 100644
index 0000000..9b615a5
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleConnectionClosedException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleConnectionClosedException;
+
+/**
+ * A {@link GuacamoleConnectionClosedException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleConnectionClosedException extends GuacamoleConnectionClosedException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleConnectionClosedException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleConnectionClosedException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleConnectionClosedException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleConnectionClosedException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleConnectionClosedException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleConnectionClosedException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleConnectionClosedException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleConnectionClosedException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleCredentialsException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleCredentialsException.java
new file mode 100644
index 0000000..86c04b8
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleCredentialsException.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
+import org.apache.guacamole.net.auth.credentials.GuacamoleCredentialsException;
+
+/**
+ * A {@link GuacamoleCredentialsException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleCredentialsException
+ extends GuacamoleCredentialsException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleCredentialsException with the given
+ * message, cause, and associated credential information. The message must
+ * be provided in both non-translatable (readable as-written) and
+ * translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleCredentialsException(String message,
+ TranslatableMessage translatableMessage, Throwable cause, CredentialsInfo credentialsInfo) {
+ super(message, cause, credentialsInfo);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleCredentialsException with the given
+ * message, and associated credential information. The message must be
+ * provided in both non-translatable (readable as-written) and translatable
+ * forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleCredentialsException(String message,
+ TranslatableMessage translatableMessage, CredentialsInfo credentialsInfo) {
+ super(message, credentialsInfo);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleCredentialsException with the given
+ * message, cause, and associated credential information. The message must
+ * be provided in both non-translatable (readable as-written) and
+ * translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleCredentialsException(String message,
+ String key, Throwable cause, CredentialsInfo credentialsInfo) {
+ this(message, new TranslatableMessage(key), cause, credentialsInfo);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleCredentialsException with the given
+ * message, and associated credential information. The message must be
+ * provided in both non-translatable (readable as-written) and translatable
+ * forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleCredentialsException(String message,
+ String key, CredentialsInfo credentialsInfo) {
+ this(message, new TranslatableMessage(key), credentialsInfo);
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleInsufficientCredentialsException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleInsufficientCredentialsException.java
new file mode 100644
index 0000000..5b51d2c
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleInsufficientCredentialsException.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
+import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
+
+/**
+ * A {@link GuacamoleInsufficientCredentialsException} whose associated message
+ * is translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleInsufficientCredentialsException
+ extends GuacamoleInsufficientCredentialsException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleInsufficientCredentialsException with
+ * the given message, cause, and associated credential information. The
+ * message must be provided in both non-translatable (readable as-written)
+ * and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInsufficientCredentialsException(String message,
+ TranslatableMessage translatableMessage, Throwable cause, CredentialsInfo credentialsInfo) {
+ super(message, cause, credentialsInfo);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleInsufficientCredentialsException with
+ * the given message, and associated credential information. The message
+ * must be provided in both non-translatable (readable as-written) and
+ * translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInsufficientCredentialsException(String message,
+ TranslatableMessage translatableMessage, CredentialsInfo credentialsInfo) {
+ super(message, credentialsInfo);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleInsufficientCredentialsException with
+ * the given message, cause, and associated credential information. The
+ * message must be provided in both non-translatable (readable as-written)
+ * and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInsufficientCredentialsException(String message,
+ String key, Throwable cause, CredentialsInfo credentialsInfo) {
+ this(message, new TranslatableMessage(key), cause, credentialsInfo);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleInsufficientCredentialsException with
+ * the given message, and associated credential information. The message
+ * must be provided in both non-translatable (readable as-written) and
+ * translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInsufficientCredentialsException(String message,
+ String key, CredentialsInfo credentialsInfo) {
+ this(message, new TranslatableMessage(key), credentialsInfo);
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleInvalidCredentialsException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleInvalidCredentialsException.java
new file mode 100644
index 0000000..7d878ec
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleInvalidCredentialsException.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
+import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
+
+/**
+ * A {@link GuacamoleInvalidCredentialsException} whose associated message
+ * is translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleInvalidCredentialsException
+ extends GuacamoleInvalidCredentialsException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleInvalidCredentialsException with
+ * the given message, cause, and associated credential information. The
+ * message must be provided in both non-translatable (readable as-written)
+ * and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInvalidCredentialsException(String message,
+ TranslatableMessage translatableMessage, Throwable cause, CredentialsInfo credentialsInfo) {
+ super(message, cause, credentialsInfo);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleInvalidCredentialsException with
+ * the given message, and associated credential information. The message
+ * must be provided in both non-translatable (readable as-written) and
+ * translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInvalidCredentialsException(String message,
+ TranslatableMessage translatableMessage, CredentialsInfo credentialsInfo) {
+ super(message, credentialsInfo);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleInvalidCredentialsException with
+ * the given message, cause, and associated credential information. The
+ * message must be provided in both non-translatable (readable as-written)
+ * and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInvalidCredentialsException(String message,
+ String key, Throwable cause, CredentialsInfo credentialsInfo) {
+ this(message, new TranslatableMessage(key), cause, credentialsInfo);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleInvalidCredentialsException with
+ * the given message, and associated credential information. The message
+ * must be provided in both non-translatable (readable as-written) and
+ * translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param credentialsInfo
+ * Information describing the form of valid credentials.
+ */
+ public TranslatableGuacamoleInvalidCredentialsException(String message,
+ String key, CredentialsInfo credentialsInfo) {
+ this(message, new TranslatableMessage(key), credentialsInfo);
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceClosedException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceClosedException.java
new file mode 100644
index 0000000..b0e5b48
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceClosedException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleResourceClosedException;
+
+/**
+ * A {@link GuacamoleResourceClosedException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleResourceClosedException extends GuacamoleResourceClosedException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceClosedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleResourceClosedException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceClosedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleResourceClosedException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceClosedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleResourceClosedException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceClosedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleResourceClosedException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceConflictException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceConflictException.java
new file mode 100644
index 0000000..e730206
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceConflictException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleResourceConflictException;
+
+/**
+ * A {@link GuacamoleResourceConflictException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleResourceConflictException extends GuacamoleResourceConflictException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceConflictException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleResourceConflictException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceConflictException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleResourceConflictException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceConflictException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleResourceConflictException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceConflictException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleResourceConflictException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceNotFoundException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceNotFoundException.java
new file mode 100644
index 0000000..138da0e
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleResourceNotFoundException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleResourceNotFoundException;
+
+/**
+ * A {@link GuacamoleResourceNotFoundException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleResourceNotFoundException extends GuacamoleResourceNotFoundException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceNotFoundException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleResourceNotFoundException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceNotFoundException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleResourceNotFoundException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceNotFoundException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleResourceNotFoundException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleResourceNotFoundException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleResourceNotFoundException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSecurityException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSecurityException.java
new file mode 100644
index 0000000..e6a9ecd
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSecurityException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleSecurityException;
+
+/**
+ * A {@link GuacamoleSecurityException} whose associated message is translatable
+ * and can be passed through an arbitrary translation service, producing a
+ * human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleSecurityException extends GuacamoleSecurityException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleSecurityException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSecurityException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSecurityException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleSecurityException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSecurityException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSecurityException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSecurityException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleSecurityException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleServerBusyException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleServerBusyException.java
new file mode 100644
index 0000000..7d735b4
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleServerBusyException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleServerBusyException;
+
+/**
+ * A {@link GuacamoleServerBusyException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleServerBusyException extends GuacamoleServerBusyException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleServerBusyException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleServerBusyException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleServerBusyException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleServerBusyException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleServerBusyException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleServerBusyException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleServerBusyException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleServerBusyException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleServerException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleServerException.java
new file mode 100644
index 0000000..686498c
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleServerException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleServerException;
+
+/**
+ * A {@link GuacamoleServerException} whose associated message is translatable
+ * and can be passed through an arbitrary translation service, producing a
+ * human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleServerException extends GuacamoleServerException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleServerException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleServerException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleServerException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleServerException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleServerException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleServerException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleServerException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleServerException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionClosedException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionClosedException.java
new file mode 100644
index 0000000..ca9a025
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionClosedException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleSessionClosedException;
+
+/**
+ * A {@link GuacamoleSessionClosedException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleSessionClosedException extends GuacamoleSessionClosedException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionClosedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSessionClosedException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionClosedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleSessionClosedException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionClosedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSessionClosedException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionClosedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleSessionClosedException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionConflictException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionConflictException.java
new file mode 100644
index 0000000..b20575b
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionConflictException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleSessionConflictException;
+
+/**
+ * A {@link GuacamoleSessionConflictException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleSessionConflictException extends GuacamoleSessionConflictException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionConflictException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSessionConflictException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionConflictException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleSessionConflictException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionConflictException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSessionConflictException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionConflictException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleSessionConflictException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionTimeoutException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionTimeoutException.java
new file mode 100644
index 0000000..700a3ee
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleSessionTimeoutException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleSessionTimeoutException;
+
+/**
+ * A {@link GuacamoleSessionTimeoutException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleSessionTimeoutException extends GuacamoleSessionTimeoutException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionTimeoutException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSessionTimeoutException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionTimeoutException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleSessionTimeoutException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionTimeoutException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleSessionTimeoutException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleSessionTimeoutException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleSessionTimeoutException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUnauthorizedException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUnauthorizedException.java
new file mode 100644
index 0000000..340aced
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUnauthorizedException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleUnauthorizedException;
+
+/**
+ * A {@link GuacamoleUnauthorizedException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleUnauthorizedException extends GuacamoleUnauthorizedException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleUnauthorizedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUnauthorizedException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUnauthorizedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleUnauthorizedException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUnauthorizedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUnauthorizedException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUnauthorizedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleUnauthorizedException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUnsupportedException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUnsupportedException.java
new file mode 100644
index 0000000..184f65a
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUnsupportedException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleUnsupportedException;
+
+/**
+ * A {@link GuacamoleUnsupportedException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleUnsupportedException extends GuacamoleUnsupportedException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleUnsupportedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUnsupportedException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUnsupportedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleUnsupportedException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUnsupportedException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUnsupportedException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUnsupportedException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleUnsupportedException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamException.java
new file mode 100644
index 0000000..0122acb
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleUpstreamException;
+
+/**
+ * A {@link GuacamoleUpstreamException} whose associated message is translatable
+ * and can be passed through an arbitrary translation service, producing a
+ * human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleUpstreamException extends GuacamoleUpstreamException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleUpstreamException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamException with the given
+ * message and cause. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamException with the given
+ * message. The message must be provided in both non-translatable (readable
+ * as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleUpstreamException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamNotFoundException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamNotFoundException.java
new file mode 100644
index 0000000..e9b3214
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamNotFoundException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleUpstreamNotFoundException;
+
+/**
+ * A {@link GuacamoleUpstreamNotFoundException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleUpstreamNotFoundException extends GuacamoleUpstreamNotFoundException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamNotFoundException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamNotFoundException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamNotFoundException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleUpstreamNotFoundException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamNotFoundException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamNotFoundException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamNotFoundException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleUpstreamNotFoundException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamTimeoutException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamTimeoutException.java
new file mode 100644
index 0000000..9cac87c
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamTimeoutException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleUpstreamTimeoutException;
+
+/**
+ * A {@link GuacamoleUpstreamTimeoutException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleUpstreamTimeoutException extends GuacamoleUpstreamTimeoutException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamTimeoutException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamTimeoutException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamTimeoutException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleUpstreamTimeoutException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamTimeoutException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamTimeoutException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamTimeoutException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleUpstreamTimeoutException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamUnavailableException.java b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamUnavailableException.java
new file mode 100644
index 0000000..2962eb6
--- /dev/null
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/language/TranslatableGuacamoleUpstreamUnavailableException.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.language;
+
+import org.apache.guacamole.GuacamoleUpstreamUnavailableException;
+
+/**
+ * A {@link GuacamoleUpstreamUnavailableException} whose associated message is
+ * translatable and can be passed through an arbitrary translation service,
+ * producing a human-readable message in the user's native language.
+ */
+public class TranslatableGuacamoleUpstreamUnavailableException extends GuacamoleUpstreamUnavailableException implements Translatable {
+
+ /**
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ private final TranslatableMessage translatableMessage;
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamUnavailableException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamUnavailableException(String message, TranslatableMessage translatableMessage, Throwable cause) {
+ super(message, cause);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamUnavailableException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param translatableMessage
+ * A translatable, human-readable description of the exception that
+ * occurred.
+ */
+ public TranslatableGuacamoleUpstreamUnavailableException(String message, TranslatableMessage translatableMessage) {
+ super(message);
+ this.translatableMessage = translatableMessage;
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamUnavailableException with the
+ * given message and cause. The message must be provided in both
+ * non-translatable (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ *
+ * @param cause
+ * The cause of this exception.
+ */
+ public TranslatableGuacamoleUpstreamUnavailableException(String message, String key, Throwable cause) {
+ this(message, new TranslatableMessage(key), cause);
+ }
+
+ /**
+ * Creates a new TranslatableGuacamoleUpstreamUnavailableException with the
+ * given message. The message must be provided in both non-translatable
+ * (readable as-written) and translatable forms.
+ *
+ * @param message
+ * A human-readable description of the exception that occurred. This
+ * message should be readable on its own and as-written, without
+ * requiring a translation service.
+ *
+ * @param key
+ * The arbitrary key which can be used to look up the message to be
+ * displayed in the user's native language.
+ */
+ public TranslatableGuacamoleUpstreamUnavailableException(String message, String key) {
+ this(message, new TranslatableMessage(key));
+ }
+
+ @Override
+ public TranslatableMessage getTranslatableMessage() {
+ return translatableMessage;
+ }
+
+}