Github: remove duplicated interfaces

This commit is contained in:
Aleksey Pivovarov
2013-07-29 16:47:15 +04:00
parent 8cf7908a8b
commit a448f9f8b3
11 changed files with 180 additions and 109 deletions
@@ -25,27 +25,13 @@ import org.jetbrains.annotations.NotNull;
* All fields of the raw type are nullable by the nature of GSon parser;
* but some of them are required, so we want them to be @NotNull in the actual data class,
* otherwise there is an error in JSon data received from the server
* <p/>
*
* So we create Data class assuming that all required fields actually notnull and
* catch exception if they are not.
* <p/>
* There are few similar interfaces because same entity can be provided with
* different levels of detailing. And we don't want to duplicate Raw classes to
* support such cases.
*
* Probably, these interfaces shouldn't be used outside of GithubApiUtil.createDataFromRaw()
*/
interface DataConstructor<T> {
interface DataConstructor {
@NotNull
T create() throws IllegalArgumentException, NullPointerException;
}
interface DataConstructorDetailed<T> {
@NotNull
T createDetailed() throws IllegalArgumentException, NullPointerException;
}
interface DataConstructorSimplified<T> {
@NotNull
T createSimplified() throws IllegalArgumentException, NullPointerException;
<T> T create(@NotNull Class<T> resultClass) throws IllegalArgumentException, NullPointerException, ClassCastException;
}
@@ -299,32 +299,10 @@ public class GithubApiUtil {
* Github API
*/
static <Raw extends DataConstructor<Result>, Result> Result createDataFromRaw(@NotNull Raw rawObject,
@NotNull Class<Result> result) throws JsonException {
try {
return rawObject.create();
}
catch (Exception e) {
throw new JsonException("Json parse error", e);
}
}
static <Raw extends DataConstructorDetailed<Result>, Result> Result createDataFromRaw(@NotNull Raw rawObject,
@NotNull Class<Result> result)
static <Raw extends DataConstructor, Result> Result createDataFromRaw(@NotNull Raw rawObject, @NotNull Class<Result> resultClass)
throws JsonException {
try {
return rawObject.createDetailed();
}
catch (Exception e) {
throw new JsonException("Json parse error", e);
}
}
static <Raw extends DataConstructorSimplified<Result>, Result> Result createDataFromRaw(@NotNull Raw rawObject,
@NotNull Class<Result> result)
throws JsonException {
try {
return rawObject.createSimplified();
return rawObject.create(resultClass);
}
catch (Exception e) {
throw new JsonException("Json parse error", e);
@@ -23,8 +23,8 @@ import java.util.List;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubAuthorizationRaw implements DataConstructor<GithubAuthorization> {
@SuppressWarnings("UnusedDeclaration")
class GithubAuthorizationRaw implements DataConstructor {
@Nullable public Long id;
@Nullable public String url;
@Nullable public String token;
@@ -32,9 +32,19 @@ class GithubAuthorizationRaw implements DataConstructor<GithubAuthorization> {
@Nullable public String noteUrl;
@Nullable public List<String> scopes;
@NotNull
@Override
public GithubAuthorization create() {
@SuppressWarnings("ConstantConditions")
public GithubAuthorization createAuthorization() {
return new GithubAuthorization(token, scopes);
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubAuthorization.class)) {
return (T)createAuthorization();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -25,9 +25,7 @@ import java.util.List;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubCommitRaw
implements DataConstructorSimplified<GithubCommitSha>, DataConstructor<GithubCommit>, DataConstructorDetailed<GithubCommitDetailed> {
class GithubCommitRaw implements DataConstructor {
@Nullable public String url;
@Nullable public String sha;
@@ -41,73 +39,90 @@ class GithubCommitRaw
@Nullable public List<GithubCommitRaw> parents;
public static class GitCommitRaw implements DataConstructor<GithubCommit.GitCommit> {
public static class GitCommitRaw {
@Nullable public String url;
@Nullable public String message;
@Nullable public GitUserRaw author;
@Nullable public GitUserRaw committer;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubCommit.GitCommit create() {
return new GithubCommit.GitCommit(message, author.create(), committer.create());
}
}
public static class GitUserRaw implements DataConstructor<GithubCommit.GitUser> {
public static class GitUserRaw {
@Nullable public String name;
@Nullable public String email;
@Nullable public Date date;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubCommit.GitUser create() {
return new GithubCommit.GitUser(name, email, date);
}
}
public static class CommitStatsRaw implements DataConstructor<GithubCommitDetailed.CommitStats> {
public static class CommitStatsRaw {
@Nullable public Integer additions;
@Nullable public Integer deletions;
@Nullable public Integer total;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubCommitDetailed.CommitStats create() {
return new GithubCommitDetailed.CommitStats(additions, deletions, total);
}
}
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubCommitSha createSimplified() {
public GithubCommitSha createCommitSha() {
return new GithubCommitSha(url, sha);
}
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubCommit create() {
GithubUser author = this.author == null ? null : this.author.create();
GithubUser committer = this.committer == null ? null : this.committer.create();
public GithubCommit createCommit() {
GithubUser author = this.author == null ? null : this.author.createUser();
GithubUser committer = this.committer == null ? null : this.committer.createUser();
List<GithubCommitSha> parents = new ArrayList<GithubCommitSha>();
for (GithubCommitRaw raw : this.parents) {
parents.add(raw.create());
parents.add(raw.createCommitSha());
}
return new GithubCommit(url, sha, author, committer, parents, commit.create());
}
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubCommitDetailed createDetailed() {
GithubCommit commit = create();
public GithubCommitDetailed createCommitDetailed() {
GithubCommit commit = createCommit();
List<GithubFile> files = new ArrayList<GithubFile>();
for (GithubFileRaw raw : this.files) {
files.add(raw.create());
files.add(raw.createFile());
}
return new GithubCommitDetailed(commit.getUrl(), commit.getSha(), commit.getAuthor(), commit.getCommitter(), commit.getParents(),
commit.getCommit(), stats.create(), files);
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubCommitSha.class)) {
return (T)createCommitSha();
}
if (resultClass.isAssignableFrom(GithubCommit.class)) {
return (T)createCommit();
}
if (resultClass.isAssignableFrom(GithubCommitDetailed.class)) {
return (T)createCommitDetailed();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -21,8 +21,8 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
public class GithubFileRaw implements DataConstructor<GithubFile> {
@SuppressWarnings("UnusedDeclaration")
public class GithubFileRaw implements DataConstructor {
@Nullable public String filename;
@Nullable public Integer additions;
@@ -33,9 +33,20 @@ public class GithubFileRaw implements DataConstructor<GithubFile> {
@Nullable public String blobUrl;
@Nullable public String patch;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubFile create() {
public GithubFile createFile() {
return new GithubFile(filename, additions, deletions, changes, status, rawUrl, patch);
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubFile.class)) {
return (T)createFile();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -27,8 +27,8 @@ import java.util.Map;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubGistRaw implements DataConstructor<GithubGist> {
@SuppressWarnings("UnusedDeclaration")
class GithubGistRaw implements DataConstructor {
@Nullable public String id;
@Nullable public String description;
@@ -46,7 +46,7 @@ class GithubGistRaw implements DataConstructor<GithubGist> {
@Nullable public Date createdAt;
public static class GistFileRaw implements DataConstructor<GithubGist.GistFile> {
public static class GistFileRaw {
@Nullable public Long size;
@Nullable public String filename;
@Nullable public String content;
@@ -56,17 +56,17 @@ class GithubGistRaw implements DataConstructor<GithubGist> {
@Nullable public String type;
@Nullable public String language;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubGist.GistFile create() {
return new GithubGist.GistFile(filename, content, raw_url);
}
}
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubGist create() {
GithubUser user = this.user == null ? null : this.user.create();
public GithubGist createGist() {
GithubUser user = this.user == null ? null : this.user.createUser();
List<GithubGist.GistFile> files = new ArrayList<GithubGist.GistFile>();
for (Map.Entry<String, GistFileRaw> entry : this.files.entrySet()) {
@@ -75,4 +75,15 @@ class GithubGistRaw implements DataConstructor<GithubGist> {
return new GithubGist(id, description, isPublic, htmlUrl, files, user);
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubGist.class)) {
return (T)createGist();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -23,8 +23,8 @@ import java.util.Date;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubIssueCommentRaw implements DataConstructor<GithubIssueComment> {
@SuppressWarnings("UnusedDeclaration")
class GithubIssueCommentRaw implements DataConstructor {
@Nullable public Long id;
@Nullable public String url;
@@ -36,9 +36,20 @@ class GithubIssueCommentRaw implements DataConstructor<GithubIssueComment> {
@Nullable public GithubUserRaw user;
@SuppressWarnings("ConstantConditions")
@NotNull
public GithubIssueComment createIssueComment() {
return new GithubIssueComment(id, htmlUrl, body, createdAt, updatedAt, user.createUser());
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public GithubIssueComment create() {
return new GithubIssueComment(id, htmlUrl, body, createdAt, updatedAt, user.create());
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubIssueComment.class)) {
return (T)createIssueComment();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -23,8 +23,8 @@ import java.util.Date;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubIssueRaw implements DataConstructor<GithubIssue> {
@SuppressWarnings("UnusedDeclaration")
class GithubIssueRaw implements DataConstructor {
@Nullable public String url;
@Nullable public String htmlUrl;
@Nullable public Long number;
@@ -39,10 +39,21 @@ class GithubIssueRaw implements DataConstructor<GithubIssue> {
@Nullable public Date createdAt;
@Nullable public Date updatedAt;
@SuppressWarnings("ConstantConditions")
@NotNull
public GithubIssue createIssue() {
GithubUser assignee = this.assignee == null ? null : this.assignee.createUser();
return new GithubIssue(htmlUrl, number, state, title, body, user.createUser(), assignee, closedAt, createdAt, updatedAt);
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public GithubIssue create() {
GithubUser assignee = this.assignee == null ? null : this.assignee.create();
return new GithubIssue(htmlUrl, number, state, title, body, user.create(), assignee, closedAt, createdAt, updatedAt);
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubIssue.class)) {
return (T)createIssue();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -24,7 +24,7 @@ import java.util.Date;
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubPullRequestRaw implements DataConstructor<GithubPullRequest> {
class GithubPullRequestRaw implements DataConstructor {
@Nullable public Long number;
@Nullable public String state;
@Nullable public String title;
@@ -55,7 +55,7 @@ class GithubPullRequestRaw implements DataConstructor<GithubPullRequest> {
@Nullable public LinkRaw head;
@Nullable public LinkRaw base;
public static class LinkRaw implements DataConstructor<GithubPullRequest.Link> {
public static class LinkRaw {
@Nullable public String label;
@Nullable public String ref;
@Nullable public String sha;
@@ -64,16 +64,25 @@ class GithubPullRequestRaw implements DataConstructor<GithubPullRequest> {
@Nullable public GithubUserRaw user;
@NotNull
@Override
public GithubPullRequest.Link create() {
return new GithubPullRequest.Link(label, ref, sha, repo.create(), user.create());
return new GithubPullRequest.Link(label, ref, sha, repo.createRepo(), user.createUser());
}
}
@NotNull
@Override
public GithubPullRequest create() {
public GithubPullRequest createPullRequest() {
return new GithubPullRequest(number, state, title, body, htmlUrl, diffUrl, patchUrl, issueUrl, createdAt, updatedAt, closedAt, mergedAt,
user.create(), head.create(), base.create());
user.createUser(), head.create(), base.create());
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubPullRequest.class)) {
return (T)createPullRequest();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -24,8 +24,8 @@ import java.util.Date;
/**
* @author Aleksey Pivovarov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubRepoRaw implements DataConstructor<GithubRepo>, DataConstructorDetailed<GithubRepoDetailed> {
@SuppressWarnings("UnusedDeclaration")
class GithubRepoRaw implements DataConstructor {
@Nullable public Long id;
@Nullable public String name;
@Nullable public String fullName;
@@ -72,16 +72,31 @@ class GithubRepoRaw implements DataConstructor<GithubRepo>, DataConstructorDetai
@Nullable public Date createdAt;
@Nullable public Date updatedAt;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubRepo create() {
return new GithubRepo(name, fullName, description, isPrivate, isFork, htmlUrl, cloneUrl, defaultBranch, owner.create());
public GithubRepo createRepo() {
return new GithubRepo(name, fullName, description, isPrivate, isFork, htmlUrl, cloneUrl, defaultBranch, owner.createUser());
}
@SuppressWarnings("ConstantConditions")
@NotNull
public GithubRepoDetailed createRepoDetailed() {
GithubRepo parent = this.parent == null ? null : this.parent.createRepo();
return new GithubRepoDetailed(name, fullName, description, isPrivate, isFork, htmlUrl, cloneUrl, defaultBranch, owner.createUser(),
parent);
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public GithubRepoDetailed createDetailed() {
GithubRepo parent = this.parent == null ? null : this.parent.create();
return new GithubRepoDetailed(name, fullName, description, isPrivate, isFork, htmlUrl, cloneUrl, defaultBranch, owner.create(), parent);
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubRepo.class)) {
return (T)createRepo();
}
if (resultClass.isAssignableFrom(GithubRepoDetailed.class)) {
return (T)createRepoDetailed();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}
@@ -25,8 +25,8 @@ import java.util.Date;
*
* @author Kirill Likhodedov
*/
@SuppressWarnings({"UnusedDeclaration", "ConstantConditions"})
class GithubUserRaw implements DataConstructor<GithubUser>, DataConstructorDetailed<GithubUserDetailed> {
@SuppressWarnings("UnusedDeclaration")
class GithubUserRaw implements DataConstructor {
@Nullable public String login;
@Nullable public Long id;
@@ -58,28 +58,42 @@ class GithubUserRaw implements DataConstructor<GithubUser>, DataConstructorDetai
@Nullable public Date createdAt;
public static class UserPlanRaw implements DataConstructor<GithubUserDetailed.UserPlan> {
public static class UserPlanRaw {
@Nullable public String name;
@Nullable public Long space;
@Nullable public Long collaborators;
@Nullable public Long privateRepos;
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubUserDetailed.UserPlan create() {
return new GithubUserDetailed.UserPlan(name, privateRepos);
}
}
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubUser create() {
public GithubUser createUser() {
return new GithubUser(login, htmlUrl, gravatarId);
}
@SuppressWarnings("ConstantConditions")
@NotNull
@Override
public GithubUserDetailed createDetailed() {
public GithubUserDetailed createUserDetailed() {
return new GithubUserDetailed(login, htmlUrl, gravatarId, name, email, ownedPrivateRepos, type, plan.create());
}
@SuppressWarnings("unchecked")
@NotNull
@Override
public <T> T create(@NotNull Class<T> resultClass) {
if (resultClass.isAssignableFrom(GithubUser.class)) {
return (T)createUser();
}
if (resultClass.isAssignableFrom(GithubUserDetailed.class)) {
return (T)createUserDetailed();
}
throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
}
}