From 86cf2fbb3469f1ea50f021322ed6cf57a0f3fe74 Mon Sep 17 00:00:00 2001 From: sahan Date: Thu, 25 Jul 2013 23:34:44 +0530 Subject: [PATCH] Add models for GitHub users and repos; update intent-filter service policy (issue #2) --- travisjr/res/values/errors.xml | 1 + .../travisjr/model/GitHubRepository.java | 178 ++++++++++++++++++ .../lonepulse/travisjr/model/GitHubUser.java | 149 +++++++++++++++ .../travisjr/net/GitHubEndpoint.java | 11 +- .../travisjr/net/GitHubValidationParser.java | 55 ------ .../service/BasicIntentFilterService.java | 86 ++++----- .../travisjr/service/IntentFilterService.java | 16 +- ...positoryAuthenticationFailedException.java | 116 ++++++++++++ .../UserAuthenticationFailedException.java | 116 ++++++++++++ 9 files changed, 617 insertions(+), 111 deletions(-) create mode 100644 travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubRepository.java create mode 100644 travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubUser.java delete mode 100644 travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubValidationParser.java create mode 100644 travisjr/src/main/java/com/lonepulse/travisjr/service/RepositoryAuthenticationFailedException.java create mode 100644 travisjr/src/main/java/com/lonepulse/travisjr/service/UserAuthenticationFailedException.java diff --git a/travisjr/res/values/errors.xml b/travisjr/res/values/errors.xml index 7491500..3fa38fa 100644 --- a/travisjr/res/values/errors.xml +++ b/travisjr/res/values/errors.xml @@ -27,5 +27,6 @@ No Repositories Found Failed to fetch repositories. Failed to fetch info... + Not Found \ No newline at end of file diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubRepository.java b/travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubRepository.java new file mode 100644 index 0000000..69f7295 --- /dev/null +++ b/travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubRepository.java @@ -0,0 +1,178 @@ +package com.lonepulse.travisjr.model; + +/* + * #%L + * Travis Jr. App + * %% + * Copyright (C) 2013 Lonepulse + * %% + * Licensed 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. + * #L% + */ + + +import java.io.Serializable; + +/** + *

This model represents a GitHub repository.

+ * + *

Note that this is a partial representation of the complete Repository model (available + * via the service {@code https://api.github.com/repos}) which is used for authentication and + * for retrieving the repository slug in its proper case. + * + * @since 1.1.0 + *

+ * @version 1.1.0 + *

+ * @author Lahiru Sahan Jayasinghe + */ +public class GitHubRepository implements Serializable { + + + private static final long serialVersionUID = -957338228041395159L; + + /** + *

Identifies this GitHub repository uniquely. + */ + private String id; + + /** + *

The name of this GitHub repository in its proper case. + */ + private String name; + + /** + *

The complete slug for this GitHub repository in its proper case. + */ + private String full_name; + + /** + *

A message which describes an API request failure. + */ + private String message; + + + /** + *

Accessor for id. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + *

Mutator for id. + * + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + *

Accessor for name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + *

Mutator for name. + * + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + *

Accessor for full_name. + * + * @return the full_name + */ + public String getFull_name() { + return full_name; + } + + /** + *

Mutator for full_name. + * + * @param full_name + * the full_name to set + */ + public void setFull_name(String full_name) { + this.full_name = full_name; + } + + /** + *

Accessor for message. + * + * @return the message + */ + public String getMessage() { + return message; + } + + /** + *

Mutator for message. + * + * @param message + * the message to set + */ + public void setMessage(String message) { + this.message = message; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GitHubRepository other = (GitHubRepository) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("GitHubRepository [id="); + builder.append(id); + builder.append(", name="); + builder.append(name); + builder.append(", full_name="); + builder.append(full_name); + builder.append("]"); + return builder.toString(); + } +} diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubUser.java b/travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubUser.java new file mode 100644 index 0000000..61ed9a9 --- /dev/null +++ b/travisjr/src/main/java/com/lonepulse/travisjr/model/GitHubUser.java @@ -0,0 +1,149 @@ +package com.lonepulse.travisjr.model; + +/* + * #%L + * Travis Jr. App + * %% + * Copyright (C) 2013 Lonepulse + * %% + * Licensed 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. + * #L% + */ + + +import java.io.Serializable; + +/** + *

This model represents a GitHub user. This could be an individual or an organization.

+ * + *

Note that this is a partial representation of the complete User model (available + * via the service {@code https://api.github.com/users}) which is used for authentication and + * for retrieving the login name in its proper case. + * + * @since 1.1.0 + *

+ * @version 1.1.0 + *

+ * @author Lahiru Sahan Jayasinghe + */ +public class GitHubUser implements Serializable { + + + private static final long serialVersionUID = 5687172223807519601L; + + /** + *

Identifies this GitHub user uniquely. + */ + private String id; + + /** + *

The login name of this GitHub user in its proper case. + */ + private String login; + + /** + *

A message which describes an API request failure. + */ + private String message; + + + /** + *

Accessor for id. + * + * @return the id + */ + public String getId() { + return id; + } + /** + *

Mutator for id. + * + * @param id + * the id to set + */ + public void setId(String id) { + this.id = id; + } + /** + *

Accessor for login. + * + * @return the login + */ + public String getLogin() { + return login; + } + /** + *

Mutator for login. + * + * @param login + * the login to set + */ + public void setLogin(String login) { + this.login = login; + } + /** + *

Accessor for message. + * + * @return the message + */ + public String getMessage() { + return message; + } + /** + *

Mutator for message. + * + * @param message + * the message to set + */ + public void setMessage(String message) { + this.message = message; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + GitHubUser other = (GitHubUser) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("GitHubUser [id="); + builder.append(id); + builder.append(", login="); + builder.append(login); + builder.append(", message="); + builder.append(message); + builder.append("]"); + return builder.toString(); + } +} diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubEndpoint.java b/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubEndpoint.java index bb0965b..84129eb 100644 --- a/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubEndpoint.java +++ b/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubEndpoint.java @@ -25,6 +25,8 @@ import com.lonepulse.robozombie.core.annotation.Parser; import com.lonepulse.robozombie.rest.annotation.PathParam; import com.lonepulse.robozombie.rest.annotation.Rest; +import com.lonepulse.travisjr.model.GitHubRepository; +import com.lonepulse.travisjr.model.GitHubUser; /** /** @@ -36,6 +38,7 @@ *

* @author Lahiru Sahan Jayasinghe */ +@Parser(Parser.PARSER_TYPE.JSON) @Endpoint(scheme = "https", value = "api.github.com") public interface GitHubEndpoint { @@ -51,8 +54,7 @@ public interface GitHubEndpoint { * @since 1.1.0 */ @Rest(path = "/users/:user") - @Parser(type = GitHubValidationParser.class) - Boolean isValidUser(@PathParam("user") String user); + GitHubUser getUser(@PathParam("user") String user); /** *

A simple call to the /users service at api.github.com @@ -68,7 +70,6 @@ public interface GitHubEndpoint { * * @since 1.1.0 */ - @Rest(path = "/users/:user") - @Parser(type = GitHubValidationParser.class) - Boolean isValidRepository(@PathParam("user") String user, @PathParam("repo") String repo); + @Rest(path = "/repos/:user/:repo") + GitHubRepository getRepository(@PathParam("user") String user, @PathParam("repo") String repo); } diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubValidationParser.java b/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubValidationParser.java deleted file mode 100644 index 9335d28..0000000 --- a/travisjr/src/main/java/com/lonepulse/travisjr/net/GitHubValidationParser.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.lonepulse.travisjr.net; - -/* - * #%L - * Travis Jr. App - * %% - * Copyright (C) 2013 Lonepulse - * %% - * Licensed 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. - * #L% - */ - - -import org.apache.http.HttpResponse; -import org.apache.http.util.EntityUtils; - -import com.lonepulse.robozombie.core.response.parser.AbstractResponseParser; - -/** - *

Parses the content of the {@link HttpResponse} body to determine if valid - * JSON content is received for a GitHup API call of type /user/:username. - * - * @since 1.1.0 - *

- * @version 1.1.0 - *

- * @author Lahiru Sahan Jayasinghe - */ -public class GitHubValidationParser extends AbstractResponseParser { - - - @Override - protected Boolean processResponse(HttpResponse httpResponse) throws Exception { - - String responseBody = EntityUtils.toString(httpResponse.getEntity()); - - return responseBody.contains("\"message\": \"Not Found\""); - } - - @Override - protected Class getType() { - - return Boolean.class; - } -} diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/service/BasicIntentFilterService.java b/travisjr/src/main/java/com/lonepulse/travisjr/service/BasicIntentFilterService.java index 0efae76..9963d50 100644 --- a/travisjr/src/main/java/com/lonepulse/travisjr/service/BasicIntentFilterService.java +++ b/travisjr/src/main/java/com/lonepulse/travisjr/service/BasicIntentFilterService.java @@ -22,22 +22,22 @@ import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; import android.content.IntentFilter; import android.net.Uri; import com.lonepulse.robozombie.core.annotation.Bite; import com.lonepulse.robozombie.core.inject.Zombie; +import com.lonepulse.travisjr.R; +import com.lonepulse.travisjr.model.GitHubRepository; +import com.lonepulse.travisjr.model.GitHubUser; import com.lonepulse.travisjr.net.GitHubEndpoint; +import com.lonepulse.travisjr.util.Resources; /** *

A concrete implementation of {@link IntentFilterService} which offers services for working - * with {@link Uri} data filtered through an {@link IntentFilter}. Only {@link Uri}s whose host is - * travis-ci.org will be processed. + * with {@link Uri} data filtered through an {@link IntentFilter}. Only {@link Uri}s whose host + * is travis-ci.org will be processed. * * @since 1.1.0 *

@@ -50,6 +50,8 @@ public class BasicIntentFilterService implements IntentFilterService { public static final String travisCIHost = "travis-ci.org"; + public static final String msgNotFound = Resources.error(R.string.err_github_msg_not_found); + @Bite private GitHubEndpoint gitHubEndpoint; @@ -59,97 +61,91 @@ public class BasicIntentFilterService implements IntentFilterService { /** - *

See {@link IntentFilterService#isValidUser(Uri)}.

+ *

See {@link IntentFilterService#resolveUser(Uri)}.

* *

Note that this service is a blocking operation which contacts the GitHub API - * at api.github.com to validate the user. + * at api.github.com to validate the user. Execute this on a worker thread.

*/ @Override - public boolean isValidUser(Uri uri) { + public String resolveUser(Uri uri) { - ExecutorService executorService = Executors.newFixedThreadPool(1); + UserAuthenticationFailedException uafe = new UserAuthenticationFailedException(uri); try { if(!isValidContext(uri)) { - return false; + throw uafe; } List pathSegments = uri.getPathSegments(); if(pathSegments == null || pathSegments.size() != 1) { - return false; + throw uafe; } - final String user = pathSegments.get(0); + GitHubUser gitHubUser = gitHubEndpoint.getUser(pathSegments.get(0)); - Future future = executorService.submit(new Callable() { - - public Boolean call() throws Exception { - - return gitHubEndpoint.isValidUser(user); - } - }); + String message = gitHubUser.getMessage(); - return future.get(); + if(message != null && message.equals(msgNotFound)) { + + throw uafe; + } + + return gitHubUser.getLogin(); } catch (Exception e) { - return Boolean.FALSE; - } - finally { - - executorService.shutdownNow(); + throw (e instanceof UserAuthenticationFailedException)? (UserAuthenticationFailedException)e + :new UserAuthenticationFailedException(uri, e); } } /** - *

See {@link IntentFilterService#isValidRepository(Uri)}.

+ *

See {@link IntentFilterService#resolveRepository(Uri)}.

* *

Note that this service is a blocking operation which contacts the GitHub API - * at api.github.com to validate the repository. + * at api.github.com to validate the repository. Execute this on a worker thread.

*/ @Override - public boolean isValidRepository(Uri uri) { + public String resolveRepository(Uri uri) { - ExecutorService executorService = Executors.newFixedThreadPool(1); + RepositoryAuthenticationFailedException rafe = new RepositoryAuthenticationFailedException(uri); try { if(!isValidContext(uri)) { - return false; + throw rafe; } List pathSegments = uri.getPathSegments(); if(pathSegments == null || pathSegments.size() != 2) { - return false; + throw rafe; } final String user = pathSegments.get(0); final String repo = pathSegments.get(1); - Future future = executorService.submit(new Callable() { + GitHubRepository gitHubRepo = gitHubEndpoint.getRepository(user, repo); + + String message = gitHubRepo.getMessage(); + + if(message != null && message.equals(msgNotFound)) { - public Boolean call() throws Exception { - - return gitHubEndpoint.isValidRepository(user, repo); - } - }); - - return future.get(); + throw rafe; + } + + return gitHubRepo.getFull_name(); } catch (Exception e) { - return Boolean.FALSE; - } - finally { - - executorService.shutdownNow(); + throw (e instanceof RepositoryAuthenticationFailedException)? (RepositoryAuthenticationFailedException)e + :new RepositoryAuthenticationFailedException(uri, e); } } diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/service/IntentFilterService.java b/travisjr/src/main/java/com/lonepulse/travisjr/service/IntentFilterService.java index c2d3e54..2fb5b2c 100644 --- a/travisjr/src/main/java/com/lonepulse/travisjr/service/IntentFilterService.java +++ b/travisjr/src/main/java/com/lonepulse/travisjr/service/IntentFilterService.java @@ -37,20 +37,22 @@ public interface IntentFilterService { /** - *

Determines if the given {@link Uri} points to user on travis-ci.org. + *

Determines if the given {@link Uri} points to a user on travis-ci.org. * * @param uri * the {@link Uri} to be checked if it points to a user * - * @return {@code true} if the given {@link Uri} points to a user, else {@code false} if - * the {@link Uri} does not point to a user or if an error occurred during validation + * @return the username of the GitHub user in its proper case + * + * @throws UserAuthenticationFailedException + * if a valid GitHub user failed to be resolved using the given {@link Uri} * * @since 1.1.0 */ - boolean isValidUser(Uri uri); + String resolveUser(Uri uri) throws UserAuthenticationFailedException; /** - *

Determines if the given {@link Uri} points to repository on travis-ci.org. + *

Determines if the given {@link Uri} points to a repository on travis-ci.org. * * @param uri * the {@link Uri} to be checked if it points to a repository @@ -58,7 +60,9 @@ public interface IntentFilterService { * @return {@code true} if the given {@link Uri} points to a repository, else {@code false} if * the {@link Uri} does not point to a repository or if an error occurred during validation * + * @return the GitHub repository it its proper case, in the format <user>/<repo> + * * @since 1.1.0 */ - boolean isValidRepository(Uri uri); + String resolveRepository(Uri uri) throws RepositoryAuthenticationFailedException; } diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/service/RepositoryAuthenticationFailedException.java b/travisjr/src/main/java/com/lonepulse/travisjr/service/RepositoryAuthenticationFailedException.java new file mode 100644 index 0000000..fa121cd --- /dev/null +++ b/travisjr/src/main/java/com/lonepulse/travisjr/service/RepositoryAuthenticationFailedException.java @@ -0,0 +1,116 @@ +package com.lonepulse.travisjr.service; + +/* + * #%L + * Travis Jr. + * %% + * Copyright (C) 2013 Lonepulse + * %% + * Licensed 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. + * #L% + */ + + +import android.net.Uri; + +import com.lonepulse.travisjr.TravisJrException; +import com.lonepulse.travisjr.TravisJrRuntimeException; + +/** + *

This exception is thrown when a GitHub repository failed to be authenticated using the + * API at {@code https://api.github.com/repos}). + * + * @since 1.1.0 + *

+ * @version 1.1.0 + *

+ * @author Lahiru Sahan Jayasinghe + */ +public class RepositoryAuthenticationFailedException extends TravisJrRuntimeException { + + + private static final long serialVersionUID = -3484014330090316059L; + + + /** + *

Prints a detailed message using the {@link Uri} which failed to be resolved + * to an authentic GitHub repository. + * + * @param uri + * the {@link Uri} which failed to be resolved to a GitHub repository + * + * @since 1.1.0 + */ + public RepositoryAuthenticationFailedException(Uri uri) { + + this("A GitHub repository failed to be resolved for the url " + + ((uri == null)? "" :uri.toString())); + } + + /** + *

Prints a detailed message using the {@link Uri} which failed to be resolved + * to an authentic GitHub repository and the root cause of this failure. + * + * @param uri + * the {@link Uri} which failed to be resolved to a GitHub repository + * + * @param rootCause + * the root cause which caused a failure in repository resolution + * + * @since 1.1.0 + */ + public RepositoryAuthenticationFailedException(Uri uri, Throwable rootCause) { + + this("A GitHub repository failed to be resolved for the url " + + ((uri == null)? "" :uri.toString()), rootCause); + } + + /** + *

Prints a detailed with the "<user>/<repo>" identifier which failed to be authenticated. + * + * @param user + * the username which failed to be authenticated + * + * @since 1.1.0 + */ + public RepositoryAuthenticationFailedException(String slug) { + + super("The repository " + slug + " failed to be authenticated. "); + } + + /** + *

See {@link TravisJrException#TravisJrRuntimeException(Throwable)}. + * + * @since 1.1.0 + */ + public RepositoryAuthenticationFailedException(Throwable throwable) { + + super(throwable); + } + + /** + *

Prints a detailed with the "<user>/<repo>" identifier which failed to be authenticated. + * + * @param user + * the username which failed to be authenticated + * + * @param rootCause + * the root cause which caused a failure in repository resolution + * + * @since 1.1.0 + */ + public RepositoryAuthenticationFailedException(String slug, Throwable rootCause) { + + super("The repository " + slug + " failed to be authenticated. ", rootCause); + } +} diff --git a/travisjr/src/main/java/com/lonepulse/travisjr/service/UserAuthenticationFailedException.java b/travisjr/src/main/java/com/lonepulse/travisjr/service/UserAuthenticationFailedException.java new file mode 100644 index 0000000..43b7a7c --- /dev/null +++ b/travisjr/src/main/java/com/lonepulse/travisjr/service/UserAuthenticationFailedException.java @@ -0,0 +1,116 @@ +package com.lonepulse.travisjr.service; + +/* + * #%L + * Travis Jr. + * %% + * Copyright (C) 2013 Lonepulse + * %% + * Licensed 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. + * #L% + */ + + +import android.net.Uri; + +import com.lonepulse.travisjr.TravisJrException; +import com.lonepulse.travisjr.TravisJrRuntimeException; + +/** + *

This exception is thrown when a GitHub user failed to be authenticated using the + * API at {@code https://api.github.com/users}). + * + * @since 1.1.0 + *

+ * @version 1.1.0 + *

+ * @author Lahiru Sahan Jayasinghe + */ +public class UserAuthenticationFailedException extends TravisJrRuntimeException { + + + private static final long serialVersionUID = -7087904713673704796L; + + + /** + *

Prints a detailed message using the {@link Uri} which failed to be resolved + * to an authentic GitHub user. + * + * @param uri + * the {@link Uri} which failed to be resolved to a GitHub user + * + * @since 1.1.0 + */ + public UserAuthenticationFailedException(Uri uri) { + + this("A GitHub user failed to be resolved for the url " + + ((uri == null)? "" :uri.toString())); + } + + /** + *

Prints a detailed message using the {@link Uri} which failed to be resolved + * to an authentic GitHub user. + * + * @param uri + * the {@link Uri} which failed to be resolved to a GitHub user + * + * @param rootCause + * the root cause which caused a failure in repository resolution + * + * @since 1.1.0 + */ + public UserAuthenticationFailedException(Uri uri, Throwable rootCause) { + + this("A GitHub user failed to be resolved for the url " + + ((uri == null)? "" :uri.toString()), rootCause); + } + + /** + *

Prints a detailed with the username which failed to be authenticated. + * + * @param user + * the username which failed to be authenticated + * + * @since 1.1.0 + */ + public UserAuthenticationFailedException(String user) { + + super("The user " + user + " failed to be authenticated. "); + } + + /** + *

See {@link TravisJrException#TravisJrRuntimeException(Throwable)}. + * + * @since 1.1.0 + */ + public UserAuthenticationFailedException(Throwable throwable) { + + super(throwable); + } + + /** + *

Prints a detailed with the username which failed to be authenticated. + * + * @param user + * the username which failed to be authenticated + * + * @param rootCause + * the root cause which caused a failure in repository resolution + * + * @since 1.1.0 + */ + public UserAuthenticationFailedException(String user, Throwable rootCause) { + + super("The user " + user + " failed to be authenticated. ", rootCause); + } +}