Skip to content

Commit e7f1705

Browse files
committed
First 2.0 pass
- Consolidate all JSON deserialization into the request class - Add support for metadata and relationships - Remove all deprecated items - Better support for single vs array return objects - Improve API for core objects
1 parent 398fb6a commit e7f1705

File tree

74 files changed

+916
-1188
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+916
-1188
lines changed

build.gradle

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
apply plugin: 'maven'
2-
apply plugin: 'java'
3-
apply plugin: 'eclipse'
4-
apply plugin: 'idea'
5-
61
buildscript {
72
repositories {
83
mavenCentral()
@@ -12,6 +7,14 @@ buildscript {
127
}
138
}
149

10+
plugins {
11+
id 'java'
12+
id 'maven'
13+
id 'eclipse'
14+
id 'idea'
15+
id 'net.franz-becker.gradle-lombok' version '1.5'
16+
}
17+
1518
archivesBaseName = "creatubbles-wsapi"
1619
group = 'com.creatubbles.api'
1720
description = "WS API for Creatubbles"
@@ -42,6 +45,19 @@ dependencies {
4245
compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.22.1'
4346
}
4447

48+
lombok {
49+
version = "1.16.8"
50+
sha256 = "fe32b29b7b33eb2b19866cbc5345c59c9984a6036cc396856a04c0d09f99ea68"
51+
}
52+
53+
import net.franz_becker.gradle.lombok.task.DelombokTask
54+
55+
task delombok(type: DelombokTask) {
56+
args("src/main/java", "-d", "build/sources/delomboked/java")
57+
}
58+
59+
tasks.eclipse.dependsOn installLombok
60+
4561
task sourceJar(type: Jar) {
4662
from sourceSets.main.allSource
4763
classifier = 'sources'

lombok.config

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
config.stopBubbling = true
2+
lombok.equalsAndHashCode.callSuper = call

src/main/java/com/creatubbles/api/CreatubblesAPI.java

+76-37
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,47 @@
44
import java.io.IOException;
55
import java.lang.reflect.Type;
66
import java.nio.file.Files;
7+
import java.util.Map.Entry;
78

89
import org.glassfish.jersey.client.ClientProperties;
910
import org.glassfish.jersey.client.JerseyClient;
1011
import org.glassfish.jersey.client.JerseyClientBuilder;
1112

12-
import com.creatubbles.api.core.Gallery;
1313
import com.creatubbles.api.core.LandingUrl;
1414
import com.creatubbles.api.request.amazon.UploadS3FileRequest;
1515
import com.creatubbles.api.request.creation.CreateCreationRequest;
1616
import com.creatubbles.api.request.creation.CreationsUploadsRequest;
1717
import com.creatubbles.api.request.creation.PingCreationsUploadsRequest;
1818
import com.creatubbles.api.request.landingurls.GetLandingUrlsRequest;
1919
import com.creatubbles.api.request.landingurls.GetSpecificLandingUrlRequest;
20-
import com.creatubbles.api.response.auth.SignUpResponse;
2120
import com.creatubbles.api.response.creation.CreateCreationResponse;
2221
import com.creatubbles.api.response.creation.CreationsUploadsResponse;
23-
import com.creatubbles.api.response.creation.GetCreationsResponse;
24-
import com.creatubbles.api.response.creator.CreateCreatorResponse;
25-
import com.creatubbles.api.response.creator.GetCreatorsResponse;
26-
import com.creatubbles.api.response.gallery.CreateUserGalleryResponse;
27-
import com.creatubbles.api.response.landingurls.GetCreationLandingUrlResponse;
2822
import com.creatubbles.api.response.landingurls.GetLandingUrlsResponse;
2923
import com.creatubbles.api.response.landingurls.GetSpecificLandingUrlResponse;
30-
import com.creatubbles.api.response.user.UserProfileResponse;
31-
import com.creatubbles.api.util.EndPoints;
3224
import com.creatubbles.api.util.HttpUtil;
3325
import com.google.gson.Gson;
3426
import com.google.gson.GsonBuilder;
3527
import com.google.gson.JsonDeserializationContext;
3628
import com.google.gson.JsonDeserializer;
3729
import com.google.gson.JsonElement;
30+
import com.google.gson.JsonObject;
3831
import com.google.gson.JsonParseException;
32+
import com.google.gson.TypeAdapter;
33+
import com.google.gson.TypeAdapterFactory;
34+
import com.google.gson.reflect.TypeToken;
35+
import com.google.gson.stream.JsonReader;
36+
import com.google.gson.stream.JsonWriter;
3937

4038

41-
@SuppressWarnings("deprecation")
4239
public class CreatubblesAPI {
40+
41+
42+
public static final String URL_BASE = "https://api.creatubbles.com/v2/";
43+
public static final String URL_BASE_STAGING = "https://api.staging.creatubbles.com/v2/";
44+
4345
public final static Gson GSON = new GsonBuilder()
44-
.registerTypeAdapter(SignUpResponse.class, new SignUpResponse())
45-
.registerTypeAdapter(UserProfileResponse.class, new UserProfileResponse())
46-
.registerTypeAdapter(CreateCreatorResponse.class, new CreateCreatorResponse())
47-
.registerTypeAdapter(CreateUserGalleryResponse.class, new CreateUserGalleryResponse())
48-
.registerTypeAdapter(CreateUserGalleryResponse.class, new CreateUserGalleryResponse())
49-
.registerTypeAdapter(Gallery.class, new Gallery())
50-
.registerTypeAdapter(GetCreatorsResponse.class, new GetCreatorsResponse())
51-
.registerTypeAdapter(GetCreationsResponse.class, new GetCreationsResponse())
52-
.registerTypeAdapter(CreateCreationResponse.class, new CreateCreationResponse())
53-
.registerTypeAdapter(CreationsUploadsResponse.class, new CreationsUploadsResponse())
54-
.registerTypeAdapter(GetLandingUrlsResponse.class, new GetLandingUrlsResponse())
55-
.registerTypeAdapter(GetSpecificLandingUrlResponse.class, new GetSpecificLandingUrlResponse())
56-
.registerTypeAdapter(GetCreationLandingUrlResponse.class, new GetCreationLandingUrlResponse())
5746
.registerTypeAdapter(String.class, new StringAdapter())
47+
.registerTypeAdapterFactory(new JsonHackx())
5848
.create();
5949

6050
public final static JerseyClient CLIENT = JerseyClientBuilder
@@ -63,11 +53,12 @@ public class CreatubblesAPI {
6353
.property(ClientProperties.READ_TIMEOUT, 5000)
6454
.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, Boolean.TRUE);
6555

66-
public static String buildURL(final String endPoint) {
56+
public static String buildURL(final Object end) {
57+
String endPoint = end.toString();
6758
if (endPoint.startsWith("https://")) {
6859
return endPoint;
6960
}
70-
String base = staging ? EndPoints.URL_BASE_STAGING : EndPoints.URL_BASE;
61+
String base = staging ? URL_BASE_STAGING : URL_BASE;
7162
return base.concat(endPoint);
7263
}
7364

@@ -77,6 +68,10 @@ public static void setStagingMode(boolean staging) {
7768
CreatubblesAPI.staging = staging;
7869
}
7970

71+
public static boolean stagingModeEnabled() {
72+
return staging;
73+
}
74+
8075
public static void main(String[] args) throws IOException {
8176
// Additional examples can be found in the JUnit test files
8277

@@ -85,38 +80,38 @@ public static void main(String[] args) throws IOException {
8580

8681
CreateCreationRequest createCreation = new CreateCreationRequest(accessToken);
8782
CreateCreationResponse createCreationResponse = createCreation.execute().getResponse();
88-
System.out.println(createCreationResponse.creation.id);
83+
System.out.println(createCreationResponse.getCreation().getId());
8984

9085
File file = new File("C:/dev/1.png");
9186
String extension = HttpUtil.getExtension(file.getPath());
9287

93-
CreationsUploadsRequest creationsUploads = new CreationsUploadsRequest(createCreationResponse.creation.id, extension, accessToken);
88+
CreationsUploadsRequest creationsUploads = new CreationsUploadsRequest(createCreationResponse.getCreation().getId(), extension, accessToken);
9489
CreationsUploadsResponse creationsUploadsResponse = creationsUploads.execute().getResponse();
95-
System.out.println(creationsUploadsResponse.url);
96-
System.out.println(creationsUploadsResponse.id);
90+
System.out.println(creationsUploadsResponse.getUrl());
91+
System.out.println(creationsUploadsResponse.getId());
9792

9893
GetLandingUrlsRequest getLandingUrls = new GetLandingUrlsRequest(accessToken);
99-
for (LandingUrl landingUrl : getLandingUrls.execute().getResponse().urls) {
100-
System.out.println(landingUrl.type + ":" + landingUrl.url);
94+
for (GetLandingUrlsResponse landingUrl : getLandingUrls.execute().getResponseList()) {
95+
System.out.println(landingUrl.getUrl().getType() + ":" + landingUrl.getUrl().getUrl());
10196
}
10297

10398
GetSpecificLandingUrlRequest getSpecificLandingUrl = new GetSpecificLandingUrlRequest(accessToken, LandingUrl.LandingUrlType.CTB_USER_PROFILE);
10499
GetSpecificLandingUrlResponse getSpecificLandingUrlResponse = getSpecificLandingUrl.execute().getResponse();
105-
LandingUrl url = getSpecificLandingUrlResponse.url;
106-
System.out.println("specific url - " + url.type + ":" + url.url);
100+
LandingUrl url = getSpecificLandingUrlResponse.getUrl();
101+
System.out.println("specific url - " + url.getType() + ":" + url.getUrl());
107102

108103
byte[] data = Files.readAllBytes(file.toPath());
109104

110-
UploadS3FileRequest uploadS3Image = new UploadS3FileRequest(data, creationsUploadsResponse.url, creationsUploadsResponse.content_type);
105+
UploadS3FileRequest uploadS3Image = new UploadS3FileRequest(data, creationsUploadsResponse.getUrl(), creationsUploadsResponse.getType());
111106
uploadS3Image.execute().getResponse();
112107

113-
PingCreationsUploadsRequest pingCreationsUploads = new PingCreationsUploadsRequest(creationsUploadsResponse.ping_url, accessToken);
108+
PingCreationsUploadsRequest pingCreationsUploads = new PingCreationsUploadsRequest(creationsUploadsResponse.getPingUrl(), accessToken);
114109
pingCreationsUploads.setData("");
115110
pingCreationsUploads.execute().getResponse();
116111
System.out.println("-Finish-");
117112
}
118113

119-
static class StringAdapter implements JsonDeserializer<String> {
114+
private static class StringAdapter implements JsonDeserializer<String> {
120115

121116
public String deserialize(JsonElement json, Type typeOfT,
122117
JsonDeserializationContext context)
@@ -125,5 +120,49 @@ public String deserialize(JsonElement json, Type typeOfT,
125120
return asString != null && asString.isEmpty() ? null : asString;
126121
}
127122
}
128-
123+
124+
private static class JsonHackx implements TypeAdapterFactory {
125+
126+
@Override
127+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
128+
129+
final TypeAdapter<T> adapter = gson.getDelegateAdapter(this, type);
130+
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
131+
132+
TypeAdapter<T> result = new TypeAdapter<T>() {
133+
134+
@Override
135+
public void write(JsonWriter out, T value) throws IOException {
136+
JsonObject object = adapter.toJsonTree(value).getAsJsonObject();
137+
elementAdapter.write(out, object);
138+
}
139+
140+
@Override public T read(JsonReader in) throws IOException {
141+
JsonElement e = elementAdapter.read(in);
142+
143+
// Enter into all "data" fields immediately
144+
if (e.isJsonObject() && e.getAsJsonObject().has("data")) {
145+
e = e.getAsJsonObject().get("data");
146+
}
147+
148+
// Add all "attributes" fields to the parent object so they are accessible without indirection
149+
// Yeah this is a massive hack but it is necessary for things like landing URLs which only
150+
// serve a single string inside the attributes
151+
if (e.isJsonObject()) {
152+
JsonObject obj = e.getAsJsonObject();
153+
if (obj.has("attributes")) {
154+
JsonObject attr = obj.get("attributes").getAsJsonObject();
155+
for (Entry<String, JsonElement> entry : attr.entrySet()) {
156+
obj.add(entry.getKey(), entry.getValue());
157+
}
158+
}
159+
}
160+
161+
return adapter.fromJsonTree(e);
162+
}
163+
}.nullSafe(); // so we don't have to check for null on the stream
164+
165+
return result;
166+
}
167+
}
129168
}

src/main/java/com/creatubbles/api/core/Country.java

-5
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,59 @@
11
package com.creatubbles.api.core;
22

3-
public class Creation {
3+
import java.util.HashMap;
44

5-
public String id, user_id;
6-
public String[] creator_ids;
7-
public String name, created_at, created_at_age;
8-
public int created_at_month, created_at_year, comments_count, bubble_count, views_count;
9-
public String last_bubbled_at, last_commented_at, last_submitted_at;
10-
public Image image;
11-
public String short_url;
12-
public boolean approved;
5+
import jersey.repackaged.com.google.common.collect.Maps;
6+
import lombok.AccessLevel;
7+
import lombok.Getter;
8+
import lombok.ToString;
9+
import lombok.Value;
1310

14-
@Deprecated
15-
public Creator[] creators;
16-
/**
17-
* @see #short_url
18-
* @see Image#links
19-
*/
20-
@Deprecated
21-
public String store_dir;
22-
/**
23-
* @see #short_url
24-
* @see Image#links
25-
*/
26-
@Deprecated
27-
public String url;
11+
import com.google.gson.annotations.SerializedName;
12+
13+
@Value
14+
@ToString(callSuper = true)
15+
public class Creation extends CreatubblesObject {
16+
17+
String name;
18+
@SerializedName("created_at")
19+
String createdDate;
20+
@SerializedName("created_at_age")
21+
String createdAge;
22+
23+
@Getter(value = AccessLevel.NONE)
24+
@SerializedName("created_at_age_per_creator")
25+
HashMap<String, String> creatorToAgeMap = Maps.newHashMap();
26+
27+
public String getCreatedAge(String creatorId) {
28+
return creatorToAgeMap.get(creatorId);
29+
}
30+
31+
public String getCreatedAge(User creator) {
32+
return getCreatedAge(creator.getId());
33+
}
34+
35+
@SerializedName("created_at_month")
36+
int createdMonth;
37+
@SerializedName("created_at_year")
38+
int createdYear;
39+
@SerializedName("comments_count")
40+
int commentCount;
41+
@SerializedName("bubble_count")
42+
int bubbleCount;
43+
@SerializedName("views_count")
44+
int viewCount;
45+
46+
@SerializedName("last_bubbled_at")
47+
String lastBubbleDate;
48+
@SerializedName("last_commented_at")
49+
String lastCommentDate;
50+
@SerializedName("last_submitted_at")
51+
String lastSubmitDate;
52+
53+
Image image;
54+
55+
@SerializedName("short_url")
56+
String shortUrl;
57+
58+
boolean approved;
2859
}

src/main/java/com/creatubbles/api/core/Creator.java

-16
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.creatubbles.api.core;
2+
3+
import lombok.Data;
4+
5+
@Data
6+
public class CreatubblesObject {
7+
8+
private String type;
9+
private String id;
10+
}

0 commit comments

Comments
 (0)