From df31a6f6ef81c10de0759bb006c99c950f0ed64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Mon, 25 Jun 2018 22:58:12 +0200 Subject: [PATCH 1/9] Merge branch 'master' into develop --- .gradle/4.4/fileChanges/last-build.bin | Bin 0 -> 1 bytes .gradle/4.4/fileHashes/fileHashes.bin | Bin 0 -> 18797 bytes .gradle/4.4/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .gradle/4.4/taskHistory/taskHistory.bin | Bin 0 -> 19630 bytes .gradle/4.4/taskHistory/taskHistory.lock | Bin 0 -> 17 bytes .../buildOutputCleanup.lock | Bin 0 -> 17 bytes .gradle/buildOutputCleanup/cache.properties | 2 + .gradle/buildOutputCleanup/outputFiles.bin | Bin 0 -> 18731 bytes gradle/wrapper/gradle-wrapper.properties | 5 + pom.xml | 2 +- .../bananaj/connection/Connection.java | 417 +++++++----------- .../bananaj/model/list/MailChimpList.java | 4 +- .../bananaj/model/list/member/Member.java | 6 +- 13 files changed, 168 insertions(+), 268 deletions(-) create mode 100644 .gradle/4.4/fileChanges/last-build.bin create mode 100644 .gradle/4.4/fileHashes/fileHashes.bin create mode 100644 .gradle/4.4/fileHashes/fileHashes.lock create mode 100644 .gradle/4.4/taskHistory/taskHistory.bin create mode 100644 .gradle/4.4/taskHistory/taskHistory.lock create mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 .gradle/buildOutputCleanup/cache.properties create mode 100644 .gradle/buildOutputCleanup/outputFiles.bin create mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/.gradle/4.4/fileChanges/last-build.bin b/.gradle/4.4/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/.gradle/4.4/fileHashes/fileHashes.bin b/.gradle/4.4/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..cb7cefa9e7985f1afca957b66b6336117f0cb5b1 GIT binary patch literal 18797 zcmeI(%PT}t0LSq&Lf(ePBMUVYO*2W6nv^JNri6_o%))CUNt6h&U=}jvH5(R)A}J+{ zDQjjSN{WR>StygTFblEZT<6|A=0DK))ZBCK@6K)(9iBREkb$E1M1d9;FKa literal 0 HcmV?d00001 diff --git a/.gradle/4.4/fileHashes/fileHashes.lock b/.gradle/4.4/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..0d10b295fe32442c0488a6b62f114ce3bb1bcde2 GIT binary patch literal 17 UcmZQ}&RvsIFF|90%}uj*vxvrb8%19U_8IXM{A$o3dLPR-&z&AR@l$9bCI4WDxOv%gnx+_xAmM@AKZw zWh0taWvmp7wpw2emrIT`3}*VB2AWC?^=C4}TKQyx`gW?*7ToiRMqUytCYg{H zO|uc2b(qLAE~OQ5?cof|`qF9_Zc@-phG&!337VtodVtxgAwje1GhnG!C(ZJv8dx{> z9=$x)y|Va`8S@L{Umwg7a%F&uV?51NuumHm%*qSuc}x^z*A_2L6-qap-tU$1mT23A zHs1PvZ0J5A)1GiuZ=W++%w*|rXR;bmHx4|%W?${S`R&!+rMam$gLep-kU#y4$-LO8 zWb(REy}TIj`7l?r;BMb{duKffit&2S#z1@281Hb|FxJtzx(R5hvh3;zM)n9HRA literal 0 HcmV?d00001 diff --git a/.gradle/4.4/taskHistory/taskHistory.lock b/.gradle/4.4/taskHistory/taskHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..4933c7eef3992440a1280da026a85f4d08d35fbc GIT binary patch literal 17 UcmZR6tG{gXN2T<43=qH!06i%LF06qN$4*&oF literal 0 HcmV?d00001 diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..d6ce19f --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Mon Apr 23 19:34:34 CEST 2018 +gradle.version=4.4 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..83d61f58b544166927a80c233ab59abaeea3b169 GIT binary patch literal 18731 zcmeI%KPZG@9KiACL^yxWBFCV_pirbp43xnw60zKJiwrkmIEpjfaGkq_?dnF0ZqTI& z-Kax!=`8A^LotxSV9@J*d!JvIWR>)N>v`U%@AKCCKA-g+Rmxpw=t~u^`r?um0tg_0 z00IagfB*srAbAWr)*?#>cx;R-0#U2QIEB0g8cK;QF~ zy*)N7{|{ojsnmJtc8l(B(ht35%`2goW4n7Ar5}B44Ne4JPxbRt(l5e2i<3j`LEQt= zFP%623rlMqx+kUQ{9V4_bta^HSh|t+MNiHWx4NgLSL`>%lKF=X-AAOi-5c-TNFlC! zT>8w;x_^8wlhZvbeg5$vyLXqU(!C&kHQ%~9{IndkyQf^b+?8^8>^)`#5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009JkN1)ey WO{F;;*0849FU1UhynO%WAIc}ErNJ=( literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..933b647 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip diff --git a/pom.xml b/pom.xml index 5dc3aad..e44ddb5 100755 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.alexanderwe bananaj - 1.2.5-alpha + 0.5.0 jar bananaj diff --git a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java index 07a346b..baae606 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java +++ b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java @@ -1,25 +1,17 @@ package com.github.alexanderwe.bananaj.connection; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - +import com.github.alexanderwe.bananaj.exceptions.TransportException; import org.apache.http.HttpEntity; import org.apache.http.client.entity.EntityBuilder; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPatch; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.*; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; -import com.github.alexanderwe.bananaj.exceptions.TransportException; +import java.io.*; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; /** * Created by Alexander on 10.08.2016. @@ -27,254 +19,149 @@ public class Connection { - public String do_Get(URL url, String authorization) throws TransportException { - CloseableHttpClient httpclient = null; - CloseableHttpResponse response = null; - InputStream entityStream = null; - - try { - httpclient = HttpClients.createDefault(); - HttpGet httpget = new HttpGet(url.toURI()); - httpget.addHeader("Authorization", authorization); - response = httpclient.execute(httpget); - - int responseCode = response.getStatusLine().getStatusCode(); - //System.out.println("\nSending 'GET' request to URL : " + url); - //System.out.println("Response Code : " + responseCode + "\n"); - if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); - } - - HttpEntity entity = response.getEntity(); - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } catch (Exception e) { - throw new TransportException("GET " + url.toExternalForm() + " failed", e); - } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} - } - } - - public String do_Post(URL url, String post_string, String authorization) throws TransportException { - CloseableHttpClient httpclient = null; - CloseableHttpResponse response = null; - InputStream entityStream = null; - - try { - httpclient = HttpClients.createDefault(); - HttpPost httppost = new HttpPost(url.toURI()); - httppost.addHeader("Authorization", authorization); - httppost.addHeader("Content-Type", "application/json; charset=UTF-8"); - httppost.setEntity(EntityBuilder.create().setText(post_string).build()); - response = httpclient.execute(httppost); - - int responseCode = response.getStatusLine().getStatusCode(); - //System.out.println("\nSending 'POST' request to URL : " + url + System.lineSeparator() + "Send data: " + (post_string.length() > 500 ? post_string.substring(0, 500)+"..." : post_string)); - //System.out.println("Response Code : " + responseCode + "\n"); - if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); - } - - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { - throw new TransportException("POST " + post_string.length() + " bytes to " + url.toExternalForm() + " failed", e); - } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} - } - } - - public String do_Patch(URL url, String patch_string, String authorization) throws TransportException { - CloseableHttpClient httpclient = null; - CloseableHttpResponse response = null; - InputStream entityStream = null; - - try { - httpclient = HttpClients.createDefault(); - HttpPatch httppatch = new HttpPatch(url.toURI()); - httppatch.addHeader("Authorization", authorization); - httppatch.addHeader("Content-Type", "application/json; charset=UTF-8"); - httppatch.setEntity(EntityBuilder.create().setText(patch_string).build()); - response = httpclient.execute(httppatch); - - int responseCode = response.getStatusLine().getStatusCode(); - //System.out.println("\nSending 'PATCH' request to URL : " + url + System.lineSeparator() + "Send data: " + (patch_string.length() > 500 ? patch_string.substring(0, 500)+"..." : patch_string)); - //System.out.println("Response Code : " + responseCode + "\n"); - if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); - } - - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { - throw new TransportException("PATCH " + patch_string.length() + " bytes to " + url.toExternalForm() + " failed", e); - } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} - } - } - - public String do_Put(URL url, String put_string, String authorization) throws TransportException { - CloseableHttpClient httpclient = null; - CloseableHttpResponse response = null; - InputStream entityStream = null; - - try { - httpclient = HttpClients.createDefault(); - HttpPut httpput = new HttpPut(url.toURI()); - httpput.addHeader("Authorization", authorization); - httpput.addHeader("Content-Type", "application/json; charset=UTF-8"); - httpput.setEntity(EntityBuilder.create().setText(put_string).build()); - response = httpclient.execute(httpput); - - int responseCode = response.getStatusLine().getStatusCode(); - //System.out.println("\nSending 'PUT' request to URL : " + url + System.lineSeparator() + "Send data: " + (put_string.length() > 500 ? put_string.substring(0, 500)+"..." : put_string)); - //System.out.println("Response Code : " + responseCode + "\n"); - if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); - } - - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { - throw new TransportException("PUT " + put_string.length() + " bytes to " + url.toExternalForm() + " failed", e); - } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} - } - } - - public String do_Post(URL url, String authorization) throws TransportException { - CloseableHttpClient httpclient = null; - CloseableHttpResponse response = null; - InputStream entityStream = null; - - try { - httpclient = HttpClients.createDefault(); - HttpPost httppost = new HttpPost(url.toURI()); - httppost.addHeader("Authorization", authorization); - httppost.addHeader("Content-Type", "application/json; charset=UTF-8"); - response = httpclient.execute(httppost); - - int responseCode = response.getStatusLine().getStatusCode(); - //System.out.println("\nSending 'POST' request to URL : " + url); - //System.out.println("Response Code : " + responseCode + "\n"); - if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); - } - - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { - throw new TransportException("POST " + url.toExternalForm() + " failed", e); - } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} - } - } - - public String do_Delete(URL url, String authorization) throws TransportException { - CloseableHttpClient httpclient = null; - CloseableHttpResponse response = null; - InputStream entityStream = null; - - try { - httpclient = HttpClients.createDefault(); - HttpDelete httpdelete = new HttpDelete(url.toURI()); - httpdelete.addHeader("Authorization", authorization); - httpdelete.addHeader("Content-Type", "application/json; charset=UTF-8"); - response = httpclient.execute(httpdelete); - - int responseCode = response.getStatusLine().getStatusCode(); - //System.out.println("\nSending 'DELETE' request to URL : " + url); - //System.out.println("Response Code : " + responseCode + "\n"); - if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); - } - - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { - throw new TransportException("DELETE " + url.toExternalForm() + " failed", e); - } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} - } - } + public String do_Get(URL url, String authorization) throws TransportException, URISyntaxException { + CloseableHttpClient httpclient; + + HttpGet httpget = new HttpGet(url.toURI()); + httpget.addHeader("Authorization", authorization); + httpclient = HttpClients.createDefault(); + try (CloseableHttpResponse response = httpclient.execute(httpget)) { + + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode < 200 || responseCode > 299) { + throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + } + + return createResponseFromEntity(response.getEntity()); + } catch (Exception e) { + throw new TransportException("GET " + url.toExternalForm() + " failed", e); + } + } + + public String do_Post(URL url, String post_string, String authorization) throws TransportException, URISyntaxException { + CloseableHttpClient httpclient; + + HttpPost httppost = new HttpPost(url.toURI()); + httppost.setEntity(EntityBuilder.create().setText(post_string).build()); + httppost.addHeader("Content-Type", "application/json; charset=UTF-8"); + httppost.addHeader("Authorization", authorization); + + httpclient = HttpClients.createDefault(); + try (CloseableHttpResponse response = httpclient.execute(httppost)) { + + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode < 200 || responseCode > 299) { + throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + } + + return createResponseFromEntity(response.getEntity()); + } catch (Exception e) { + throw new TransportException("POST " + post_string.length() + " bytes to " + url.toExternalForm() + " failed", e); + } + } + + public String do_Patch(URL url, String patch_string, String authorization) throws TransportException, URISyntaxException { + CloseableHttpClient httpclient; + + HttpPatch httppatch = new HttpPatch(url.toURI()); + httppatch.setEntity(EntityBuilder.create().setText(patch_string).build()); + httppatch.addHeader("Content-Type", "application/json; charset=UTF-8"); + httppatch.addHeader("Authorization", authorization); + + httpclient = HttpClients.createDefault(); + try (CloseableHttpResponse response = httpclient.execute(httppatch)) { + + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode < 200 || responseCode > 299) { + throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + } + + return createResponseFromEntity(response.getEntity()); + } catch (Exception e) { + throw new TransportException("PATCH " + patch_string.length() + " bytes to " + url.toExternalForm() + " failed", e); + } + } + + public String do_Put(URL url, String put_string, String authorization) throws TransportException, URISyntaxException { + CloseableHttpClient httpclient; + + HttpPut httpput = new HttpPut(url.toURI()); + httpput.setEntity(EntityBuilder.create().setText(put_string).build()); + httpput.addHeader("Content-Type", "application/json; charset=UTF-8"); + httpput.addHeader("Authorization", authorization); + + httpclient = HttpClients.createDefault(); + try (CloseableHttpResponse response = httpclient.execute(httpput)) { + + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode < 200 || responseCode > 299) { + throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + } + + return createResponseFromEntity(response.getEntity()); + } catch (Exception e) { + throw new TransportException("PUT " + put_string.length() + " bytes to " + url.toExternalForm() + " failed", e); + } + } + + public String do_Post(URL url, String authorization) throws TransportException, URISyntaxException { + CloseableHttpClient httpclient = null; + + HttpPost httppost = new HttpPost(url.toURI()); + httppost.addHeader("Content-Type", "application/json; charset=UTF-8"); + httppost.addHeader("Authorization", authorization); + httpclient = HttpClients.createDefault(); + + try (CloseableHttpResponse response = httpclient.execute(httppost)) { + + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode < 200 || responseCode > 299) { + throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + } + + return createResponseFromEntity(response.getEntity()); + } catch (Exception e) { + throw new TransportException("POST " + url.toExternalForm() + " failed", e); + } + } + + public String do_Delete(URL url, String authorization) throws TransportException, URISyntaxException { + CloseableHttpClient httpclient; + + HttpDelete httpdelete = new HttpDelete(url.toURI()); + httpdelete.addHeader("Content-Type", "application/json; charset=UTF-8"); + httpdelete.addHeader("Authorization", authorization); + + httpclient = HttpClients.createDefault(); + try (CloseableHttpResponse response = httpclient.execute(httpdelete)) { + + int responseCode = response.getStatusLine().getStatusCode(); + if (responseCode < 200 || responseCode > 299) { + throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + } + + return createResponseFromEntity(response.getEntity()); + } catch (Exception e) { + throw new TransportException("DELETE " + url.toExternalForm() + " failed", e); + } + } + + + private String createResponseFromEntity(HttpEntity entity) throws IOException { + InputStream entityStream; + if (entity != null) { + long length = entity.getContentLength(); + entityStream = entity.getContent(); + StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int) length : 200); + try (Reader reader = new BufferedReader(new InputStreamReader + (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { + int c = 0; + while ((c = reader.read()) != -1) { + strbuilder.append((char) c); + } + } + return strbuilder.toString(); + } + return null; + } } diff --git a/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java b/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java index ac3f24f..de466bf 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java +++ b/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java @@ -269,13 +269,15 @@ public void addMember(MemberStatus status, String emailAddress, HashMap pair = it.next(); it.remove(); // avoids a ConcurrentModificationException - merge_fields.put(pair.getKey().toString(), pair.getValue()); + merge_fields.put(pair.getKey(), pair.getValue()); } member.put("status", status.getStringRepresentation()); member.put("email_address", emailAddress); member.put("merge_fields", merge_fields); + System.out.println(member.toString()); getConnection().do_Post(url,member.toString(),connection.getApikey()); + this.membercount++; } diff --git a/src/main/java/com/github/alexanderwe/bananaj/model/list/member/Member.java b/src/main/java/com/github/alexanderwe/bananaj/model/list/member/Member.java index a72b20c..e6648e7 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/model/list/member/Member.java +++ b/src/main/java/com/github/alexanderwe/bananaj/model/list/member/Member.java @@ -115,7 +115,11 @@ public Member(String id, MailChimpList mailChimpList, HashMap me this.memberInterest = new HashMap(); this.connection = connection; } - + + public Member() { + + } + /** * Update the mailChimpList of this member * @param listId From ef08368e756d1c361baffb941ed99684365e52ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Mon, 25 Jun 2018 23:04:10 +0200 Subject: [PATCH 2/9] Add jsonError to TransportError.class Make Connection.class lighter --- .gitignore | 2 +- .../bananaj/connection/Connection.java | 12 ++++++------ .../bananaj/exceptions/TransportException.java | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index b6bca6e..feef80a 100755 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,5 @@ target/ .DS_Store # Project -Test.java +src/test/Test.java src/test/* diff --git a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java index baae606..d2e5622 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java +++ b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java @@ -29,7 +29,7 @@ public String do_Get(URL url, String authorization) throws TransportException, U int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); } return createResponseFromEntity(response.getEntity()); @@ -51,7 +51,7 @@ public String do_Post(URL url, String post_string, String authorization) throws int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); } return createResponseFromEntity(response.getEntity()); @@ -73,7 +73,7 @@ public String do_Patch(URL url, String patch_string, String authorization) throw int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); } return createResponseFromEntity(response.getEntity()); @@ -95,7 +95,7 @@ public String do_Put(URL url, String put_string, String authorization) throws Tr int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); } return createResponseFromEntity(response.getEntity()); @@ -116,7 +116,7 @@ public String do_Post(URL url, String authorization) throws TransportException, int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); } return createResponseFromEntity(response.getEntity()); @@ -137,7 +137,7 @@ public String do_Delete(URL url, String authorization) throws TransportException int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity())); + throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); } return createResponseFromEntity(response.getEntity()); diff --git a/src/main/java/com/github/alexanderwe/bananaj/exceptions/TransportException.java b/src/main/java/com/github/alexanderwe/bananaj/exceptions/TransportException.java index 8b08cfe..22ad86b 100644 --- a/src/main/java/com/github/alexanderwe/bananaj/exceptions/TransportException.java +++ b/src/main/java/com/github/alexanderwe/bananaj/exceptions/TransportException.java @@ -3,12 +3,17 @@ */ package com.github.alexanderwe.bananaj.exceptions; +import org.json.JSONObject; + /** * @author USCRIGA * */ public class TransportException extends Exception { + + private JSONObject jsonError; + /** * */ @@ -23,6 +28,16 @@ public TransportException(String message) { super(message); } + /** + * @param message the detail message + * @param jsonError JSON string of the Mailchimp error message + */ + public TransportException(String message, String jsonError) { + super(message); + this.jsonError = new JSONObject(jsonError); + + } + /** * @param cause the cause. (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ From 4f016470a71704db940dd9e5e8dbddd2dc5f1802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Mon, 25 Jun 2018 23:19:40 +0200 Subject: [PATCH 3/9] Change gitignore --- .gitignore | 154 ++++++++++++++++++----- gradle/wrapper/gradle-wrapper.properties | 5 - 2 files changed, 124 insertions(+), 35 deletions(-) delete mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/.gitignore b/.gitignore index feef80a..bc75bc3 100755 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,129 @@ -# IntelliJ -*.iml -*.ipr +# Created by https://www.gitignore.io/api/macos,maven,gradle,intellij + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format *.iws -.idea/ - -# Eclipse -.settings -.classpath -.project -.metadata -*.launch -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib - -# packages -*.class -*.jar -*.war -*.ear - -# maven -target/ -# Mac +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint + +### macOS ### +# General .DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Maven ### +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + + +# End of https://www.gitignore.io/api/macos,maven,gradle,intellij + -# Project -src/test/Test.java +### Project specific ### src/test/* diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 933b647..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip From dfce9573201f9f2bad2a0b32696fc0f8e610606a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Mon, 25 Jun 2018 23:23:02 +0200 Subject: [PATCH 4/9] Add Gradle Support Gradle will replace Maven, because of faster builds and it is the more modern tool. But for now it wil reside next to Maven, until it is fully configured --- .gitignore | 10 +- .gradle/4.4/fileChanges/last-build.bin | Bin 1 -> 0 bytes .gradle/4.4/fileHashes/fileHashes.bin | Bin 18797 -> 0 bytes .gradle/4.4/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .gradle/4.4/taskHistory/taskHistory.bin | Bin 19630 -> 0 bytes .gradle/4.4/taskHistory/taskHistory.lock | Bin 17 -> 0 bytes .../buildOutputCleanup.lock | Bin 17 -> 0 bytes .gradle/buildOutputCleanup/cache.properties | 2 - .gradle/buildOutputCleanup/outputFiles.bin | Bin 18731 -> 0 bytes build.gradle | 26 +++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54731 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 ++++++++++++++++++ gradlew.bat | 84 +++++++++ settings.gradle | 1 + .../bananaj/connection/Connection.java | 18 +- 16 files changed, 306 insertions(+), 12 deletions(-) delete mode 100644 .gradle/4.4/fileChanges/last-build.bin delete mode 100644 .gradle/4.4/fileHashes/fileHashes.bin delete mode 100644 .gradle/4.4/fileHashes/fileHashes.lock delete mode 100644 .gradle/4.4/taskHistory/taskHistory.bin delete mode 100644 .gradle/4.4/taskHistory/taskHistory.lock delete mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock delete mode 100644 .gradle/buildOutputCleanup/cache.properties delete mode 100644 .gradle/buildOutputCleanup/outputFiles.bin create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore index bc75bc3..ab8a91a 100755 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +.idea + # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml @@ -57,10 +59,10 @@ fabric.properties ### Intellij Patch ### # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 -# *.iml -# modules.xml -# .idea/misc.xml -# *.ipr +*.iml +modules.xml +.idea/misc.xml +*.ipr # Sonarlint plugin .idea/sonarlint diff --git a/.gradle/4.4/fileChanges/last-build.bin b/.gradle/4.4/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/.gradle/4.4/fileHashes/fileHashes.bin b/.gradle/4.4/fileHashes/fileHashes.bin deleted file mode 100644 index cb7cefa9e7985f1afca957b66b6336117f0cb5b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18797 zcmeI(%PT}t0LSq&Lf(ePBMUVYO*2W6nv^JNri6_o%))CUNt6h&U=}jvH5(R)A}J+{ zDQjjSN{WR>StygTFblEZT<6|A=0DK))ZBCK@6K)(9iBREkb$E1M1d9;FKa diff --git a/.gradle/4.4/fileHashes/fileHashes.lock b/.gradle/4.4/fileHashes/fileHashes.lock deleted file mode 100644 index 0d10b295fe32442c0488a6b62f114ce3bb1bcde2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZQ}&RvsIFF|90%}uj*vxvrb8%19U_8IXM{A$o3dLPR-&z&AR@l$9bCI4WDxOv%gnx+_xAmM@AKZw zWh0taWvmp7wpw2emrIT`3}*VB2AWC?^=C4}TKQyx`gW?*7ToiRMqUytCYg{H zO|uc2b(qLAE~OQ5?cof|`qF9_Zc@-phG&!337VtodVtxgAwje1GhnG!C(ZJv8dx{> z9=$x)y|Va`8S@L{Umwg7a%F&uV?51NuumHm%*qSuc}x^z*A_2L6-qap-tU$1mT23A zHs1PvZ0J5A)1GiuZ=W++%w*|rXR;bmHx4|%W?${S`R&!+rMam$gLep-kU#y4$-LO8 zWb(REy}TIj`7l?r;BMb{duKffit&2S#z1@281Hb|FxJtzx(R5hvh3;zM)n9HRA diff --git a/.gradle/4.4/taskHistory/taskHistory.lock b/.gradle/4.4/taskHistory/taskHistory.lock deleted file mode 100644 index 4933c7eef3992440a1280da026a85f4d08d35fbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZR6tG{gXN2T<43=qH!06i%LF06qN$4*&oF diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index d6ce19f..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Mon Apr 23 19:34:34 CEST 2018 -gradle.version=4.4 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin deleted file mode 100644 index 83d61f58b544166927a80c233ab59abaeea3b169..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18731 zcmeI%KPZG@9KiACL^yxWBFCV_pirbp43xnw60zKJiwrkmIEpjfaGkq_?dnF0ZqTI& z-Kax!=`8A^LotxSV9@J*d!JvIWR>)N>v`U%@AKCCKA-g+Rmxpw=t~u^`r?um0tg_0 z00IagfB*srAbAWr)*?#>cx;R-0#U2QIEB0g8cK;QF~ zy*)N7{|{ojsnmJtc8l(B(ht35%`2goW4n7Ar5}B44Ne4JPxbRt(l5e2i<3j`LEQt= zFP%623rlMqx+kUQ{9V4_bta^HSh|t+MNiHWx4NgLSL`>%lKF=X-AAOi-5c-TNFlC! zT>8w;x_^8wlhZvbeg5$vyLXqU(!C&kHQ%~9{IndkyQf^b+?8^8>^)`#5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009JkN1)ey WO{F;;*0849FU1UhynO%WAIc}ErNJ=( diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..8156e23 --- /dev/null +++ b/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'java' +apply plugin: 'maven' + +group = 'com.github.alexanderwe' +version = '0.5.0' + +description = """bananaj""" + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + + + +repositories { + + maven { url "http://repo.maven.apache.org/maven2" } +} +dependencies { + compile group: 'commons-codec', name: 'commons-codec', version:'1.10' + compile group: 'net.sourceforge.jexcelapi', name: 'jxl', version:'2.6.12' + compile group: 'org.json', name: 'json', version:'20160212' + compile group: 'org.apache.httpcomponents', name: 'httpclient', version:'4.5.5' +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..6b6ea3ab4ff4f69d55c5fd9c0a6ac70f47d41008 GIT binary patch literal 54731 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�A``0fKpc0WAU$bg;D1GyIQa;7hdW#MKpuc+fPkN63DB8-QCon}w55{+ zK*~kT%+g5EzyQD?t7onEf4S{n5`Y%HU(o_IxB{TT|7ske_`f6&x7P#Y(^Lk?K1$eF z8Ohk#SUB1Kx@itd&0`AyGX5-pngUK={i!e#{R8yBlYsrOyWkeC%j+RF5iuzNd@qNfB>rpz#I8f@s{`{nv9Lfe|_68v(EoSLz4a_*l*>a ze`!-MGn)To!IAynEWd7smziIGVoE6e67%Kc<1cw&U)K0#-o>Bj6zac3|F@C;A`9b7 z=$C2lenNw4{S)+GliV}2G}0N|fG z)sG;wmk+am&9E z{i*){Mdkk`{7ZrQpYTT3{{;VHviuVEr7rtV*j}4|g8j3f;U(rv3E-cYWBU$VtD_%M1M5Tztu!v61)^^{7FFK`5OfPAl>+q z>7}IGPbO2}-(dPJfwz~OFNL~(a)Jl^2IoJ?cDeQ`pGlj`8S@I)6PGc(f|02zx2HPq$%$HzbV~+ v^TYh7&j0bc{Ml*p!|U?1+ylV=n-AuVG#FqV^dowa3FsZ*6oN|6kH7vOrq \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..9942a63 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'bananaj' diff --git a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java index d2e5622..0ab5c68 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java +++ b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java @@ -29,7 +29,8 @@ public String do_Get(URL url, String authorization) throws TransportException, U int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); + String errorJson = createResponseFromEntity(response.getEntity()); + throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + errorJson, errorJson); } return createResponseFromEntity(response.getEntity()); @@ -51,7 +52,8 @@ public String do_Post(URL url, String post_string, String authorization) throws int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); + String errorJson = createResponseFromEntity(response.getEntity()); + throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + errorJson, errorJson); } return createResponseFromEntity(response.getEntity()); @@ -73,7 +75,8 @@ public String do_Patch(URL url, String patch_string, String authorization) throw int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); + String errorJson = createResponseFromEntity(response.getEntity()); + throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + errorJson, errorJson); } return createResponseFromEntity(response.getEntity()); @@ -95,7 +98,8 @@ public String do_Put(URL url, String put_string, String authorization) throws Tr int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); + String errorJson = createResponseFromEntity(response.getEntity()); + throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + errorJson, errorJson); } return createResponseFromEntity(response.getEntity()); @@ -116,7 +120,8 @@ public String do_Post(URL url, String authorization) throws TransportException, int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); + String errorJson = createResponseFromEntity(response.getEntity()); + throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + errorJson, errorJson); } return createResponseFromEntity(response.getEntity()); @@ -137,7 +142,8 @@ public String do_Delete(URL url, String authorization) throws TransportException int responseCode = response.getStatusLine().getStatusCode(); if (responseCode < 200 || responseCode > 299) { - throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + createResponseFromEntity(response.getEntity()), createResponseFromEntity(response.getEntity())); + String errorJson = createResponseFromEntity(response.getEntity()); + throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + errorJson, errorJson); } return createResponseFromEntity(response.getEntity()); From 7e985e550f8d52d10efed8ff98ee8b6d2c92c642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Tue, 26 Jun 2018 11:03:38 +0200 Subject: [PATCH 5/9] Remove some methods which are not necessary Smaller changes at other places --- .../bananaj/model/list/MailChimpList.java | 73 ++----------------- 1 file changed, 8 insertions(+), 65 deletions(-) diff --git a/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java b/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java index de466bf..6c579e3 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java +++ b/src/main/java/com/github/alexanderwe/bananaj/model/list/MailChimpList.java @@ -161,14 +161,12 @@ public Member updateMember(Member member) throws Exception { if (member.getEmail_type() != null) { json.put("email_type", member.getEmail_type().value()); } - jsonPut(json, "status", member.getStatus().getStringRepresentation()); + json.put( "status", member.getStatus().getStringRepresentation()); { JSONObject mergeFields = new JSONObject(); HashMap mergeFieldsMap = member.getMerge_fields(); - Iterator it = mergeFieldsMap.keySet().iterator(); - while (it.hasNext()) { - String key = it.next(); + for (String key : mergeFieldsMap.keySet()) { mergeFields.put(key, mergeFieldsMap.get(key)); } json.put("merge_fields", mergeFields); @@ -177,81 +175,26 @@ public Member updateMember(Member member) throws Exception { { JSONObject interests = new JSONObject(); HashMap interestsMap = member.getInterest(); - Iterator it = interestsMap.keySet().iterator(); - while (it.hasNext()) { - String key = it.next(); + for (String key : interestsMap.keySet()) { interests.put(key, interestsMap.get(key)); } json.put("interests",interests); } - jsonPut(json, "ip_signup", member.getIp_signup()); - jsonPut(json, "timestamp_signup", member.getTimestamp_signup()); - jsonPut(json, "ip_opt", member.getIp_opt()); - jsonPut(json, "timestamp_opt", member.getTimestamp_opt()); + json.put("ip_signup", member.getIp_signup()); + json.put("timestamp_signup", member.getTimestamp_signup()); + json.put( "ip_opt", member.getIp_opt()); + json.put("timestamp_opt", member.getTimestamp_opt()); try { String results = getConnection().do_Patch(new URL(connection.getListendpoint()+"/"+this.getId()+"/members/"+member.getId()),json.toString(),connection.getApikey()); - //this.membercount++; + this.membercount++; return new Member(this, new JSONObject(results)); } catch (Exception e) { e.printStackTrace(); } return null; } - - public Member createUpdateMember(Member member) throws Exception { - JSONObject json = new JSONObject(); - json.put("email_address", member.getEmail_address()); - if (member.getStatus_if_new() != null) { - json.put("status_if_new", member.getStatus_if_new().getStringRepresentation()); - } - if (member.getEmail_type() != null) { - json.put("email_type", member.getEmail_type().value()); - } - jsonPut(json, "status", member.getStatus().getStringRepresentation()); - { - JSONObject mergeFields = new JSONObject(); - HashMap mergeFieldsMap = member.getMerge_fields(); - Iterator it = mergeFieldsMap.keySet().iterator(); - while (it.hasNext()) { - String key = it.next(); - mergeFields.put(key, mergeFieldsMap.get(key)); - } - json.put("merge_fields", mergeFields); - } - - { - JSONObject interests = new JSONObject(); - HashMap interestsMap = member.getInterest(); - Iterator it = interestsMap.keySet().iterator(); - while (it.hasNext()) { - String key = it.next(); - interests.put(key, interestsMap.get(key)); - } - json.put("interests",interests); - } - jsonPut(json, "ip_signup", member.getIp_signup()); - jsonPut(json, "timestamp_signup", member.getTimestamp_signup()); - jsonPut(json, "ip_opt", member.getIp_opt()); - jsonPut(json, "timestamp_opt", member.getTimestamp_opt()); - - try { - String results = getConnection().do_Put(new URL(connection.getListendpoint()+"/"+this.getId()+"/members/"+member.getId()),json.toString(),connection.getApikey()); - //this.membercount++; - return new Member(this, new JSONObject(results)); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - private void jsonPut(JSONObject json, String fieldName, String value) { - if (value != null) { - json.put(fieldName, value); - } - } - /** * Add a member with first and last name * @param status From fc496a2dd8e25d27960845abd90dfdb79e1db88a Mon Sep 17 00:00:00 2001 From: Gary Scriver Date: Wed, 27 Jun 2018 12:24:44 -0600 Subject: [PATCH 6/9] Fixed - MailChimp API returns error status 400 when content contains Unicode. Updated error handling to include info from the MailChimp API error object when failure occurs. --- .../bananaj/connection/Connection.java | 160 +++++++----------- 1 file changed, 59 insertions(+), 101 deletions(-) diff --git a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java index 07a346b..ea31544 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java +++ b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java @@ -1,9 +1,11 @@ package com.github.alexanderwe.bananaj.connection; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -18,6 +20,8 @@ import org.apache.http.client.methods.HttpPut; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; +import org.json.JSONException; +import org.json.JSONObject; import com.github.alexanderwe.bananaj.exceptions.TransportException; @@ -30,7 +34,6 @@ public class Connection { public String do_Get(URL url, String authorization) throws TransportException { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; - InputStream entityStream = null; try { httpclient = HttpClients.createDefault(); @@ -42,25 +45,13 @@ public String do_Get(URL url, String authorization) throws TransportException { //System.out.println("\nSending 'GET' request to URL : " + url); //System.out.println("Response Code : " + responseCode + "\n"); if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " GET " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw buildTrasportError("GET", url.toExternalForm(), response); } - HttpEntity entity = response.getEntity(); - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } catch (Exception e) { + return getResponseEntity(response); + } catch (IOException | URISyntaxException e) { throw new TransportException("GET " + url.toExternalForm() + " failed", e); } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} if (response != null) {try {response.close();} catch (Exception e) { }} } } @@ -68,42 +59,26 @@ public String do_Get(URL url, String authorization) throws TransportException { public String do_Post(URL url, String post_string, String authorization) throws TransportException { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; - InputStream entityStream = null; try { httpclient = HttpClients.createDefault(); HttpPost httppost = new HttpPost(url.toURI()); httppost.addHeader("Authorization", authorization); httppost.addHeader("Content-Type", "application/json; charset=UTF-8"); - httppost.setEntity(EntityBuilder.create().setText(post_string).build()); + httppost.setEntity(EntityBuilder.create().setBinary(post_string.getBytes(StandardCharsets.UTF_8)).build()); response = httpclient.execute(httppost); int responseCode = response.getStatusLine().getStatusCode(); //System.out.println("\nSending 'POST' request to URL : " + url + System.lineSeparator() + "Send data: " + (post_string.length() > 500 ? post_string.substring(0, 500)+"..." : post_string)); //System.out.println("Response Code : " + responseCode + "\n"); if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw buildTrasportError("POST", url.toExternalForm(), response); } - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { + return getResponseEntity(response); + } catch (IOException | URISyntaxException e) { throw new TransportException("POST " + post_string.length() + " bytes to " + url.toExternalForm() + " failed", e); } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} if (response != null) {try {response.close();} catch (Exception e) { }} } } @@ -111,42 +86,26 @@ public String do_Post(URL url, String post_string, String authorization) throws public String do_Patch(URL url, String patch_string, String authorization) throws TransportException { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; - InputStream entityStream = null; try { httpclient = HttpClients.createDefault(); HttpPatch httppatch = new HttpPatch(url.toURI()); httppatch.addHeader("Authorization", authorization); httppatch.addHeader("Content-Type", "application/json; charset=UTF-8"); - httppatch.setEntity(EntityBuilder.create().setText(patch_string).build()); + httppatch.setEntity(EntityBuilder.create().setBinary(patch_string.getBytes(StandardCharsets.UTF_8)).build()); response = httpclient.execute(httppatch); int responseCode = response.getStatusLine().getStatusCode(); //System.out.println("\nSending 'PATCH' request to URL : " + url + System.lineSeparator() + "Send data: " + (patch_string.length() > 500 ? patch_string.substring(0, 500)+"..." : patch_string)); //System.out.println("Response Code : " + responseCode + "\n"); if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " PATCH " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw buildTrasportError("PATCH", url.toExternalForm(), response); } - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { + return getResponseEntity(response); + } catch (IOException | URISyntaxException e) { throw new TransportException("PATCH " + patch_string.length() + " bytes to " + url.toExternalForm() + " failed", e); } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} if (response != null) {try {response.close();} catch (Exception e) { }} } } @@ -154,42 +113,26 @@ public String do_Patch(URL url, String patch_string, String authorization) throw public String do_Put(URL url, String put_string, String authorization) throws TransportException { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; - InputStream entityStream = null; try { httpclient = HttpClients.createDefault(); HttpPut httpput = new HttpPut(url.toURI()); httpput.addHeader("Authorization", authorization); httpput.addHeader("Content-Type", "application/json; charset=UTF-8"); - httpput.setEntity(EntityBuilder.create().setText(put_string).build()); + httpput.setEntity(EntityBuilder.create().setBinary(put_string.getBytes(StandardCharsets.UTF_8)).build()); response = httpclient.execute(httpput); int responseCode = response.getStatusLine().getStatusCode(); //System.out.println("\nSending 'PUT' request to URL : " + url + System.lineSeparator() + "Send data: " + (put_string.length() > 500 ? put_string.substring(0, 500)+"..." : put_string)); //System.out.println("Response Code : " + responseCode + "\n"); if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " PUT " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw buildTrasportError("PUT", url.toExternalForm(), response); } - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { + return getResponseEntity(response); + } catch (IOException | URISyntaxException e) { throw new TransportException("PUT " + put_string.length() + " bytes to " + url.toExternalForm() + " failed", e); } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} if (response != null) {try {response.close();} catch (Exception e) { }} } } @@ -197,7 +140,6 @@ public String do_Put(URL url, String put_string, String authorization) throws Tr public String do_Post(URL url, String authorization) throws TransportException { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; - InputStream entityStream = null; try { httpclient = HttpClients.createDefault(); @@ -210,28 +152,13 @@ public String do_Post(URL url, String authorization) throws TransportException { //System.out.println("\nSending 'POST' request to URL : " + url); //System.out.println("Response Code : " + responseCode + "\n"); if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " POST " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw buildTrasportError("POST", url.toExternalForm(), response); } - HttpEntity entity = response.getEntity(); - if (entity != null) { - long length = entity.getContentLength(); - entityStream = entity.getContent(); - StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int)length : 200); - try (Reader reader = new BufferedReader(new InputStreamReader - (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; - while ((c = reader.read()) != -1) { - strbuilder.append((char) c); - } - } - return strbuilder.toString(); - } - return null; - } catch (Exception e) { + return getResponseEntity(response); + } catch (IOException | URISyntaxException e) { throw new TransportException("POST " + url.toExternalForm() + " failed", e); } finally { - if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} if (response != null) {try {response.close();} catch (Exception e) { }} } } @@ -239,7 +166,6 @@ public String do_Post(URL url, String authorization) throws TransportException { public String do_Delete(URL url, String authorization) throws TransportException { CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; - InputStream entityStream = null; try { httpclient = HttpClients.createDefault(); @@ -252,9 +178,20 @@ public String do_Delete(URL url, String authorization) throws TransportException //System.out.println("\nSending 'DELETE' request to URL : " + url); //System.out.println("Response Code : " + responseCode + "\n"); if (responseCode >= 400) { - throw new TransportException("Error: " + responseCode + " DELETE " + url.toExternalForm() + " " + response.getStatusLine().getReasonPhrase()); + throw buildTrasportError("DELETE", url.toExternalForm(), response); } + return getResponseEntity(response); + } catch (IOException | URISyntaxException e) { + throw new TransportException("DELETE " + url.toExternalForm() + " failed", e); + } finally { + if (response != null) {try {response.close();} catch (Exception e) { }} + } + } + + private String getResponseEntity(CloseableHttpResponse response) throws IOException { + InputStream entityStream = null; + try { HttpEntity entity = response.getEntity(); if (entity != null) { long length = entity.getContentLength(); @@ -269,12 +206,33 @@ public String do_Delete(URL url, String authorization) throws TransportException } return strbuilder.toString(); } - return null; - } catch (Exception e) { - throw new TransportException("DELETE " + url.toExternalForm() + " failed", e); } finally { if (entityStream != null) {try {entityStream.close();} catch (Exception e) { }} - if (response != null) {try {response.close();} catch (Exception e) { }} } + return null; + } + + private TransportException buildTrasportError(String verb, String url, CloseableHttpResponse response) { + int responseCode = response.getStatusLine().getStatusCode(); + JSONObject errObj = null; + try { + errObj = new JSONObject( getResponseEntity(response)); + String errType = getErrorObjString(errObj, "type"); + String errTitle = getErrorObjString(errObj, "title"); + String errDetail = getErrorObjString(errObj, "detail"); + String errInstance = getErrorObjString(errObj, "instance"); + return new TransportException("Status: " + Integer.toString(responseCode) + " " + verb + ": " + url + " Reason: " + response.getStatusLine().getReasonPhrase() + + " - " + errTitle + " Details: " + errDetail + " Instance: " + errInstance + " Type: " + errType); + } catch (IOException | JSONException e) { + e.printStackTrace(); + } + return new TransportException("Status: " + Integer.toString(responseCode) + " " + verb + ": " + url + " Reason: " + response.getStatusLine().getReasonPhrase()); + } + + private String getErrorObjString(JSONObject errObj, String key) { + if (errObj.has(key)) { + return errObj.getString(key); + } + return ""; } } From 59deebae056b88ea472ad6408d0358a6d4c7c3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Tue, 3 Jul 2018 15:24:08 +0200 Subject: [PATCH 7/9] Migrate to Gradle --- .gitignore | 1 + build.gradle | 71 ++++++++- pom.xml | 145 ------------------ .../bananaj/connection/Connection.java | 2 +- .../model/filemanager/FileManagerFile.java | 10 +- 5 files changed, 76 insertions(+), 153 deletions(-) delete mode 100755 pom.xml diff --git a/.gitignore b/.gitignore index ab8a91a..459d0fe 100755 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ # Gradle .idea/**/gradle.xml .idea/**/libraries +gradle.properties # CMake cmake-build-*/ diff --git a/build.gradle b/build.gradle index 8156e23..c470dcb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,11 @@ apply plugin: 'java' apply plugin: 'maven' +apply plugin: 'signing' + group = 'com.github.alexanderwe' -version = '0.5.0' +archivesBaseName = "bananaj" +version = '0.5.1' description = """bananaj""" @@ -12,7 +15,21 @@ tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} +task fatJar(type: Jar) { + baseName = 'bananaj-all-in-one-jar' + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + with jar +} repositories { @@ -24,3 +41,55 @@ dependencies { compile group: 'org.json', name: 'json', version:'20160212' compile group: 'org.apache.httpcomponents', name: 'httpclient', version:'4.5.5' } + +artifacts { + archives javadocJar, fatJar +} + +signing { + sign configurations.archives +} + +uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: ossrhUsername, password: ossrhPassword) + } + + pom.project { + name 'bananaj' + packaging 'jar' + // optionally artifactId can be defined here + description 'A simple MailChimp API wrapper written in Java' + url 'https://github.com/alexanderwe/bananaj' + + scm { + connection 'scm:git:git://github.com/alexanderwe/bananaj.git' + developerConnection 'scm:git:git://github.com/alexanderwe/bananaj.git' + url 'https://github.com/alexanderwe/bananaj' + } + + licenses { + license { + name 'MIT' + url 'https://raw.githubusercontent.com/alexanderwe/bananaj/master/LICENSE.md' + } + } + + developers { + developer { + name 'Alexander Weiß' + url 'https://www.github.com/alexanderwe' + } + } + } + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml deleted file mode 100755 index e44ddb5..0000000 --- a/pom.xml +++ /dev/null @@ -1,145 +0,0 @@ - - - 4.0.0 - - com.github.alexanderwe - bananaj - 0.5.0 - jar - - bananaj - A simple MailChimp API wrapper written in Java - https://github.com/alexanderwe/bananaj - - - - MIT - https://raw.githubusercontent.com/alexanderwe/bananaj/master/LICENSE.md - repo - - - - - - - Alexander Weiß - https://www.github.com/alexanderwe - - - - - - scm:git:git://github.com/alexanderwe/bananaj.git - scm:git:git://github.com/alexanderwe/bananaj.git - https://github.com/alexanderwe/bananaj - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - UTF-8 - 1.8 - 1.8 - - - - - - commons-codec - commons-codec - 1.10 - - - - net.sourceforge.jexcelapi - jxl - 2.6.12 - - - - org.json - json - 20160212 - - - - org.apache.httpcomponents - httpclient - 4.5.5 - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.5.1 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - - attach-javadocs - - jar - - - - - -Xdoclint:none - - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - - - - - \ No newline at end of file diff --git a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java index 628823b..be6dcde 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java +++ b/src/main/java/com/github/alexanderwe/bananaj/connection/Connection.java @@ -163,7 +163,7 @@ private String createResponseFromEntity(HttpEntity entity) throws IOException { StringBuilder strbuilder = new StringBuilder(length > 16 && length < Integer.MAX_VALUE ? (int) length : 200); try (Reader reader = new BufferedReader(new InputStreamReader (entityStream, Charset.forName(StandardCharsets.UTF_8.name())))) { - int c = 0; + int c; while ((c = reader.read()) != -1) { strbuilder.append((char) c); } diff --git a/src/main/java/com/github/alexanderwe/bananaj/model/filemanager/FileManagerFile.java b/src/main/java/com/github/alexanderwe/bananaj/model/filemanager/FileManagerFile.java index 2c83b5a..35a0f62 100755 --- a/src/main/java/com/github/alexanderwe/bananaj/model/filemanager/FileManagerFile.java +++ b/src/main/java/com/github/alexanderwe/bananaj/model/filemanager/FileManagerFile.java @@ -120,11 +120,10 @@ public FileManagerFile (Builder b){ this.folder_id = b.folderId; } - /** * Change the name of the file - * @param newName - * @ + * @param name + * @throws Exception */ public void changeName(String name) throws Exception{ JSONObject changedFileName = new JSONObject(); @@ -136,9 +135,8 @@ public void changeName(String name) throws Exception{ /** * Change the folder of this file - * @param The id of the folder. Setting folderID to "0" will remove a file from its current folder. - * @throws Exception - * @throws + * @param folderID Setting folderID to "0" will remove a file from its current folder. + * @throws Exception */ public void changeFolder(int folderID) throws Exception { JSONObject changedFileName = new JSONObject(); From 19e537d59489afc76e89ef70ad394ea4844d8437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Sat, 7 Jul 2018 15:41:04 +0200 Subject: [PATCH 8/9] Finalize the switch to Gradle --- README.md | 18 ++++++--- build.gradle | 112 +++++++++++++++++++++++++-------------------------- 2 files changed, 68 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index ce506ec..2317c6e 100755 --- a/README.md +++ b/README.md @@ -3,11 +3,6 @@ Simple api for accessing Mailchimp - Work in progess [![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://raw.githubusercontent.com/gr4h4n/bananaj/master/LICENSE.md) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.alexanderwe/bananaj/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.alexanderwe/bananaj) - - - - # Introduction bananaj provides an Java wrapper for the MailChimp API 3.0. It is possible access your MailChimp data through Java. @@ -22,9 +17,20 @@ Add this dependency to your pom.xml to use **bananaj** in your project. com.github.alexanderwe bananaj - 0.5.0 + 0.5.1 ``` +or with Gradle + +``` +repositories { + maven { url "http://repo.maven.apache.org/maven2" } +} + +dependencies { + compile group: 'com.github.alexanderwe', name: 'bananaj', version: '0.5.1' +} +``` ## MailChimpObject class Most of the com.github.alexanderwe.bananaj.model classes extend the MailChimpObject class.They are immutable, to prevent asynchronous data between the client and the MailChimp server. diff --git a/build.gradle b/build.gradle index c470dcb..59787e8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,29 @@ -apply plugin: 'java' -apply plugin: 'maven' +apply plugin: "java" +apply plugin: "maven" +apply plugin: "maven-publish" apply plugin: 'signing' - group = 'com.github.alexanderwe' -archivesBaseName = "bananaj" version = '0.5.1' -description = """bananaj""" +description = 'A simple MailChimp API wrapper written in Java' sourceCompatibility = 1.8 targetCompatibility = 1.8 + tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' + options.encoding = 'UTF-8' +} + +repositories { + maven { url "http://repo.maven.apache.org/maven2" } +} + +dependencies { + compile group: 'commons-codec', name: 'commons-codec', version: '1.11' + compile group: 'net.sourceforge.jexcelapi', name: 'jxl', version: '2.6.12' + compile group: 'org.json', name: 'json', version: '20180130' + compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.5' } task javadocJar(type: Jar) { @@ -26,70 +37,59 @@ task sourcesJar(type: Jar) { } task fatJar(type: Jar) { - baseName = 'bananaj-all-in-one-jar' + baseName = 'bananaj' from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar } -repositories { - - maven { url "http://repo.maven.apache.org/maven2" } -} -dependencies { - compile group: 'commons-codec', name: 'commons-codec', version:'1.10' - compile group: 'net.sourceforge.jexcelapi', name: 'jxl', version:'2.6.12' - compile group: 'org.json', name: 'json', version:'20160212' - compile group: 'org.apache.httpcomponents', name: 'httpclient', version:'4.5.5' -} - -artifacts { - archives javadocJar, fatJar -} - -signing { - sign configurations.archives -} +publishing { + publications { + mavenJava(MavenPublication) { + from components.java -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - pom.project { - name 'bananaj' - packaging 'jar' - // optionally artifactId can be defined here - description 'A simple MailChimp API wrapper written in Java' - url 'https://github.com/alexanderwe/bananaj' - - scm { - connection 'scm:git:git://github.com/alexanderwe/bananaj.git' - developerConnection 'scm:git:git://github.com/alexanderwe/bananaj.git' - url 'https://github.com/alexanderwe/bananaj' - } + artifact javadocJar + artifact sourcesJar + pom { + name = 'bananaj' + description = 'A simple MailChimp API wrapper written in Java' + url = 'https://github.com/alexanderwe/bananaj' licenses { license { - name 'MIT' - url 'https://raw.githubusercontent.com/alexanderwe/bananaj/master/LICENSE.md' + name = 'MIT' + url = 'https://raw.githubusercontent.com/alexanderwe/bananaj/master/LICENSE.md' } } - developers { developer { - name 'Alexander Weiß' - url 'https://www.github.com/alexanderwe' + name = 'Alexander Weiß' + email = 'https://www.github.com/alexanderwe' } } + scm { + connection = 'scm:git:git://github.com/alexanderwe/bananaj.git' + developerConnection = 'scm:git:git://github.com/alexanderwe/bananaj.git' + url = 'https://github.com/alexanderwe/bananaj' + } + issueManagement { + url = 'https://github.com/alexanderwe/bananaj/issues' + system = 'GitHub' + } } } } -} \ No newline at end of file + repositories { + maven { + url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' + credentials { + username ossrhUsername + password ossrhPassword + } + } + } +} + +signing { + sign publishing.publications.mavenJava +} + From bf9f11757f0d82af3e44c3b3cee594389f8cb2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Wei=C3=9F?= Date: Sat, 7 Jul 2018 15:42:16 +0200 Subject: [PATCH 9/9] Bump License year --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index f85d0b1..49e6f43 100755 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # The MIT License (MIT) -Copyright (c) 2015 - 2017 Alexander Weiß +Copyright (c) 2015 - 2018 Alexander Weiß Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: