From f4f2c2e21ab5f05a702d2d985b582afb3c000b70 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 24 Mar 2017 12:45:28 +0100 Subject: [PATCH 01/74] Finishing Thumbnail and Attachement Converter, started with tests --- .../java/com/sybit/airtable/Airtable.java | 6 +- .../com/sybit/airtable/ListConverter.java | 65 ++++++++++++------- .../sybit/airtable/ThumbnailConverter.java | 43 +++++++----- .../java/com/sybit/airtable/vo/Thumbnail.java | 52 ++++++++++++++- src/main/resources/credentials.properties | 5 ++ .../sybit/airtable/TableConverterTest.java | 35 ++++++++++ .../sybit/airtable/test/WireMockBaseTest.java | 2 +- 7 files changed, 160 insertions(+), 48 deletions(-) create mode 100644 src/main/resources/credentials.properties create mode 100644 src/test/java/com/sybit/airtable/TableConverterTest.java diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index dd33179..7e0f26c 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -22,10 +22,12 @@ import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; +import org.apache.http.HttpHost; /** * Representation Class of Airtable. @@ -107,7 +109,7 @@ public Airtable configure(String apiKey, String endpointUrl) throws AirtableExce final String httpProxy = System.getenv("http_proxy"); if(httpProxy != null) { LOG.info("Use Proxy: Environment variable 'http_proxy' found and used: " + httpProxy); - //Unirest.setProxy(HttpHost.create(httpProxy)); + Unirest.setProxy(HttpHost.create(httpProxy)); } @@ -126,7 +128,7 @@ public Airtable configure(String apiKey, String endpointUrl) throws AirtableExce ConvertUtils.register(dtConverter, Date.class); ConvertUtils.register(lConverter, List.class); - //ConvertUtils.register(thConverter, Map.class); + ConvertUtils.register(thConverter, Map.class); return this; diff --git a/src/main/java/com/sybit/airtable/ListConverter.java b/src/main/java/com/sybit/airtable/ListConverter.java index c1645af..5bd33d6 100644 --- a/src/main/java/com/sybit/airtable/ListConverter.java +++ b/src/main/java/com/sybit/airtable/ListConverter.java @@ -7,7 +7,10 @@ import com.google.gson.internal.LinkedTreeMap; import com.sybit.airtable.vo.Attachment; +import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.converters.AbstractConverter; @@ -19,24 +22,39 @@ public class ListConverter extends AbstractConverter { private Class listClass; + + @Override + protected Object convertArray(final Object value) { + return value; + } @Override protected T convertToType(final Class type, Object value) throws Throwable { - - Object instanz = this.getListClass().newInstance(); - Class sourceType = (Class) value.getClass(); - - if(value instanceof LinkedTreeMap){ - for (String key : ((LinkedTreeMap) value).keySet()) { - Object val = ((LinkedTreeMap) value).get(key); - BeanUtils.setProperty(instanz,key,val); - } - return toClassList(sourceType,instanz); + List returnList = new ArrayList(); + + if(value instanceof List){ + for (T item: ((List) value)){ + if(item instanceof LinkedTreeMap){ + Object instanz = this.getListClass().newInstance(); + for (String key : ((LinkedTreeMap) item).keySet()) { + Object val = ((LinkedTreeMap) item).get(key); + BeanUtils.setProperty(instanz,key,val); + } + returnList = toClassList(item.getClass(),instanz,returnList); + } + if(item instanceof String){ + returnList = toStringList(item.getClass(),item.toString(),returnList); + } + + } + return (T) returnList; } + + //TODO überarbeiten if(value instanceof String){ - return toStringList(sourceType,value.toString()); + return (T) toStringList(value.getClass(),value.toString(),returnList); } final String stringValue = value.toString().trim(); @@ -44,31 +62,28 @@ protected T convertToType(final Class type, Object value) throws Throwabl return handleMissing(type); } - return toStringList(sourceType,stringValue); + return (T) toStringList(value.getClass(),stringValue,returnList); } - private T toStringList(final Class type, final String value) { - - List returnList = new ArrayList(); - + private List toStringList(final Class type, final String value,List returnList) { + if (type.equals(String.class)) { - returnList.add(type.cast(String.valueOf(value))); - return (T) returnList; + returnList.add(String.valueOf(value)); + return returnList; } - returnList.add(type.cast(String.valueOf(value))); - return (T) returnList; + returnList.add(String.valueOf(value)); + return returnList; } - private T toClassList(final Class type, final Object value) { + private List toClassList(final Class type, final Object value, List returnList) { if (type.equals(LinkedTreeMap.class)) { - List returnList = new ArrayList(); - returnList.add((T) value); - return (T) returnList; + returnList.add(value); + return returnList; } - return toStringList(type,value.toString()); + return toStringList(type,value.toString(),returnList); } /** diff --git a/src/main/java/com/sybit/airtable/ThumbnailConverter.java b/src/main/java/com/sybit/airtable/ThumbnailConverter.java index 9a0db4f..d0ecbf9 100644 --- a/src/main/java/com/sybit/airtable/ThumbnailConverter.java +++ b/src/main/java/com/sybit/airtable/ThumbnailConverter.java @@ -8,7 +8,9 @@ import com.google.gson.internal.LinkedTreeMap; import com.sybit.airtable.vo.Thumbnail; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.converters.AbstractConverter; @@ -24,19 +26,25 @@ public class ThumbnailConverter extends AbstractConverter{ protected T convertToType(Class type, Object value) throws Throwable { - Class sourceType = (Class) value.getClass(); Object instanz = this.mapClass.newInstance(); - + Class sourceType = (Class) value.getClass(); + Map returnMap = new HashMap(); + if(value instanceof LinkedTreeMap){ for (String key : ((LinkedTreeMap) value).keySet()) { - Object val = ((LinkedTreeMap) value).get(key); - BeanUtils.setProperty(instanz,key,val); + Object val = ((LinkedTreeMap) value).get(key); + BeanUtils.setProperty(instanz,"name",key); + for (String key2 : ((LinkedTreeMap) val).keySet()) { + Object val2 = ((LinkedTreeMap) val).get(key2); + BeanUtils.setProperty(instanz,key2,val2); + } + returnMap = toClassMap(sourceType,instanz,returnMap); } - return toClassList(sourceType,instanz); + return (T) returnMap; } if(value instanceof String){ - return toStringList(sourceType,value.toString()); + return (T) toStringMap(sourceType,value.toString(),returnMap); } final String stringValue = value.toString().trim(); @@ -44,31 +52,32 @@ protected T convertToType(Class type, Object value) throws Throwable { return handleMissing(type); } - return toStringList(sourceType,stringValue); + return (T) toStringMap(sourceType,stringValue,returnMap); } - private T toClassList(final Class type, final Object value) { + private Map toClassMap(final Class type, final Object value,Map returnMap) { - if (type.equals(LinkedTreeMap.class)) { - List returnList = new ArrayList(); - returnList.add((T) value); - return (T) returnList; + if (type.equals(LinkedTreeMap.class)) { + if (value.getClass().equals(Thumbnail.class)) { + returnMap.put(((Thumbnail)value).getName(),value); + } + return returnMap; } - return toStringList(type,value.toString()); + return toStringMap(type,value.toString(),returnMap); } - private T toStringList(final Class type, final String value) { + private Map toStringMap(final Class type, final String value,Map returnMap) { - List returnList = new ArrayList(); + List returnList = new ArrayList(); if (type.equals(String.class)) { returnList.add(type.cast(String.valueOf(value))); - return (T) returnList; + return (Map) returnList; } returnList.add(type.cast(String.valueOf(value))); - return (T) returnList; + return (Map) returnList; } @Override diff --git a/src/main/java/com/sybit/airtable/vo/Thumbnail.java b/src/main/java/com/sybit/airtable/vo/Thumbnail.java index 0e5c4d9..5e2f203 100644 --- a/src/main/java/com/sybit/airtable/vo/Thumbnail.java +++ b/src/main/java/com/sybit/airtable/vo/Thumbnail.java @@ -13,10 +13,12 @@ * @author fzr */ public class Thumbnail { - + + private String name; + private String url; - //private Float width; - //private Float height; + private Float width; + private Float height; /** * @return the url @@ -32,6 +34,50 @@ public void setUrl(String url) { this.url = url; } + /** + * @return the width + */ + public Float getWidth() { + return width; + } + + /** + * @param width the width to set + */ + public void setWidth(Float width) { + this.width = width; + } + + /** + * @return the height + */ + public Float getHeight() { + return height; + } + + /** + * @param height the height to set + */ + public void setHeight(Float height) { + this.height = height; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + + } diff --git a/src/main/resources/credentials.properties b/src/main/resources/credentials.properties new file mode 100644 index 0000000..f0e2759 --- /dev/null +++ b/src/main/resources/credentials.properties @@ -0,0 +1,5 @@ +# To change this license header, choose License Headers in Project Properties. +# To change this template file, choose Tools | Templates +# and open the template in the editor. +AIRTABLE_API_KEY=keyrguODZpsZdrPRd + diff --git a/src/test/java/com/sybit/airtable/TableConverterTest.java b/src/test/java/com/sybit/airtable/TableConverterTest.java new file mode 100644 index 0000000..b900ba2 --- /dev/null +++ b/src/test/java/com/sybit/airtable/TableConverterTest.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable; + +import com.sybit.airtable.exception.AirtableException; +import com.sybit.airtable.movies.Actor; +import com.sybit.airtable.movies.Movie; +import com.sybit.airtable.test.WireMockBaseTest; +import java.util.List; +import org.apache.http.client.HttpResponseException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +/** + * + * @author fzr + */ +public class TableConverterTest extends WireMockBaseTest { + + @Test + public void testConvertAttachements() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie movie = movieTable.find("rec6733da527dd0f1"); + assertNotNull(movie); + + } + +} diff --git a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java index a195117..2b39a60 100644 --- a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java +++ b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java @@ -31,7 +31,7 @@ public class WireMockBaseTest { @Before public void setup() throws AirtableException { airtable.configure(); - airtable.setEndpointUrl("http://localhost:8080/v0"); + //airtable.setEndpointUrl("http://localhost:8080/v0"); //set 404 as default stubFor(any(anyUrl()) From 05f89c14a7e74aad1aadfd351efc3976471da6a6 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 24 Mar 2017 15:30:47 +0100 Subject: [PATCH 02/74] Test for Converter and README changes --- README.md | 13 ++ .../java/com/sybit/airtable/Airtable.java | 2 +- .../sybit/airtable/AttachementConverter.java | 129 ------------------ .../com/sybit/airtable/ListConverter.java | 4 - .../sybit/airtable/ThumbnailConverter.java | 3 +- .../sybit/airtable/TableConverterTest.java | 61 ++++++++- .../sybit/airtable/test/WireMockBaseTest.java | 2 +- .../resources/__files/body-MoviesFind.json | 54 ++++++++ .../resources/mappings/mapping-MovieFind.json | 10 ++ 9 files changed, 140 insertions(+), 138 deletions(-) delete mode 100644 src/main/java/com/sybit/airtable/AttachementConverter.java create mode 100644 src/test/resources/__files/body-MoviesFind.json create mode 100644 src/test/resources/mappings/mapping-MovieFind.json diff --git a/README.md b/README.md index cf2b229..d9122c4 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,19 @@ Table actorTable = base.table("Actors", Actor.class); Actor actor = actorTable.find("rec514228ed76ced1"); ``` +## Annotations + +Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter. + +### Example +```Java + + import com.google.gson.annotations.SerializedName; + + @SerializedName("First- & Lastname") + private String name; +``` + # Roadmap + [x] Select diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index 7e0f26c..238522c 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -109,7 +109,7 @@ public Airtable configure(String apiKey, String endpointUrl) throws AirtableExce final String httpProxy = System.getenv("http_proxy"); if(httpProxy != null) { LOG.info("Use Proxy: Environment variable 'http_proxy' found and used: " + httpProxy); - Unirest.setProxy(HttpHost.create(httpProxy)); + //Unirest.setProxy(HttpHost.create(httpProxy)); } diff --git a/src/main/java/com/sybit/airtable/AttachementConverter.java b/src/main/java/com/sybit/airtable/AttachementConverter.java deleted file mode 100644 index fb5e1d7..0000000 --- a/src/main/java/com/sybit/airtable/AttachementConverter.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.sybit.airtable; - - -import com.sybit.airtable.vo.Thumbnail; -import org.apache.commons.beanutils.converters.AbstractConverter; - -/** - * - * @author fzr - */ -public class AttachementConverter extends AbstractConverter { - - private String id; - private String url; - private String filename; - private Float size; - private String type; - private Thumbnail thumbnail; - - - @Override - protected T convertToType(Class type, Object value) throws Throwable { - - final Class sourceType = value.getClass(); - - if(value instanceof String){ - - } else { - } - - return null; - } - - @Override - protected Class getDefaultType() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - /** - * @return the id - */ - public String getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(String id) { - this.id = id; - } - - /** - * @return the url - */ - public String getUrl() { - return url; - } - - /** - * @param url the url to set - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * @return the filename - */ - public String getFilename() { - return filename; - } - - /** - * @param filename the filename to set - */ - public void setFilename(String filename) { - this.filename = filename; - } - - /** - * @return the size - */ - public Float getSize() { - return size; - } - - /** - * @param size the size to set - */ - public void setSize(Float size) { - this.size = size; - } - - /** - * @return the type - */ - public String getType() { - return type; - } - - /** - * @param type the type to set - */ - public void setType(String type) { - this.type = type; - } - - /** - * @return the thumbnail - */ - public Thumbnail getThumbnail() { - return thumbnail; - } - - /** - * @param thumbnail the thumbnail to set - */ - public void setThumbnail(Thumbnail thumbnail) { - this.thumbnail = thumbnail; - } - - -} diff --git a/src/main/java/com/sybit/airtable/ListConverter.java b/src/main/java/com/sybit/airtable/ListConverter.java index 5bd33d6..2f54cdf 100644 --- a/src/main/java/com/sybit/airtable/ListConverter.java +++ b/src/main/java/com/sybit/airtable/ListConverter.java @@ -6,11 +6,7 @@ package com.sybit.airtable; import com.google.gson.internal.LinkedTreeMap; -import com.sybit.airtable.vo.Attachment; -import java.lang.reflect.Array; import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.converters.AbstractConverter; diff --git a/src/main/java/com/sybit/airtable/ThumbnailConverter.java b/src/main/java/com/sybit/airtable/ThumbnailConverter.java index d0ecbf9..4357803 100644 --- a/src/main/java/com/sybit/airtable/ThumbnailConverter.java +++ b/src/main/java/com/sybit/airtable/ThumbnailConverter.java @@ -26,12 +26,13 @@ public class ThumbnailConverter extends AbstractConverter{ protected T convertToType(Class type, Object value) throws Throwable { - Object instanz = this.mapClass.newInstance(); + Class sourceType = (Class) value.getClass(); Map returnMap = new HashMap(); if(value instanceof LinkedTreeMap){ for (String key : ((LinkedTreeMap) value).keySet()) { + Object instanz = this.mapClass.newInstance(); Object val = ((LinkedTreeMap) value).get(key); BeanUtils.setProperty(instanz,"name",key); for (String key2 : ((LinkedTreeMap) val).keySet()) { diff --git a/src/test/java/com/sybit/airtable/TableConverterTest.java b/src/test/java/com/sybit/airtable/TableConverterTest.java index b900ba2..810fc9c 100644 --- a/src/test/java/com/sybit/airtable/TableConverterTest.java +++ b/src/test/java/com/sybit/airtable/TableConverterTest.java @@ -9,7 +9,10 @@ import com.sybit.airtable.movies.Actor; import com.sybit.airtable.movies.Movie; import com.sybit.airtable.test.WireMockBaseTest; +import com.sybit.airtable.vo.Attachment; +import com.sybit.airtable.vo.Thumbnail; import java.util.List; +import java.util.Map; import org.apache.http.client.HttpResponseException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -22,14 +25,68 @@ public class TableConverterTest extends WireMockBaseTest { @Test - public void testConvertAttachements() throws AirtableException, HttpResponseException { + public void testConvertMovie() throws AirtableException, HttpResponseException { Base base = airtable.base("appe9941ff07fffcc"); Table movieTable = base.table("Movies", Movie.class); Movie movie = movieTable.find("rec6733da527dd0f1"); assertNotNull(movie); - + + assertEquals(movie.getId(),"rec6733da527dd0f1"); + assertEquals(movie.getName(),"The Godfather"); + assertEquals(movie.getDescription(),"The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selli..."); + assertEquals(movie.getPhotos().size(),2); + assertEquals(movie.getDirector(),"recfaf64fe0db19a9"); + assertEquals(movie.getActors().size(),2); + assertEquals(movie.getGenre().size(),1); + //TODO Test für Datum + + } + + @Test + public void testConvertAttachement() throws AirtableException, HttpResponseException { + + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie movie = movieTable.find("rec6733da527dd0f1"); + assertNotNull(movie); + + assertEquals(movie.getPhotos().size(),2); + + Attachment photo1 = movie.getPhotos().get(0); + assertNotNull(photo1); + Attachment photo2 = movie.getPhotos().get(0); + assertNotNull(photo2); + + assertEquals(photo1.getId(),"att6dba4af5786df1"); + assertEquals(photo1.getUrl(),"https://www.filepicker.io/api/file/akW7wUX7QM66a2hjxb9k"); + assertEquals(photo1.getFilename(),"220px-TheGodfatherAlPacinoMarlonBrando.jpg"); + assertEquals(photo1.getSize(),16420.0,0); + assertEquals(photo1.getType(),"image/jpeg"); + assertEquals(photo1.getThumbnails().size(),2); + + } + + @Test + public void testConvertThumbnails() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie movie = movieTable.find("rec6733da527dd0f1"); + assertNotNull(movie); + + assertEquals(movie.getPhotos().get(0).getThumbnails().size(),2); + assertEquals(movie.getPhotos().get(1).getThumbnails().size(),2); + Map thumbnails = movie.getPhotos().get(1).getThumbnails(); + Thumbnail thumb = thumbnails.get("small"); + assertEquals(thumb.getUrl(),"https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg"); + assertEquals(thumb.getHeight(),36.0, 0); + assertEquals(thumb.getWidth(),48.0, 0); + } } diff --git a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java index 2b39a60..a195117 100644 --- a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java +++ b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java @@ -31,7 +31,7 @@ public class WireMockBaseTest { @Before public void setup() throws AirtableException { airtable.configure(); - //airtable.setEndpointUrl("http://localhost:8080/v0"); + airtable.setEndpointUrl("http://localhost:8080/v0"); //set 404 as default stubFor(any(anyUrl()) diff --git a/src/test/resources/__files/body-MoviesFind.json b/src/test/resources/__files/body-MoviesFind.json new file mode 100644 index 0000000..4c01308 --- /dev/null +++ b/src/test/resources/__files/body-MoviesFind.json @@ -0,0 +1,54 @@ +{ + "id": "rec6733da527dd0f1", + "fields": { + "Name": "The Godfather", + "Description": "The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selli...", + "Photos": [ + { + "id": "att6dba4af5786df1", + "url": "https://www.filepicker.io/api/file/akW7wUX7QM66a2hjxb9k", + "filename": "220px-TheGodfatherAlPacinoMarlonBrando.jpg", + "size": 16420, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://www.filepicker.io/api/file/XvbySDtbSxymbbUJzCoN" + }, + "large": { + "url": "https://www.filepicker.io/api/file/Fpc86btaS1Stl79SvHX4" + } + } + }, + { + "id": "attzWvarnmYBBd2Wm", + "url": "https://dl.airtable.com/jJqBm304SBWBrF3dXn12_Lighthouse.jpg", + "filename": "Lighthouse.jpg", + "size": 561276, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg", + "width": 48, + "height": 36 + }, + "large": { + "url": "https://dl.airtable.com/8QX7f3nSAe6lrOxeuvTP_large_Lighthouse.jpg", + "width": 512, + "height": 512 + } + } + } + ], + "Actors": [ + "recc8841a14245b0b", + "rec514228ed76ced1" + ], + "Director": [ + "recfaf64fe0db19a9" + ], + "Genre": [ + "Drama" + ] + }, + "createdTime": "2014-07-18T04:42:06.000Z" + } \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-MovieFind.json b/src/test/resources/mappings/mapping-MovieFind.json new file mode 100644 index 0000000..326b51b --- /dev/null +++ b/src/test/resources/mappings/mapping-MovieFind.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies/rec6733da527dd0f1", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-MoviesFind.json" + } +} \ No newline at end of file From b8e2a13f8035e163b94c8be50881eecd241b1b6d Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 24 Mar 2017 15:48:56 +0100 Subject: [PATCH 03/74] Documentation --- .../com/sybit/airtable/ListConverter.java | 57 +++++++++++++++---- .../sybit/airtable/ThumbnailConverter.java | 39 ++++++++++++- .../sybit/airtable/TableConverterTest.java | 2 + 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/sybit/airtable/ListConverter.java b/src/main/java/com/sybit/airtable/ListConverter.java index 2f54cdf..c531664 100644 --- a/src/main/java/com/sybit/airtable/ListConverter.java +++ b/src/main/java/com/sybit/airtable/ListConverter.java @@ -12,6 +12,12 @@ import org.apache.commons.beanutils.converters.AbstractConverter; /** + * + * org.apache.commons.beanutils.Converter implementaion + * that handles conversion to and from List objects. + * + * This implementation converts List to List. + * The innerClass can be set to the Class that is needed. * * @author fzr */ @@ -19,11 +25,32 @@ public class ListConverter extends AbstractConverter { private Class listClass; + /** + * + * Method overwritten so it doesent return only the first Element of the Array. + * + * @param value + * @return value + */ @Override protected Object convertArray(final Object value) { return value; } + /** + * + * Convert the Input Object into a List of Attachements + * + * This Method handles the conversion from a List of LinkedHashMaps to a List of Attachement Objects. + * + * If the Input Object is no List or the List Item is no LinkedHashMap everything will be converted into a (List?) String. + * + * @param + * @param type + * @param value + * @return + * @throws Throwable + */ @Override protected T convertToType(final Class type, Object value) throws Throwable { @@ -32,7 +59,7 @@ protected T convertToType(final Class type, Object value) throws Throwabl if(value instanceof List){ for (T item: ((List) value)){ if(item instanceof LinkedTreeMap){ - Object instanz = this.getListClass().newInstance(); + Object instanz = this.listClass.newInstance(); for (String key : ((LinkedTreeMap) item).keySet()) { Object val = ((LinkedTreeMap) item).get(key); BeanUtils.setProperty(instanz,key,val); @@ -61,6 +88,14 @@ protected T convertToType(final Class type, Object value) throws Throwabl return (T) toStringList(value.getClass(),stringValue,returnList); } + /** + * Default toString conversion + * + * @param type + * @param value + * @param returnList + * @return + */ private List toStringList(final Class type, final String value,List returnList) { if (type.equals(String.class)) { @@ -72,6 +107,15 @@ private List toStringList(final Class type, final String value,List returnList) return returnList; } + /** + * Default conversion to specified Class. + * If conversion is not possible default toString. + * + * @param type + * @param value + * @param returnList + * @return + */ private List toClassList(final Class type, final Object value, List returnList) { if (type.equals(LinkedTreeMap.class)) { @@ -82,22 +126,13 @@ private List toClassList(final Class type, final Object value, List returnList) return toStringList(type,value.toString(),returnList); } - /** - * @return the listClass - */ - public Class getListClass() { - return listClass; - } - /** * @param listClass the listClass to set */ public void setListClass(Class listClass) { this.listClass = listClass; } - - - + //TODO Default überlegen @Override protected Class getDefaultType() { diff --git a/src/main/java/com/sybit/airtable/ThumbnailConverter.java b/src/main/java/com/sybit/airtable/ThumbnailConverter.java index 4357803..2663e13 100644 --- a/src/main/java/com/sybit/airtable/ThumbnailConverter.java +++ b/src/main/java/com/sybit/airtable/ThumbnailConverter.java @@ -16,17 +16,31 @@ /** * + * org.apache.commons.beanutils.Converter implementaion + * that handles conversion to and from Map objects. + * + * This implementation converts Map to Map. + * The mapClass can be set to the Class that is needed. + * * @author fzr */ public class ThumbnailConverter extends AbstractConverter{ private Class mapClass; + /** + * + * Converts the Input Object into a Map. + * + * @param + * @param type + * @param value + * @return + * @throws Throwable + */ @Override protected T convertToType(Class type, Object value) throws Throwable { - - - + Class sourceType = (Class) value.getClass(); Map returnMap = new HashMap(); @@ -56,6 +70,15 @@ protected T convertToType(Class type, Object value) throws Throwable { return (T) toStringMap(sourceType,stringValue,returnMap); } + /** + * + * Default Conversion to specified Class. + * + * @param type + * @param value + * @param returnMap + * @return + */ private Map toClassMap(final Class type, final Object value,Map returnMap) { if (type.equals(LinkedTreeMap.class)) { @@ -68,6 +91,16 @@ private Map toClassMap(final Class type, final Object value,Map toStringMap(final Class type, final String value,Map returnMap) { List returnList = new ArrayList(); diff --git a/src/test/java/com/sybit/airtable/TableConverterTest.java b/src/test/java/com/sybit/airtable/TableConverterTest.java index 810fc9c..d08d449 100644 --- a/src/test/java/com/sybit/airtable/TableConverterTest.java +++ b/src/test/java/com/sybit/airtable/TableConverterTest.java @@ -24,6 +24,8 @@ */ public class TableConverterTest extends WireMockBaseTest { + //TODO Test für nicht gülitiges bzw String + @Test public void testConvertMovie() throws AirtableException, HttpResponseException { From a13bc4f4040d0b8780e415fc6aff2db63a681585 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 24 Mar 2017 16:20:51 +0100 Subject: [PATCH 04/74] Changes in Documentation --- .../java/com/sybit/airtable/Airtable.java | 14 +++---- .../com/sybit/airtable/ListConverter.java | 41 ++++++++++--------- .../sybit/airtable/ThumbnailConverter.java | 29 +++++++------ 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index 437667f..0b80215 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -6,29 +6,26 @@ */ package com.sybit.airtable; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.internal.LinkedTreeMap; -import com.mashape.unirest.http.ObjectMapper; + import com.mashape.unirest.http.Unirest; import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.vo.Attachment; import com.sybit.airtable.vo.Thumbnail; + +import org.apache.http.HttpHost; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.converters.DateConverter; import org.apache.commons.beanutils.converters.DateTimeConverter; -import org.apache.http.HttpHost; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; -import org.apache.http.HttpHost; + /** * Representation Class of Airtable. @@ -57,6 +54,7 @@ public class Airtable { * or within credentials.properties. * * @return configured Airtable object. + * @throws com.sybit.airtable.exception.AirtableException Missing API-Key */ @SuppressWarnings("UnusedReturnValue") public Airtable configure() throws AirtableException { @@ -82,6 +80,7 @@ public Airtable configure() throws AirtableException { * * @param apiKey API-Key of Airtable. * @return + * @throws com.sybit.airtable.exception.AirtableException Missing API-Key */ @SuppressWarnings("WeakerAccess") public Airtable configure(String apiKey) throws AirtableException { @@ -93,6 +92,7 @@ public Airtable configure(String apiKey) throws AirtableException { * @param apiKey * @param endpointUrl * @return + * @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint */ @SuppressWarnings("WeakerAccess") public Airtable configure(String apiKey, String endpointUrl) throws AirtableException { diff --git a/src/main/java/com/sybit/airtable/ListConverter.java b/src/main/java/com/sybit/airtable/ListConverter.java index c531664..dab26b7 100644 --- a/src/main/java/com/sybit/airtable/ListConverter.java +++ b/src/main/java/com/sybit/airtable/ListConverter.java @@ -6,6 +6,7 @@ package com.sybit.airtable; import com.google.gson.internal.LinkedTreeMap; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; @@ -14,10 +15,10 @@ /** * * org.apache.commons.beanutils.Converter implementaion - * that handles conversion to and from List objects. + * that handles conversion to and from List<T> objects. * - * This implementation converts List to List. - * The innerClass can be set to the Class that is needed. + *

This implementation converts List<T> to List<innerClass>. + * The innerClass can be set to the Class that is needed.

* * @author fzr */ @@ -29,8 +30,8 @@ public class ListConverter extends AbstractConverter { * * Method overwritten so it doesent return only the first Element of the Array. * - * @param value - * @return value + * @param value The Input Value + * @return value The value to be returned */ @Override protected Object convertArray(final Object value) { @@ -43,16 +44,17 @@ protected Object convertArray(final Object value) { * * This Method handles the conversion from a List of LinkedHashMaps to a List of Attachement Objects. * - * If the Input Object is no List or the List Item is no LinkedHashMap everything will be converted into a (List?) String. + *

If the Input Object is no List or the List Item is no LinkedHashMap everything will be converted into a (List?) String.

* - * @param - * @param type - * @param value - * @return - * @throws Throwable + * @param type The type of the Input Object + * @param value The value of the Input Object + * @return A List + * @throws java.lang.InstantiationException If no Instance of the listClass can be instantiated + * @throws java.lang.IllegalAccessException If the Object can't be accest + * @throws java.lang.reflect.InvocationTargetException If th Target can't be accessed */ @Override - protected T convertToType(final Class type, Object value) throws Throwable { + protected T convertToType(final Class type, Object value) throws InstantiationException, IllegalAccessException, InvocationTargetException { List returnList = new ArrayList(); @@ -91,9 +93,9 @@ protected T convertToType(final Class type, Object value) throws Throwabl /** * Default toString conversion * - * @param type - * @param value - * @param returnList + * @param type The type of the Class + * @param value The String value + * @param returnList A List of all currently converted Objects * @return */ private List toStringList(final Class type, final String value,List returnList) { @@ -109,11 +111,12 @@ private List toStringList(final Class type, final String value,List returnList) /** * Default conversion to specified Class. - * If conversion is not possible default toString. * - * @param type - * @param value - * @param returnList + *

If conversion is not possible default toString.

+ * + * @param type The type of the Class + * @param value The value of the Input Object + * @param returnList A List of all currently converted Objects * @return */ private List toClassList(final Class type, final Object value, List returnList) { diff --git a/src/main/java/com/sybit/airtable/ThumbnailConverter.java b/src/main/java/com/sybit/airtable/ThumbnailConverter.java index 2663e13..5c1bf39 100644 --- a/src/main/java/com/sybit/airtable/ThumbnailConverter.java +++ b/src/main/java/com/sybit/airtable/ThumbnailConverter.java @@ -17,9 +17,9 @@ /** * * org.apache.commons.beanutils.Converter implementaion - * that handles conversion to and from Map objects. + * that handles conversion to and from Map<String,T> objects. * - * This implementation converts Map to Map. + * This implementation converts Map<String,T> to Map. * The mapClass can be set to the Class that is needed. * * @author fzr @@ -29,13 +29,12 @@ public class ThumbnailConverter extends AbstractConverter{ private Class mapClass; /** - * * Converts the Input Object into a Map. * - * @param - * @param type - * @param value - * @return + * + * @param type The type of the Input Object + * @param value The value of the Input Object + * @return A Map * @throws Throwable */ @Override @@ -74,10 +73,10 @@ protected T convertToType(Class type, Object value) throws Throwable { * * Default Conversion to specified Class. * - * @param type - * @param value - * @param returnMap - * @return + * @param type The Class of the type + * @param value The value of the Object + * @param returnMap A Map of all currently converted Objects + * @return A Map */ private Map toClassMap(final Class type, final Object value,Map returnMap) { @@ -95,10 +94,10 @@ private Map toClassMap(final Class type, final Object value,Map toStringMap(final Class type, final String value,Map returnMap) { From 5d3e719d924f5fba80c20ca9fd93f165b6044d31 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 24 Mar 2017 16:24:00 +0100 Subject: [PATCH 05/74] Renamed Thumbnail Converter --- src/main/java/com/sybit/airtable/Airtable.java | 2 +- .../airtable/{ThumbnailConverter.java => MapConverter.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/java/com/sybit/airtable/{ThumbnailConverter.java => MapConverter.java} (98%) diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index 0b80215..e562845 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -115,7 +115,7 @@ public Airtable configure(String apiKey, String endpointUrl) throws AirtableExce // Add specific Converter for Date DateTimeConverter dtConverter = new DateConverter(); ListConverter lConverter = new ListConverter(); - ThumbnailConverter thConverter = new ThumbnailConverter(); + MapConverter thConverter = new MapConverter(); lConverter.setListClass(Attachment.class); thConverter.setMapClass(Thumbnail.class); diff --git a/src/main/java/com/sybit/airtable/ThumbnailConverter.java b/src/main/java/com/sybit/airtable/MapConverter.java similarity index 98% rename from src/main/java/com/sybit/airtable/ThumbnailConverter.java rename to src/main/java/com/sybit/airtable/MapConverter.java index 5c1bf39..4999346 100644 --- a/src/main/java/com/sybit/airtable/ThumbnailConverter.java +++ b/src/main/java/com/sybit/airtable/MapConverter.java @@ -24,7 +24,7 @@ * * @author fzr */ -public class ThumbnailConverter extends AbstractConverter{ +public class MapConverter extends AbstractConverter{ private Class mapClass; From ae2ed0a74d547277e6f021321fcc9661b328cacd Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 24 Mar 2017 16:30:46 +0100 Subject: [PATCH 06/74] Documentation changes --- src/main/java/com/sybit/airtable/Airtable.java | 2 ++ src/main/java/com/sybit/airtable/ListConverter.java | 6 +++--- src/main/java/com/sybit/airtable/MapConverter.java | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index e562845..4ad73f0 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -154,6 +154,7 @@ private void setProxy(String endpointUrl) { * Getting the base by given property AIRTABLE_BASE. * * @return the base object. + * @throws com.sybit.airtable.exception.AirtableException Missing Airtable_BASE */ public Base base() throws AirtableException { @@ -175,6 +176,7 @@ public Base base() throws AirtableException { * Builder method to create base of given base id. * @param base the base id. * @return + * @throws com.sybit.airtable.exception.AirtableException AIRTABLE_BASE was Null */ public Base base(String base) throws AirtableException { if(base == null) { diff --git a/src/main/java/com/sybit/airtable/ListConverter.java b/src/main/java/com/sybit/airtable/ListConverter.java index dab26b7..29b7537 100644 --- a/src/main/java/com/sybit/airtable/ListConverter.java +++ b/src/main/java/com/sybit/airtable/ListConverter.java @@ -56,7 +56,7 @@ protected Object convertArray(final Object value) { @Override protected T convertToType(final Class type, Object value) throws InstantiationException, IllegalAccessException, InvocationTargetException { - List returnList = new ArrayList(); + List returnList = new ArrayList<>(); if(value instanceof List){ for (T item: ((List) value)){ @@ -96,7 +96,7 @@ protected T convertToType(final Class type, Object value) throws Instanti * @param type The type of the Class * @param value The String value * @param returnList A List of all currently converted Objects - * @return + * @return A List */ private List toStringList(final Class type, final String value,List returnList) { @@ -117,7 +117,7 @@ private List toStringList(final Class type, final String value,List returnList) * @param type The type of the Class * @param value The value of the Input Object * @param returnList A List of all currently converted Objects - * @return + * @return A List */ private List toClassList(final Class type, final Object value, List returnList) { diff --git a/src/main/java/com/sybit/airtable/MapConverter.java b/src/main/java/com/sybit/airtable/MapConverter.java index 4999346..5e7d462 100644 --- a/src/main/java/com/sybit/airtable/MapConverter.java +++ b/src/main/java/com/sybit/airtable/MapConverter.java @@ -19,8 +19,8 @@ * org.apache.commons.beanutils.Converter implementaion * that handles conversion to and from Map<String,T> objects. * - * This implementation converts Map<String,T> to Map. - * The mapClass can be set to the Class that is needed. + *

This implementation converts Map<String,T> to Map<String,mapClass>. + * The mapClass can be set to the Class that is needed.

* * @author fzr */ @@ -41,7 +41,7 @@ public class MapConverter extends AbstractConverter{ protected T convertToType(Class type, Object value) throws Throwable { Class sourceType = (Class) value.getClass(); - Map returnMap = new HashMap(); + Map returnMap = new HashMap<>(); if(value instanceof LinkedTreeMap){ for (String key : ((LinkedTreeMap) value).keySet()) { From 987b1e91d238c4e58ff0645df280e87816e22ed9 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 28 Mar 2017 08:06:51 +0200 Subject: [PATCH 07/74] Dokumentation --- src/main/java/com/sybit/airtable/MapConverter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/sybit/airtable/MapConverter.java b/src/main/java/com/sybit/airtable/MapConverter.java index 5e7d462..2fa914b 100644 --- a/src/main/java/com/sybit/airtable/MapConverter.java +++ b/src/main/java/com/sybit/airtable/MapConverter.java @@ -118,6 +118,11 @@ protected Class getDefaultType() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + /** + * Set-Method for the MapClass + * + * @param aClass The Parameter that is used + */ void setMapClass(Class aClass) { this.mapClass = aClass; } From db891308b6794bd55de13af98482639c03953350 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 28 Mar 2017 09:30:54 +0200 Subject: [PATCH 08/74] Codacy Improvements --- src/main/java/com/sybit/airtable/GsonObjectMapper.java | 2 +- src/main/java/com/sybit/airtable/MapConverter.java | 10 +++++----- src/main/java/com/sybit/airtable/vo/Thumbnail.java | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/sybit/airtable/GsonObjectMapper.java b/src/main/java/com/sybit/airtable/GsonObjectMapper.java index f1a4d14..7a21986 100644 --- a/src/main/java/com/sybit/airtable/GsonObjectMapper.java +++ b/src/main/java/com/sybit/airtable/GsonObjectMapper.java @@ -17,7 +17,7 @@ */ class GsonObjectMapper implements ObjectMapper{ private static final Logger LOG = Logger.getLogger( GsonObjectMapper.class.getName() ); - final Gson gson; + private final Gson gson; public GsonObjectMapper() { gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create(); diff --git a/src/main/java/com/sybit/airtable/MapConverter.java b/src/main/java/com/sybit/airtable/MapConverter.java index 2fa914b..ee37080 100644 --- a/src/main/java/com/sybit/airtable/MapConverter.java +++ b/src/main/java/com/sybit/airtable/MapConverter.java @@ -105,12 +105,12 @@ private Map toStringMap(final Class type, final String value,Map< List returnList = new ArrayList(); if (type.equals(String.class)) { - returnList.add(type.cast(String.valueOf(value))); - return (Map) returnList; + returnMap.put(value,value); + return returnMap; } - returnList.add(type.cast(String.valueOf(value))); - return (Map) returnList; + returnMap.put(value,value); + return returnMap; } @Override @@ -123,7 +123,7 @@ protected Class getDefaultType() { * * @param aClass The Parameter that is used */ - void setMapClass(Class aClass) { + public void setMapClass(Class aClass) { this.mapClass = aClass; } diff --git a/src/main/java/com/sybit/airtable/vo/Thumbnail.java b/src/main/java/com/sybit/airtable/vo/Thumbnail.java index 5e2f203..ba782cd 100644 --- a/src/main/java/com/sybit/airtable/vo/Thumbnail.java +++ b/src/main/java/com/sybit/airtable/vo/Thumbnail.java @@ -5,8 +5,6 @@ */ package com.sybit.airtable.vo; -import java.util.List; -import java.util.Map; /** * From 50e3d8d6a113dae14e6f4eb381c800a41051d3c8 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 28 Mar 2017 09:41:34 +0200 Subject: [PATCH 09/74] Codacy --- src/main/java/com/sybit/airtable/MapConverter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/sybit/airtable/MapConverter.java b/src/main/java/com/sybit/airtable/MapConverter.java index ee37080..99616f0 100644 --- a/src/main/java/com/sybit/airtable/MapConverter.java +++ b/src/main/java/com/sybit/airtable/MapConverter.java @@ -101,9 +101,7 @@ private Map toClassMap(final Class type, final Object value,Map toStringMap(final Class type, final String value,Map returnMap) { - - List returnList = new ArrayList(); - + if (type.equals(String.class)) { returnMap.put(value,value); return returnMap; From 5912b68f4be9c8ec72607903e53fc7b963fada7d Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 28 Mar 2017 10:11:31 +0200 Subject: [PATCH 10/74] Codacy --- src/main/java/com/sybit/airtable/MapConverter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/sybit/airtable/MapConverter.java b/src/main/java/com/sybit/airtable/MapConverter.java index 99616f0..99638c1 100644 --- a/src/main/java/com/sybit/airtable/MapConverter.java +++ b/src/main/java/com/sybit/airtable/MapConverter.java @@ -7,9 +7,7 @@ import com.google.gson.internal.LinkedTreeMap; import com.sybit.airtable.vo.Thumbnail; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.converters.AbstractConverter; From dbcaa004fc3b7148f96d41aecbc8ceed577e9e08 Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 29 Mar 2017 10:23:17 +0200 Subject: [PATCH 11/74] moved converter to subpackage --- src/main/java/com/sybit/airtable/Airtable.java | 2 ++ src/main/java/com/sybit/airtable/Base.java | 2 +- src/main/java/com/sybit/airtable/GsonObjectMapper.java | 5 +++-- src/main/java/com/sybit/airtable/Query.java | 4 +++- src/main/java/com/sybit/airtable/Table.java | 6 +++--- .../sybit/airtable/{ => converter}/ListConverter.java | 10 ++++++---- .../sybit/airtable/{ => converter}/MapConverter.java | 2 +- 7 files changed, 19 insertions(+), 12 deletions(-) rename src/main/java/com/sybit/airtable/{ => converter}/ListConverter.java (98%) rename src/main/java/com/sybit/airtable/{ => converter}/MapConverter.java (99%) diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index 4ad73f0..f63c65c 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -8,6 +8,8 @@ import com.mashape.unirest.http.Unirest; +import com.sybit.airtable.converter.ListConverter; +import com.sybit.airtable.converter.MapConverter; import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.vo.Attachment; import com.sybit.airtable.vo.Thumbnail; diff --git a/src/main/java/com/sybit/airtable/Base.java b/src/main/java/com/sybit/airtable/Base.java index f413ab3..626da80 100644 --- a/src/main/java/com/sybit/airtable/Base.java +++ b/src/main/java/com/sybit/airtable/Base.java @@ -53,7 +53,7 @@ public Base(String base, Airtable airtable) { * Set Airtable object as parent. * @param parent the base Airtable object. */ - protected void setParent(Airtable parent) { + void setParent(Airtable parent) { this.parent = parent; } diff --git a/src/main/java/com/sybit/airtable/GsonObjectMapper.java b/src/main/java/com/sybit/airtable/GsonObjectMapper.java index 7a21986..1fc5ee0 100644 --- a/src/main/java/com/sybit/airtable/GsonObjectMapper.java +++ b/src/main/java/com/sybit/airtable/GsonObjectMapper.java @@ -15,7 +15,7 @@ * * @author fzr */ -class GsonObjectMapper implements ObjectMapper{ +class GsonObjectMapper implements ObjectMapper { private static final Logger LOG = Logger.getLogger( GsonObjectMapper.class.getName() ); private final Gson gson; @@ -25,11 +25,12 @@ public GsonObjectMapper() { } public T readValue(String value, Class valueType) { - LOG.log(Level.INFO, "readValue: \n" + value); + LOG.log(Level.FINE, "readValue: \n" + value); return gson.fromJson(value, valueType); } public String writeValue(Object value) { + LOG.log(Level.FINE, "writeValue: \n" + value); return gson.toJson(value); } diff --git a/src/main/java/com/sybit/airtable/Query.java b/src/main/java/com/sybit/airtable/Query.java index 16b069c..f884b1b 100644 --- a/src/main/java/com/sybit/airtable/Query.java +++ b/src/main/java/com/sybit/airtable/Query.java @@ -29,8 +29,10 @@ public interface Query { List getSort(); /** + * Define a filter formula. * - * @return + * @see https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference + * @return get the filter formula. */ String filterByFormula(); } diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index d1db3cd..3f59e66 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -110,7 +110,7 @@ public String filterByFormula() { * @throws HttpResponseException */ @SuppressWarnings("WeakerAccess") - public List select(Query query) throws AirtableException, HttpResponseException { + public List select(Query query) throws AirtableException { HttpResponse response; try { GetRequest request = Unirest.get(getTableEndpointUrl()) @@ -272,7 +272,7 @@ private List getList(HttpResponse response) { * @return searched record. * @throws AirtableException */ - public T find(String id) throws AirtableException, HttpResponseException { + public T find(String id) throws AirtableException { RecordItem body = null; @@ -423,7 +423,7 @@ private void setProperty(T retval, String key, Object value) throws IllegalAcces private String key2property(String key) { if(key.contains(" ") || key.contains("-") ) { - LOG.warn( "Annotate special characters using @SerializedName for property: [" + key + "]"); + LOG.warn( "Annotate columns having special characters by using @SerializedName for property: [" + key + "]"); } String property = key.trim(); property = property.substring(0,1).toLowerCase() + property.substring(1, property.length()); diff --git a/src/main/java/com/sybit/airtable/ListConverter.java b/src/main/java/com/sybit/airtable/converter/ListConverter.java similarity index 98% rename from src/main/java/com/sybit/airtable/ListConverter.java rename to src/main/java/com/sybit/airtable/converter/ListConverter.java index 29b7537..3ce02c3 100644 --- a/src/main/java/com/sybit/airtable/ListConverter.java +++ b/src/main/java/com/sybit/airtable/converter/ListConverter.java @@ -3,14 +3,15 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package com.sybit.airtable; +package com.sybit.airtable.converter; import com.google.gson.internal.LinkedTreeMap; +import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.beanutils.converters.AbstractConverter; + import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; -import org.apache.commons.beanutils.BeanUtils; -import org.apache.commons.beanutils.converters.AbstractConverter; /** * @@ -99,7 +100,8 @@ protected T convertToType(final Class type, Object value) throws Instanti * @return A List */ private List toStringList(final Class type, final String value,List returnList) { - + + //FIXME why this if? if (type.equals(String.class)) { returnList.add(String.valueOf(value)); return returnList; diff --git a/src/main/java/com/sybit/airtable/MapConverter.java b/src/main/java/com/sybit/airtable/converter/MapConverter.java similarity index 99% rename from src/main/java/com/sybit/airtable/MapConverter.java rename to src/main/java/com/sybit/airtable/converter/MapConverter.java index 99638c1..390e37d 100644 --- a/src/main/java/com/sybit/airtable/MapConverter.java +++ b/src/main/java/com/sybit/airtable/converter/MapConverter.java @@ -3,7 +3,7 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package com.sybit.airtable; +package com.sybit.airtable.converter; import com.google.gson.internal.LinkedTreeMap; import com.sybit.airtable.vo.Thumbnail; From 4d7b01d3519a3c74115d007f335a33c7212461e2 Mon Sep 17 00:00:00 2001 From: fzr Date: Thu, 30 Mar 2017 10:00:10 +0200 Subject: [PATCH 12/74] Implemented Destroy Method with Tests Added Test Specific Files, New Class Delete to handle Delete Responses, Implemented Method in Table, Added Attributes to Actor Class --- src/main/java/com/sybit/airtable/Table.java | 26 +++++- .../java/com/sybit/airtable/vo/Delete.java | 47 +++++++++++ .../com/sybit/airtable/TableDestroyTest.java | 43 ++++++++++ .../java/com/sybit/airtable/movies/Actor.java | 36 +++++++- .../resources/__files/body-ActorDelete.json | 4 + src/test/resources/__files/body-Actors.json | 84 +++++++++++++------ .../mappings/mapping-ActorDelete.json | 10 +++ 7 files changed, 221 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/sybit/airtable/vo/Delete.java create mode 100644 src/test/java/com/sybit/airtable/TableDestroyTest.java create mode 100644 src/test/resources/__files/body-ActorDelete.json create mode 100644 src/test/resources/mappings/mapping-ActorDelete.json diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 3f59e66..55fcf54 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -13,6 +13,7 @@ import com.mashape.unirest.request.GetRequest; import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.exception.HttpResponseExceptionHandler; +import com.sybit.airtable.vo.Delete; import com.sybit.airtable.vo.RecordItem; import com.sybit.airtable.vo.Records; import org.apache.commons.beanutils.BeanUtils; @@ -317,9 +318,30 @@ public T replace(T item) { throw new UnsupportedOperationException("not yet implemented"); } - public T destroy(T item) { + public void destroy(String id) throws AirtableException { + + Delete body = null; - throw new UnsupportedOperationException("not yet implemented"); + HttpResponse response; + try { + response = Unirest.delete(getTableEndpointUrl() + "/" + id) + .header("accept", "application/json") + .header("Authorization", getBearerToken()) + .asObject(Delete.class); + } catch (UnirestException e) { + throw new AirtableException(e); + } + int code = response.getStatus(); + + if(200 == code) { + body = response.getBody(); + } else { + HttpResponseExceptionHandler.onResponse(response); + } + + if(!body.isDeleted()){ + throw new AirtableException("Record id: "+body.getId()+" could not be deleted."); + } } /** diff --git a/src/main/java/com/sybit/airtable/vo/Delete.java b/src/main/java/com/sybit/airtable/vo/Delete.java new file mode 100644 index 0000000..9cd0c79 --- /dev/null +++ b/src/main/java/com/sybit/airtable/vo/Delete.java @@ -0,0 +1,47 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable.vo; + +/** + * + * @author fzr + */ +public class Delete { + + private boolean deleted; + private String id; + + /** + * @return the deleted + */ + public boolean isDeleted() { + return deleted; + } + + /** + * @param deleted the deleted to set + */ + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + + +} diff --git a/src/test/java/com/sybit/airtable/TableDestroyTest.java b/src/test/java/com/sybit/airtable/TableDestroyTest.java new file mode 100644 index 0000000..833a8c1 --- /dev/null +++ b/src/test/java/com/sybit/airtable/TableDestroyTest.java @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable; + +import com.sybit.airtable.exception.AirtableException; +import com.sybit.airtable.movies.Actor; +import com.sybit.airtable.test.WireMockBaseTest; +import java.util.List; +import org.apache.http.client.HttpResponseException; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author fzr + */ +public class TableDestroyTest extends WireMockBaseTest { + + + + @Test + public void testDestroyMovie() throws AirtableException, HttpResponseException{ + + Base base = airtable.base("appe9941ff07fffcc"); + Table actorTable = base.table("Actors", Actor.class); + + actorTable.destroy("recapJ3Js8AEwt0Bf"); + + } + + @Test (expected = AirtableException.class) + public void testDestroyMovieException() throws AirtableException{ + + Base base = airtable.base("appe9941ff07fffcc"); + Table actorTable = base.table("Actors", Actor.class); + + actorTable.destroy("not succesfull"); + } + +} diff --git a/src/test/java/com/sybit/airtable/movies/Actor.java b/src/test/java/com/sybit/airtable/movies/Actor.java index ec3366b..912edd1 100644 --- a/src/test/java/com/sybit/airtable/movies/Actor.java +++ b/src/test/java/com/sybit/airtable/movies/Actor.java @@ -6,13 +6,19 @@ */ package com.sybit.airtable.movies; -import com.google.gson.annotations.SerializedName; + +import com.sybit.airtable.vo.Attachment; +import java.util.List; public class Actor { private String id; - @SerializedName("Name") private String name; + private List Photo; + private String Biography; + private String[] Filmography; + + public String getId() { return id; @@ -29,4 +35,30 @@ public String getName() { public void setName(String name) { this.name = name; } + + public String[] getFilmography() { + return Filmography; + } + + public void setFilmography(String[] Filmography) { + this.Filmography = Filmography; + } + + public List getPhoto() { + return Photo; + } + + public void setPhoto(List Photo) { + this.Photo = Photo; + } + + public String getBiography() { + return Biography; + } + + public void setBiography(String Biography) { + this.Biography = Biography; + } + + } diff --git a/src/test/resources/__files/body-ActorDelete.json b/src/test/resources/__files/body-ActorDelete.json new file mode 100644 index 0000000..87c5f5a --- /dev/null +++ b/src/test/resources/__files/body-ActorDelete.json @@ -0,0 +1,4 @@ +{ + "deleted": true, + "id": "recapJ3Js8AEwt0Bf" +} \ No newline at end of file diff --git a/src/test/resources/__files/body-Actors.json b/src/test/resources/__files/body-Actors.json index 6c359ff..180e780 100644 --- a/src/test/resources/__files/body-Actors.json +++ b/src/test/resources/__files/body-Actors.json @@ -1,28 +1,62 @@ { - "id": "rec514228ed76ced1", - "fields": { - "Name": "Marlon Brando", - "Filmography": [ - "rec6733da527dd0f1" - ], - "Photo": [ - { - "id": "att1b7c05d697c0c1", - "url": "https://www.filepicker.io/api/file/xlhctgHEQiSGNc0ieMec", - "filename": "220px-Marlon_Brando_-_The_Wild_One.jpg", - "size": 13845, - "type": "image/jpeg", - "thumbnails": { - "small": { - "url": "https://www.filepicker.io/api/file/Rh3L1DL7QAe8nleanQVV" - }, - "large": { - "url": "https://www.filepicker.io/api/file/hcrLCStVRX6LNVEHqtXA" - } + "records": [ + { + "id": "rec514228ed76ced1", + "fields": { + "Name": "Marlon Brando", + "Filmography": [ + "rec6733da527dd0f1" + ], + "Photo": [ + { + "id": "att1b7c05d697c0c1", + "url": "https://www.filepicker.io/api/file/xlhctgHEQiSGNc0ieMec", + "filename": "220px-Marlon_Brando_-_The_Wild_One.jpg", + "size": 13845, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://www.filepicker.io/api/file/Rh3L1DL7QAe8nleanQVV" + }, + "large": { + "url": "https://www.filepicker.io/api/file/hcrLCStVRX6LNVEHqtXA" + } + } + } + ], + "Biography": "Marlon Brando, Jr. (April 3, 1924 – July 1, 2004) was an American actor. He is hailed for bringing a gripping realism to film acting, and is widely co..." + }, + "createdTime": "2014-07-18T04:48:25.000Z" + }, + { + "id":"recapJ3Js8AEwt0Bf", + "fields": { + "Name":"Test Actor", + "Photo": [ + { + "id":"attfbHPN3hRjTYk3U", + "url":"https://dl.airtable.com/eJd6UGPPTmGPvoTjpP57_Penguins.jpg", + "filename":"Penguins.jpg","size":777835,"type":"image/jpeg", + "thumbnails": { + "small": { + "url":"https://dl.airtable.com/mzOeWfo7RkiX8ueW14gi_small_Penguins.jpg", + "width":48, + "height":36 + }, + "large": { + "url":"https://dl.airtable.com/dMgnXtMrSDKSAQTQqYHa_large_Penguins.jpg", + "width":512, + "height":512 + } + } + } + ], + "Biography":"Test Bio", + "Filmography": [ + "rec6733da527dd0f1" + ] + }, + "createdTime":"2017-03-30T06:47:38.520Z" } - } - ], - "Biography": "Marlon Brando, Jr. (April 3, 1924 – July 1, 2004) was an American actor. He is hailed for bringing a gripping realism to film acting, and is widely co..." - }, - "createdTime": "2014-07-18T04:48:25.000Z" + ] } \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ActorDelete.json b/src/test/resources/mappings/mapping-ActorDelete.json new file mode 100644 index 0000000..0ce8f0e --- /dev/null +++ b/src/test/resources/mappings/mapping-ActorDelete.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Actors/recapJ3Js8AEwt0Bf", + "method" : "DELETE" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ActorDelete.json" + } +} \ No newline at end of file From 05a0750f7f4faac59409cb13017c7ac7a1a90c87 Mon Sep 17 00:00:00 2001 From: fzr Date: Thu, 30 Mar 2017 10:16:08 +0200 Subject: [PATCH 13/74] Documentation --- README.md | 15 ++++++++++++++- src/main/java/com/sybit/airtable/Table.java | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d780e53..97a404b 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,19 @@ Table actorTable = base.table("Actors", Actor.class); Actor actor = actorTable.find("rec514228ed76ced1"); ``` +## Destroy +Use Destroy to delete a specific records of table: + ++ `table(name).destroy(String id)`: delete record with `id` of table `name` + +### Example +```Java +// detailed Example see TableDestroyTest.java +Base base = airtable.base(AIRTABLE_BASE); +Table actorTable = base.table("Actors", Actor.class); +actorTable.destroy("recapJ3Js8AEwt0Bf"); +``` + ## Annotations Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter. @@ -116,7 +129,7 @@ Use the Gson Annotation @SerializedName to annotate Names which contain - or an + [ ] Create Record + [ ] Update Record -+ [ ] Delete Record ++ [x] Delete Record + [ ] Replace Record + General requirements + [ ] Automatic ObjectMapping diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 55fcf54..9fc47cc 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -317,6 +317,13 @@ public T replace(T item) { throw new UnsupportedOperationException("not yet implemented"); } + + /** + * Delete Record by given id + * + * @param id + * @throws AirtableException + */ public void destroy(String id) throws AirtableException { From 15b8490bdf63ed3f4e76fc3b3ad07a03d02e0f54 Mon Sep 17 00:00:00 2001 From: fzr Date: Thu, 30 Mar 2017 15:54:27 +0200 Subject: [PATCH 14/74] Implemented Create Method Implemented Test files, Implemente Method to create, implemented new Class Post Record to generate the Body for the request --- src/main/java/com/sybit/airtable/Table.java | 51 ++++++++++++++++++- .../com/sybit/airtable/vo/PostRecord.java | 33 ++++++++++++ .../sybit/airtable/TableCreateRecordTest.java | 36 +++++++++++++ .../java/com/sybit/airtable/movies/Actor.java | 2 + .../resources/__files/body-ActorCreate.json | 7 +++ .../mappings/mapping-ActorCreate.json | 11 ++++ 6 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/sybit/airtable/vo/PostRecord.java create mode 100644 src/test/java/com/sybit/airtable/TableCreateRecordTest.java create mode 100644 src/test/resources/__files/body-ActorCreate.json create mode 100644 src/test/resources/mappings/mapping-ActorCreate.json diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 9fc47cc..c7ea93b 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -14,6 +14,7 @@ import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.exception.HttpResponseExceptionHandler; import com.sybit.airtable.vo.Delete; +import com.sybit.airtable.vo.PostRecord; import com.sybit.airtable.vo.RecordItem; import com.sybit.airtable.vo.Records; import org.apache.commons.beanutils.BeanUtils; @@ -24,9 +25,14 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.logging.Level; /** * Representation Class of Airtable Tables. @@ -303,9 +309,50 @@ public T find(String id) throws AirtableException { return null; } - public T create(T item) { + public T create(T obj) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + + RecordItem responseBody = null; + + if(propertyExists(obj,"id")){ + setProperty(obj,"id",null); + } + if(propertyExists(obj,"createdTime")){ + setProperty(obj,"createdTime",null); + } + + PostRecord body = new PostRecord(); + body.setFields(obj); + + + HttpResponse response; + try { + response = Unirest.post( getTableEndpointUrl()) + .header("accept", "application/json") + .header("Authorization", getBearerToken()) + .header("Content-type","application/json") + .body(body) + .asObject(RecordItem.class); + } catch (UnirestException e) { + throw new AirtableException(e); + } + + + int code = response.getStatus(); - throw new UnsupportedOperationException("not yet implemented"); + if(200 == code) { + responseBody = response.getBody(); + } else { + HttpResponseExceptionHandler.onResponse(response); + } + + try { + return transform(responseBody, this.type.newInstance() ); + } catch (InvocationTargetException | IllegalAccessException | InstantiationException e) { + LOG.error(e.getMessage(), e); + } + + return null; } public T update(T item) { diff --git a/src/main/java/com/sybit/airtable/vo/PostRecord.java b/src/main/java/com/sybit/airtable/vo/PostRecord.java new file mode 100644 index 0000000..48620c7 --- /dev/null +++ b/src/main/java/com/sybit/airtable/vo/PostRecord.java @@ -0,0 +1,33 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable.vo; + +import java.util.Map; + +/** + * + * @author fzr + */ +public class PostRecord { + + private T fields; + + /** + * @return the fields + */ + public T getFields() { + return fields; + } + + /** + * @param fields the fields to set + */ + public void setFields(T fields) { + this.fields = fields; + } + + +} diff --git a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java new file mode 100644 index 0000000..b164b01 --- /dev/null +++ b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable; + +import com.sybit.airtable.exception.AirtableException; +import com.sybit.airtable.movies.Actor; +import com.sybit.airtable.test.WireMockBaseTest; +import java.lang.reflect.InvocationTargetException; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * + * @author fzr + */ +public class TableCreateRecordTest extends WireMockBaseTest { + + @Test + public void createRecordTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{ + + Base base = airtable.base("appe9941ff07fffcc"); + + Table actorTable = base.table("Actors", Actor.class); + Actor newActor = new Actor(); + newActor.setName("Neuer Actor"); + newActor.setId("10"); + Actor test = actorTable.create(newActor); + assertEquals(test.getName(),newActor.getName()); + assertEquals(test.getId(),"rec123456789"); + + } + +} diff --git a/src/test/java/com/sybit/airtable/movies/Actor.java b/src/test/java/com/sybit/airtable/movies/Actor.java index 912edd1..fd5f6b2 100644 --- a/src/test/java/com/sybit/airtable/movies/Actor.java +++ b/src/test/java/com/sybit/airtable/movies/Actor.java @@ -7,12 +7,14 @@ package com.sybit.airtable.movies; +import com.google.gson.annotations.SerializedName; import com.sybit.airtable.vo.Attachment; import java.util.List; public class Actor { private String id; + @SerializedName("Name") private String name; private List Photo; private String Biography; diff --git a/src/test/resources/__files/body-ActorCreate.json b/src/test/resources/__files/body-ActorCreate.json new file mode 100644 index 0000000..2d99298 --- /dev/null +++ b/src/test/resources/__files/body-ActorCreate.json @@ -0,0 +1,7 @@ +{ + "id": "rec123456789", + "fields": { + "Name": "Neuer Actor" + }, + "createdTime": "2014-07-18T04:48:25.000Z" +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ActorCreate.json b/src/test/resources/mappings/mapping-ActorCreate.json new file mode 100644 index 0000000..0c3924c --- /dev/null +++ b/src/test/resources/mappings/mapping-ActorCreate.json @@ -0,0 +1,11 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Actors", + "method" : "POST", + "bodyPatterns" : [{"equalToJson" : "{\"fields\":{\"Name\": \"Neuer Actor\"}}"}] + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ActorCreate.json" + } +} \ No newline at end of file From c0a2928da52902ff2db55bda29498ad115528d76 Mon Sep 17 00:00:00 2001 From: fzr Date: Thu, 30 Mar 2017 15:57:20 +0200 Subject: [PATCH 15/74] Comments etc --- src/main/java/com/sybit/airtable/Table.java | 24 +++++++++++++------ .../com/sybit/airtable/vo/PostRecord.java | 1 - 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index c7ea93b..63bb7fc 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -308,21 +308,31 @@ public T find(String id) throws AirtableException { return null; } - - public T create(T obj) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + /** + * Create Record of given Item + * + * @param item the item to be created + * @return the created item + * @throws AirtableException + * @throws IllegalAccessException + * @throws InvocationTargetException + * @throws NoSuchMethodException + */ + public T create(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { RecordItem responseBody = null; - if(propertyExists(obj,"id")){ - setProperty(obj,"id",null); + if(propertyExists(item,"id")){ + setProperty(item,"id",null); } - if(propertyExists(obj,"createdTime")){ - setProperty(obj,"createdTime",null); + if(propertyExists(item,"createdTime")){ + setProperty(item,"createdTime",null); } PostRecord body = new PostRecord(); - body.setFields(obj); + body.setFields(item); HttpResponse response; diff --git a/src/main/java/com/sybit/airtable/vo/PostRecord.java b/src/main/java/com/sybit/airtable/vo/PostRecord.java index 48620c7..f7213c9 100644 --- a/src/main/java/com/sybit/airtable/vo/PostRecord.java +++ b/src/main/java/com/sybit/airtable/vo/PostRecord.java @@ -5,7 +5,6 @@ */ package com.sybit.airtable.vo; -import java.util.Map; /** * From 3ee8c7143751e6201bce9f988bfc63045bbf97c7 Mon Sep 17 00:00:00 2001 From: stritti Date: Fri, 31 Mar 2017 10:19:41 +0200 Subject: [PATCH 16/74] - Adding configuration class. - timeout could be set now --- .../java/com/sybit/airtable/Airtable.java | 41 +++++++---- .../com/sybit/airtable/Configuration.java | 72 +++++++++++++++++++ 2 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/sybit/airtable/Configuration.java diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index f63c65c..fd0ac23 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -44,12 +44,11 @@ public class Airtable { private static final Logger LOG = LoggerFactory.getLogger( Airtable.class ); - private static final String ENDPOINT_URL = "https://api.airtable.com/v0"; + private static final String AIRTABLE_API_KEY = "AIRTABLE_API_KEY"; private static final String AIRTABLE_BASE = "AIRTABLE_BASE"; - private String endpointUrl; - private String apiKey; + private Configuration config; /** * Configure, AIRTABLE_API_KEY passed by Java property, enviroment variable @@ -86,29 +85,32 @@ public Airtable configure() throws AirtableException { */ @SuppressWarnings("WeakerAccess") public Airtable configure(String apiKey) throws AirtableException { - return configure(apiKey, ENDPOINT_URL); + return configure(new Configuration(apiKey, Configuration.ENDPOINT_URL)); } /** * - * @param apiKey - * @param endpointUrl + * @param config * @return * @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint */ @SuppressWarnings("WeakerAccess") - public Airtable configure(String apiKey, String endpointUrl) throws AirtableException { - if(apiKey == null) { + public Airtable configure(Configuration config) throws AirtableException { + if(config.getApiKey() == null) { throw new AirtableException("Missing Airtable API-Key"); } - if(endpointUrl == null) { + if(config.getEndpointUrl() == null) { throw new AirtableException("Missing endpointUrl"); } - this.apiKey = apiKey; - this.endpointUrl = endpointUrl; + this.config = config; - setProxy(endpointUrl); + if(config.getTimeout() != null) { + LOG.info("Set connection timeout to: " + config.getTimeout() + "ms."); + Unirest.setTimeouts(config.getTimeout(), config.getTimeout()); + } + + setProxy(config.getEndpointUrl()); // Only one time Unirest.setObjectMapper(new GsonObjectMapper()); @@ -190,12 +192,21 @@ public Base base(String base) throws AirtableException { return b; } + public Configuration getConfig() { + return config; + } + + public void setConfig(Configuration config) { + this.config = config; + setProxy(config.getEndpointUrl()); + } + /** * * @return */ public String endpointUrl() { - return endpointUrl; + return this.config.getEndpointUrl(); } /** @@ -203,7 +214,7 @@ public String endpointUrl() { * @return */ public String apiKey() { - return apiKey; + return this.config.getApiKey(); } /** @@ -235,7 +246,7 @@ private String getCredentialProperty(String key) { } public void setEndpointUrl(String endpointUrl) { - this.endpointUrl = endpointUrl; + this.config.setEndpointUrl(endpointUrl); setProxy(endpointUrl); } } diff --git a/src/main/java/com/sybit/airtable/Configuration.java b/src/main/java/com/sybit/airtable/Configuration.java new file mode 100644 index 0000000..9a929b0 --- /dev/null +++ b/src/main/java/com/sybit/airtable/Configuration.java @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * Copyright (c) 2017 Sybit GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + */ +package com.sybit.airtable; + +/** + * Configuration settings for Airtable. + * Used by class Airtable to configure basic settings. + */ +public class Configuration { + + public static final String ENDPOINT_URL = "https://api.airtable.com/v0"; + + private String endpointUrl; + private String apiKey; + private Long timeout; + + /** + * Configure API using given API Key and default endpoint. + * + * @param apiKey + */ + public Configuration(String apiKey) { + this(apiKey, ENDPOINT_URL); + + } + /** + * Configure API using given API Key and default endpointURL. + * + * @param apiKey + * @param endpointUrl + */ + public Configuration(String apiKey, String endpointUrl) { + this.apiKey = apiKey; + this.endpointUrl = endpointUrl; + } + + public String getEndpointUrl() { + return endpointUrl; + } + + public void setEndpointUrl(String endpointUrl) { + this.endpointUrl = endpointUrl; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + /** + * Get connection timeout. + * @return + */ + public Long getTimeout() { + return timeout; + } + + /** + * Set connection timeout. + * @param timeout + */ + public void setTimeout(Long timeout) { + this.timeout = timeout; + } +} From 39bcf128acbd5e8b9281931f80af427bb5abb45f Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 31 Mar 2017 13:21:26 +0200 Subject: [PATCH 17/74] Create Method -Added Serialized Names in Movie and Actor -Added Testfiles for MovieCreation -Implemented Check for id and created Time --- src/main/java/com/sybit/airtable/Table.java | 36 ++++++++++++---- .../sybit/airtable/TableConverterTest.java | 2 +- .../sybit/airtable/TableCreateRecordTest.java | 42 ++++++++++++++++++- .../java/com/sybit/airtable/movies/Actor.java | 21 ++++++---- .../java/com/sybit/airtable/movies/Movie.java | 12 ++++-- .../resources/__files/body-MovieCreate.json | 18 ++++++++ .../mappings/mapping-MovieCreate.json | 14 +++++++ 7 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 src/test/resources/__files/body-MovieCreate.json create mode 100644 src/test/resources/mappings/mapping-MovieCreate.json diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 63bb7fc..9f55ea7 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -27,12 +27,16 @@ import java.lang.reflect.InvocationTargetException; import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; +import org.apache.commons.beanutils.BeanUtilsBean; /** * Representation Class of Airtable Tables. @@ -319,20 +323,38 @@ public T find(String id) throws AirtableException { * @throws InvocationTargetException * @throws NoSuchMethodException */ - public T create(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + public T create(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { RecordItem responseBody = null; + T newItem = (T) item.getClass().newInstance(); - if(propertyExists(item,"id")){ - setProperty(item,"id",null); - } - if(propertyExists(item,"createdTime")){ - setProperty(item,"createdTime",null); + if(propertyExists(item,"id") || propertyExists(item,"createdTime")){ + Field[] attributes = item.getClass().getDeclaredFields(); + for (Field attribute : attributes) { + String name = attribute.getName(); + if (name.equals("id") || name.equals("createdTime") || name.equals("$jacocoData")) { + + } else if (BeanUtils.getProperty(item,attribute.getName()) == null){ + + } else if (attribute.getType().equals(List.class)){ + String [] s = BeanUtils.getArrayProperty(item,attribute.getName()); + List value = Arrays.asList(s); + BeanUtilsBean.getInstance().setProperty(newItem,attribute.getName(),value); + } else { + BeanUtilsBean.getInstance().setProperty(newItem,attribute.getName(),BeanUtils.getProperty(item,attribute.getName())); + } + + } } + + //TODO Date neu initialisieren ? Darf nicht null sein +// if(propertyExists(item,"id")){ +// setProperty(item,"createdTime",null); +// } PostRecord body = new PostRecord(); - body.setFields(item); + body.setFields(newItem); HttpResponse response; diff --git a/src/test/java/com/sybit/airtable/TableConverterTest.java b/src/test/java/com/sybit/airtable/TableConverterTest.java index d08d449..f94d08b 100644 --- a/src/test/java/com/sybit/airtable/TableConverterTest.java +++ b/src/test/java/com/sybit/airtable/TableConverterTest.java @@ -39,7 +39,7 @@ public void testConvertMovie() throws AirtableException, HttpResponseException { assertEquals(movie.getName(),"The Godfather"); assertEquals(movie.getDescription(),"The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selli..."); assertEquals(movie.getPhotos().size(),2); - assertEquals(movie.getDirector(),"recfaf64fe0db19a9"); + assertEquals(movie.getDirector().size(),1); assertEquals(movie.getActors().size(),2); assertEquals(movie.getGenre().size(),1); //TODO Test für Datum diff --git a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java index b164b01..3a808db 100644 --- a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java +++ b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java @@ -7,9 +7,14 @@ import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.movies.Actor; +import com.sybit.airtable.movies.Movie; import com.sybit.airtable.test.WireMockBaseTest; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import org.junit.Test; /** @@ -19,7 +24,7 @@ public class TableCreateRecordTest extends WireMockBaseTest { @Test - public void createRecordTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{ + public void createActorTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ Base base = airtable.base("appe9941ff07fffcc"); @@ -33,4 +38,39 @@ public void createRecordTest() throws AirtableException, IllegalAccessException, } + @Test + public void createMovieTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie newMovie = new Movie(); + + newMovie.setName("Neuer Film"); + newMovie.setDescription("Irgendwas"); + List director = new ArrayList<>(); + director.add("recfaf64fe0db19a9"); + newMovie.setDirector(director); + List actors = new ArrayList<>(); + actors.add("recc8841a14245b0b"); + actors.add("rec514228ed76ced1"); + newMovie.setActors(actors); + List genre = new ArrayList<>(); + genre.add("Drama"); + newMovie.setGenre(genre); + //Date d = new Date(); + //newMovie.setCreatedTime(d); + + Movie test = movieTable.create(newMovie); + + assertEquals(newMovie.getName(),test.getName()); + assertEquals(newMovie.getActors(),test.getActors()); + assertEquals(newMovie.getGenre(),test.getGenre()); + assertEquals(newMovie.getDescription(),test.getDescription()); + assertEquals("rec987654321",test.getId()); + assertNotNull(test.getCreatedTime()); + + + } + } diff --git a/src/test/java/com/sybit/airtable/movies/Actor.java b/src/test/java/com/sybit/airtable/movies/Actor.java index fd5f6b2..f154999 100644 --- a/src/test/java/com/sybit/airtable/movies/Actor.java +++ b/src/test/java/com/sybit/airtable/movies/Actor.java @@ -16,9 +16,12 @@ public class Actor { private String id; @SerializedName("Name") private String name; - private List Photo; - private String Biography; - private String[] Filmography; + @SerializedName("Photo") + private List photo; + @SerializedName("Biography") + private String biography; + @SerializedName("Filmography") + private String[] filmography; @@ -39,27 +42,27 @@ public void setName(String name) { } public String[] getFilmography() { - return Filmography; + return filmography; } public void setFilmography(String[] Filmography) { - this.Filmography = Filmography; + this.filmography = Filmography; } public List getPhoto() { - return Photo; + return photo; } public void setPhoto(List Photo) { - this.Photo = Photo; + this.photo = Photo; } public String getBiography() { - return Biography; + return biography; } public void setBiography(String Biography) { - this.Biography = Biography; + this.biography = Biography; } diff --git a/src/test/java/com/sybit/airtable/movies/Movie.java b/src/test/java/com/sybit/airtable/movies/Movie.java index 87b4276..b1b2ca4 100644 --- a/src/test/java/com/sybit/airtable/movies/Movie.java +++ b/src/test/java/com/sybit/airtable/movies/Movie.java @@ -6,6 +6,7 @@ */ package com.sybit.airtable.movies; +import com.google.gson.annotations.SerializedName; import com.sybit.airtable.vo.Attachment; import java.util.Date; @@ -16,11 +17,16 @@ */ public class Movie { private String id; + @SerializedName("Name") private String name; + @SerializedName("Description") private String description; private List photos; - private String director; + @SerializedName("Director") + private List director; + @SerializedName("Actors") private List actors; + @SerializedName("Genre") private List genre; private Date createdTime; @@ -56,11 +62,11 @@ public void setPhotos(List photos) { this.photos = photos; } - public String getDirector() { + public List getDirector() { return director; } - public void setDirector(String director) { + public void setDirector(List director) { this.director = director; } diff --git a/src/test/resources/__files/body-MovieCreate.json b/src/test/resources/__files/body-MovieCreate.json new file mode 100644 index 0000000..4e6512f --- /dev/null +++ b/src/test/resources/__files/body-MovieCreate.json @@ -0,0 +1,18 @@ +{ + "id": "rec987654321", + "fields": { + "Name": "Neuer Film", + "Description": "Irgendwas", + "Actors": [ + "recc8841a14245b0b", + "rec514228ed76ced1" + ], + "Director": [ + "recfaf64fe0db19a9" + ], + "Genre": [ + "Drama" + ] + }, + "createdTime": "2014-07-18T04:42:06.000Z" + } \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-MovieCreate.json b/src/test/resources/mappings/mapping-MovieCreate.json new file mode 100644 index 0000000..cb3d7c9 --- /dev/null +++ b/src/test/resources/mappings/mapping-MovieCreate.json @@ -0,0 +1,14 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies", + "method" : "POST", + "bodyPatterns" : [{"equalToJson" : "{\"fields\":{\"Name\":\"Neuer Film\",\"Description\":\"Irgendwas\",\"Director\":[\"recfaf64fe0db19a9\"],\"Actors\":[\"recc8841a14245b0b\",\"rec514228ed76ced1\"],\"Genre\":[\"Drama\"]}}", + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + }] +}, + "response" : { + "status" : 200, + "bodyFileName" : "/body-MovieCreate.json" + } +} \ No newline at end of file From ae89c1f1a479fc153a96f9d38f15eb5390d164bd Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 31 Mar 2017 15:35:47 +0200 Subject: [PATCH 18/74] Implemented Create -Added additional Tests -Serialized Name in Movie -Check if If or Created Time or Id are set --- src/main/java/com/sybit/airtable/Table.java | 25 ++------ .../sybit/airtable/TableCreateRecordTest.java | 58 ++++++++++++++++++- .../java/com/sybit/airtable/movies/Movie.java | 1 + .../resources/__files/body-MovieCreate2.json | 43 ++++++++++++++ .../mappings/mapping-MovieCreate2.json | 14 +++++ 5 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 src/test/resources/__files/body-MovieCreate2.json create mode 100644 src/test/resources/mappings/mapping-MovieCreate2.json diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 9f55ea7..65023ed 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -327,34 +327,21 @@ public T create(T item) throws AirtableException, IllegalAccessException, Invoca RecordItem responseBody = null; - T newItem = (T) item.getClass().newInstance(); if(propertyExists(item,"id") || propertyExists(item,"createdTime")){ Field[] attributes = item.getClass().getDeclaredFields(); for (Field attribute : attributes) { String name = attribute.getName(); - if (name.equals("id") || name.equals("createdTime") || name.equals("$jacocoData")) { - - } else if (BeanUtils.getProperty(item,attribute.getName()) == null){ - - } else if (attribute.getType().equals(List.class)){ - String [] s = BeanUtils.getArrayProperty(item,attribute.getName()); - List value = Arrays.asList(s); - BeanUtilsBean.getInstance().setProperty(newItem,attribute.getName(),value); - } else { - BeanUtilsBean.getInstance().setProperty(newItem,attribute.getName(),BeanUtils.getProperty(item,attribute.getName())); - } - + if (name.equals("id") || name.equals("createdTime")) { + if(BeanUtils.getProperty(item,attribute.getName()) != null){ + throw new AirtableException("Property "+name+" should be null!"); + } + } } } - - //TODO Date neu initialisieren ? Darf nicht null sein -// if(propertyExists(item,"id")){ -// setProperty(item,"createdTime",null); -// } PostRecord body = new PostRecord(); - body.setFields(newItem); + body.setFields(item); HttpResponse response; diff --git a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java index 3a808db..cfc9884 100644 --- a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java +++ b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java @@ -9,6 +9,7 @@ import com.sybit.airtable.movies.Actor; import com.sybit.airtable.movies.Movie; import com.sybit.airtable.test.WireMockBaseTest; +import com.sybit.airtable.vo.Attachment; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Date; @@ -23,6 +24,32 @@ */ public class TableCreateRecordTest extends WireMockBaseTest { + @Test(expected = AirtableException.class) + public void createMovieWithId() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie newMovie = new Movie(); + newMovie.setName("Neuer Film"); + newMovie.setId("1"); + Movie test = movieTable.create(newMovie); + + } + + @Test(expected = AirtableException.class) + public void createMovieWithCreatedTime() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie newMovie = new Movie(); + newMovie.setName("Neuer Film"); + newMovie.setCreatedTime(new Date()); + Movie test = movieTable.create(newMovie); + + } + @Test public void createActorTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ @@ -31,13 +58,42 @@ public void createActorTest() throws AirtableException, IllegalAccessException, Table actorTable = base.table("Actors", Actor.class); Actor newActor = new Actor(); newActor.setName("Neuer Actor"); - newActor.setId("10"); Actor test = actorTable.create(newActor); assertEquals(test.getName(),newActor.getName()); assertEquals(test.getId(),"rec123456789"); } + @Test + public void createMovieWithAttachementTest() throws AirtableException, IllegalAccessException, NoSuchMethodException, NoSuchMethodException, InstantiationException, InvocationTargetException { + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie newMovie = new Movie(); + + newMovie.setName("Neuer Film"); + List photos = new ArrayList(); + Attachment photo1 = new Attachment(); + Attachment photo2 = new Attachment(); + photo1.setUrl("https://www.example.imgae.file1.de"); + photo2.setUrl("https://www.example.imgae.file2.de"); + photos.add(photo1); + photos.add(photo2); + + newMovie.setPhotos(photos); + + Movie test = movieTable.create(newMovie); + + assertEquals("https://www.example.imgae.file1.de", test.getPhotos().get(0).getUrl()); + assertEquals("https://www.example.imgae.file2.de", test.getPhotos().get(1).getUrl()); + + assertNotNull(test.getPhotos().get(0).getId()); + assertNotNull(test.getPhotos().get(1).getId()); + + + } + @Test public void createMovieTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ diff --git a/src/test/java/com/sybit/airtable/movies/Movie.java b/src/test/java/com/sybit/airtable/movies/Movie.java index b1b2ca4..a8f252d 100644 --- a/src/test/java/com/sybit/airtable/movies/Movie.java +++ b/src/test/java/com/sybit/airtable/movies/Movie.java @@ -21,6 +21,7 @@ public class Movie { private String name; @SerializedName("Description") private String description; + @SerializedName("Photos") private List photos; @SerializedName("Director") private List director; diff --git a/src/test/resources/__files/body-MovieCreate2.json b/src/test/resources/__files/body-MovieCreate2.json new file mode 100644 index 0000000..94d7542 --- /dev/null +++ b/src/test/resources/__files/body-MovieCreate2.json @@ -0,0 +1,43 @@ +{ + "id": "rec6733da527dd0f1", + "fields": { + "Name": "The Godfather", + "Photos": [ + { + "id": "att6dba4af5786df1", + "url": "https://www.example.imgae.file1.de", + "filename": "220px-TheGodfatherAlPacinoMarlonBrando.jpg", + "size": 16420, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://www.filepicker.io/api/file/XvbySDtbSxymbbUJzCoN" + }, + "large": { + "url": "https://www.filepicker.io/api/file/Fpc86btaS1Stl79SvHX4" + } + } + }, + { + "id": "attzWvarnmYBBd2Wm", + "url": "https://www.example.imgae.file2.de", + "filename": "Lighthouse.jpg", + "size": 561276, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg", + "width": 48, + "height": 36 + }, + "large": { + "url": "https://dl.airtable.com/8QX7f3nSAe6lrOxeuvTP_large_Lighthouse.jpg", + "width": 512, + "height": 512 + } + } + } + ] + }, + "createdTime": "2014-07-18T04:42:06.000Z" +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-MovieCreate2.json b/src/test/resources/mappings/mapping-MovieCreate2.json new file mode 100644 index 0000000..0e0edd0 --- /dev/null +++ b/src/test/resources/mappings/mapping-MovieCreate2.json @@ -0,0 +1,14 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies", + "method" : "POST", + "bodyPatterns" : [{"equalToJson" : "{\"fields\":{\"Name\":\"Neuer Film\",\"Photos\": [{\"url\":\"https://www.example.imgae.file1.de\"},{\"url\":\"https://www.example.imgae.file2.de\"}]}}", + "ignoreArrayOrder" : true, + "ignoreExtraElements" : true + }] +}, + "response" : { + "status" : 200, + "bodyFileName" : "/body-MovieCreate2.json" + } +} \ No newline at end of file From e6fddececaac1d686a2b736cdbacaf51f84470e6 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 31 Mar 2017 16:01:18 +0200 Subject: [PATCH 19/74] Fixed Things --- src/main/java/com/sybit/airtable/Query.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sybit/airtable/Query.java b/src/main/java/com/sybit/airtable/Query.java index f884b1b..d22bfb6 100644 --- a/src/main/java/com/sybit/airtable/Query.java +++ b/src/main/java/com/sybit/airtable/Query.java @@ -31,7 +31,7 @@ public interface Query { /** * Define a filter formula. * - * @see https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference + * see https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference * @return get the filter formula. */ String filterByFormula(); From cfd89f1e7bdd9615676553a4d69ee91cb83b19d1 Mon Sep 17 00:00:00 2001 From: stritti Date: Fri, 31 Mar 2017 16:04:36 +0200 Subject: [PATCH 20/74] update readme --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 97a404b..55c1b17 100644 --- a/README.md +++ b/README.md @@ -47,16 +47,18 @@ The API supports environment variable `http_proxy`. If the variable is set, it i If `endpointUrl` contains `localhost` or `127.0.0.1` proxy settings are ignored automatically. -## Logging +### Logging -The Simple Logging Facade for Java [https://www.slf4j.org/](SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time. +The Simple Logging Facade for Java [https://www.slf4j.org/](SLF4J) serves as a simple facade or abstraction +for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired +logging framework at deployment time. +### Request Limits +The API of Airtable itself is limited to 5 requests per second. If you exceed this rate, you will receive a 429 status code and will +need to wait 30 seconds before subsequent requests will succeed. -## Access Base -## Access Table - -## CRUD-Operations on table items +## CRUD-Operations on Table Records ## Select Select List of items from table: @@ -102,13 +104,14 @@ actorTable.destroy("recapJ3Js8AEwt0Bf"); ## Annotations -Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter. +Use the Gson Annotation `@SerializedName` to annotate Names which contain `-` or emtpy characters. ### Example ```Java import com.google.gson.annotations.SerializedName; + //Column in Airtable is named "First- & Lastname", which is mapped to field "name". @SerializedName("First- & Lastname") private String name; ``` @@ -117,9 +120,9 @@ Use the Gson Annotation @SerializedName to annotate Names which contain - or an + [x] Airtable Configure + [x] configuration of `proxy` + [x] configuration of `AIRTABLE_API_KEY` & `AIRTABLE_BASE` - + [ ] configuration of `requestTimeout` + + [x] configuration of `requestTimeout` -+ [x] Select ++ [x] Select Records + [x] SelectAll + [x] Queries (`maxRecords`, `sort` & `view` ) + [ ] Support of `filterByFormula` @@ -164,5 +167,3 @@ We use following libraries: # License MIT License, see [LICENSE](LICENSE) - - From 3cfb0838d31ce10a21d2926d47ca3022459bd051 Mon Sep 17 00:00:00 2001 From: stritti Date: Fri, 31 Mar 2017 16:06:25 +0200 Subject: [PATCH 21/74] fix javadoc error --- src/main/java/com/sybit/airtable/Query.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sybit/airtable/Query.java b/src/main/java/com/sybit/airtable/Query.java index f884b1b..d22bfb6 100644 --- a/src/main/java/com/sybit/airtable/Query.java +++ b/src/main/java/com/sybit/airtable/Query.java @@ -31,7 +31,7 @@ public interface Query { /** * Define a filter formula. * - * @see https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference + * see https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference * @return get the filter formula. */ String filterByFormula(); From 089e23a2c53b7f08a4514c0236c9fa98c71a107c Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 11:17:17 +0200 Subject: [PATCH 22/74] updated/improved readme --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 55c1b17..1f47b96 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Java API for Airtable (http://www.airtable.com). The Airtable API provides a simple way of accessing your data within your Java project. +More information about the Airtable API coud be found at [https://airtable.com/api](https://airtable.com/api). +The documentation will provide detailed information about your created base. # Usage @@ -29,12 +31,20 @@ repositories { ## Initializing +It is required to initialize the Java API before it is used. At leased you have to pss your API-Key to get +access to Airtable: + +```Java +Airtable airtable = new Airtable().configure(); + +``` + ### API-Key -The API key could be passed to the app by -+ defining Java property `AIRTABLE_API_KEY` (e.g. `-DAIRTABLE_API_KEY=foo`). -+ defining OS environment variable `AIRTABLE_API_KEY` (e.g. `export AIRTABLE_API_KEY=foo`). -+ defining property file `credentials.properties` in root classpath containing key/value `AIRTABLE_API_KEY=foo`. -+ On the other hand the API-key could also be added by using the method `Airtable.configure(String apiKey)`. +The API key could be passed to the app in different ways: +* defining Java property `AIRTABLE_API_KEY` (e.g. `-DAIRTABLE_API_KEY=foo`). +* defining OS environment variable `AIRTABLE_API_KEY` (e.g. `export AIRTABLE_API_KEY=foo`). +* defining property file `credentials.properties` in root classpath containing key/value `AIRTABLE_API_KEY=foo`. +* On the other hand the API-key could also be added by using the method `Airtable.configure(String apiKey)`. #### How to get API-Key See: https://support.airtable.com/hc/en-us/articles/219046777-How-do-I-get-my-API-key- @@ -57,6 +67,28 @@ logging framework at deployment time. The API of Airtable itself is limited to 5 requests per second. If you exceed this rate, you will receive a 429 status code and will need to wait 30 seconds before subsequent requests will succeed. +## Object Mapping +The Java implementation of the Airtable API provides automatic Object mapping. + + *TODO:* + * How to create objects + * Basic objects (attachment, ...) + + +### Annotations + +Use the Gson Annotation `@SerializedName` to annotate Names which contain `-`, emtpy characters or other not mappable characters. +The airtable.java API will respect these mappings automatically. + +#### Example +```Java + + import com.google.gson.annotations.SerializedName; + + //Column in Airtable is named "First- & Lastname", which is mapped to field "name". + @SerializedName("First- & Lastname") + private String name; +``` ## CRUD-Operations on Table Records @@ -102,19 +134,6 @@ Table actorTable = base.table("Actors", Actor.class); actorTable.destroy("recapJ3Js8AEwt0Bf"); ``` -## Annotations - -Use the Gson Annotation `@SerializedName` to annotate Names which contain `-` or emtpy characters. - -### Example -```Java - - import com.google.gson.annotations.SerializedName; - - //Column in Airtable is named "First- & Lastname", which is mapped to field "name". - @SerializedName("First- & Lastname") - private String name; -``` # Roadmap + [x] Airtable Configure @@ -138,10 +157,22 @@ Use the Gson Annotation `@SerializedName` to annotate Names which contain `-` or + [ ] Automatic ObjectMapping + [x] Read: convert to Objects + [x] Read: conversion of `Attachment`s & `Thumbnail`s - + [ ] Write: convert Objects to JSON - + [x] Errorhandling + + [ ] Write: convert Objects to JSON for Airtable API + + [x] Error handling + +# Contribute + +We are glad to see your pull requests. + +## Current status + +The current status of our project is maintained on our agile board: +[Kanban Board of airtable.java](https://github.com/Sybit-Education/airtable.java/projects/1) + +## Compiling project + +airtable.jave is developed and compiled using Java 8. -# Compiling project We use [Gradle](https://gradle.org) to compile and package project: + for tests run: `./gradlew clean test` @@ -154,6 +185,9 @@ The tests are based on the Airtable template [Movies](https://airtable.com/templ For testing, the JSON-responses are mocked via [WireMock](http://wiremock.org/). # Credits + +Thank you very much for these gread frameworks and ibraries provided open source! + We use following libraries: + [unirest](http://unirest.io/java.html) From 8e36f543635cd51c6188f75e44c0b230ca43d3a0 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 11:29:03 +0200 Subject: [PATCH 23/74] updated readme --- README.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1f47b96..b1cc53b 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ If `endpointUrl` contains `localhost` or `127.0.0.1` proxy settings are ignored ### Logging -The Simple Logging Facade for Java [https://www.slf4j.org/](SLF4J) serves as a simple facade or abstraction +The Simple Logging Facade for Java [SLF4J](https://www.slf4j.org/) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time. @@ -72,7 +72,7 @@ The Java implementation of the Airtable API provides automatic Object mapping. *TODO:* * How to create objects - * Basic objects (attachment, ...) + * Basic objects (attachment, thumbnails, ...) ### Annotations @@ -93,7 +93,7 @@ The airtable.java API will respect these mappings automatically. ## CRUD-Operations on Table Records ## Select -Select List of items from table: +Select list of items from table: + `table(name).select()`: get all records of table `name` + `table(name).select(Integer maxRecords)`: get max `maxRecords` records of table `name` @@ -103,39 +103,43 @@ Select List of items from table: ### Example ```Java -// detailed Example see TableSelectTest.java Base base = new Airtable().base(AIRTABLE_BASE); List retval = base.table("Movies", Movie.class).select(); ``` +Detailed example see [TableSelectTest.java](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableSelectTest.java) + ## Find -Use Find to get specific records of table: +Use `find` to get specific records of table: + `table(name).find(String id)`: get record with `id` of table `name` ### Example ```Java -// detailed Example see TableFindTest.java Base base = new Airtable().base(AIRTABLE_BASE); Table actorTable = base.table("Actors", Actor.class); Actor actor = actorTable.find("rec514228ed76ced1"); ``` +Detailed example see [TableFindTest.java](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableFindTest.java) + ## Destroy -Use Destroy to delete a specific records of table: +Use `destroy` to delete a specific records of table: + `table(name).destroy(String id)`: delete record with `id` of table `name` ### Example ```Java -// detailed Example see TableDestroyTest.java Base base = airtable.base(AIRTABLE_BASE); Table actorTable = base.table("Actors", Actor.class); actorTable.destroy("recapJ3Js8AEwt0Bf"); ``` - +Detailed example see [TableDestroyTest.java](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableDestroyTest.java) # Roadmap + +Short overview of features, which are supported: + + [x] Airtable Configure + [x] configuration of `proxy` + [x] configuration of `AIRTABLE_API_KEY` & `AIRTABLE_BASE` @@ -151,7 +155,7 @@ actorTable.destroy("recapJ3Js8AEwt0Bf"); + [ ] Create Record + [ ] Update Record -+ [x] Delete Record ++ [x] Delete/Destroy Record + [ ] Replace Record + General requirements + [ ] Automatic ObjectMapping From 545b375e2ac492cfac953db05489cb386c226b2f Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 13:16:09 +0200 Subject: [PATCH 24/74] cleand API --- .../java/com/sybit/airtable/Airtable.java | 3 +- src/main/java/com/sybit/airtable/Base.java | 28 ++++--------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index fd0ac23..46682d6 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -186,8 +186,7 @@ public Base base(String base) throws AirtableException { if(base == null) { throw new AirtableException("base was null"); } - final Base b = new Base(base); - b.setParent(this); + final Base b = new Base(base, this); return b; } diff --git a/src/main/java/com/sybit/airtable/Base.java b/src/main/java/com/sybit/airtable/Base.java index 626da80..642a24f 100644 --- a/src/main/java/com/sybit/airtable/Base.java +++ b/src/main/java/com/sybit/airtable/Base.java @@ -26,17 +26,8 @@ public class Base { private final String base; - private Airtable parent; + private final Airtable parent; - /** - * Create Airtable Base with given base ID. - * - * ID could be found at https://airtable.com if you select your current base. - * @param base base ID could be found at https://airtable.com if you select your current base. - */ - public Base(String base) { - this.base = base; - } /** * Create Airtable Base with given base ID. @@ -45,18 +36,10 @@ public Base(String base) { * @param airtable parent airtable object */ public Base(String base, Airtable airtable) { - this(base); - setParent(airtable); - } - - /** - * Set Airtable object as parent. - * @param parent the base Airtable object. - */ - void setParent(Airtable parent) { - this.parent = parent; + this.base = base; + this.parent = airtable; } - + /** * Get Airtable object as parent. * @return @@ -78,12 +61,13 @@ public Table table(String name) { /** * Get Table object of given table. * @param name Name of required table. - * @param clazz + * @param clazz Class representing row of resultsets * @return Object to access table. */ public Table table(String name, Class clazz) { if(!tableMap.containsKey(name)) { + LOG.debug("Create new instance for table [" + name + "]"); Table t = new Table(name, clazz); t.setParent(this); tableMap.put(name, t); From 7f05f1d5237f73e31aad00d0e4bd058a5df532a3 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 13:18:01 +0200 Subject: [PATCH 25/74] travis caching --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40e3ba0..7e76d4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,7 @@ deploy: before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ \ No newline at end of file + directories: + — $HOME/.gradle \ No newline at end of file From ca42e0abb1cab5b8288aac529c938eb9e6b6736d Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 13:30:56 +0200 Subject: [PATCH 26/74] update travis build --- .travis.yml | 7 +++---- build.gradle | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7e76d4b..1a0ece1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,13 +4,12 @@ jdk: before_install: - chmod +x ./gradlew -- curl -sL https://github.com/jpm4j/jpm4j.installers/raw/master/dist/biz.aQute.jpm.run.jar - >jpm4j.jar +- curl -sL https://github.com/jpm4j/jpm4j.installers/raw/master/dist/biz.aQute.jpm.run.jar >jpm4j.jar - java -jar jpm4j.jar -u init -- "~/jpm/bin/jpm install com.codacy:codacy-coverage-reporter:assembly" +- ~/jpm/bin/jpm install com.codacy:codacy-coverage-reporter:assembly after_success: -- "~/jpm/bin/codacy-coverage-reporter -l Java -r build/reports/jacoco/test/jacocoTestReport.xml" +- ~/jpm/bin/codacy-coverage-reporter -l Java -r build/reports/jacoco/test/jacocoTestReport.xml deploy: - provider: script diff --git a/build.gradle b/build.gradle index c65222a..c8482ee 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,6 @@ repositories { dependencies { compile group: 'com.mashape.unirest', name: 'unirest-java', version:'1.4.9' compile group: 'org.apache.httpcomponents', name: 'httpclient', version:'4.5.2' - //compile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version:'4.0.2' compile group: 'org.apache.httpcomponents', name: 'httpmime', version:'4.5.1' compile group: 'org.json', name: 'json', version:'20160810' compile group: 'com.google.code.gson', name: 'gson', version:'2.5' From 4d9ee48024481156abc7b9b3ba7134ea851ae674 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 13:34:36 +0200 Subject: [PATCH 27/74] disable cache --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1a0ece1..82045ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,10 +28,10 @@ deploy: tags: true - -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - -cache: - directories: - — $HOME/.gradle \ No newline at end of file +# +#before_cache: +# - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock +# +#cache: +# directories: +# — $HOME/.gradle \ No newline at end of file From 0e1978221b71ddfb89630eea592532b911f13fb7 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 15:50:48 +0200 Subject: [PATCH 28/74] sendCoverageToCodacy --- .travis.yml | 22 ++++++++-------------- build.gradle | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82045ef..d6b0cac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,17 +4,11 @@ jdk: before_install: - chmod +x ./gradlew -- curl -sL https://github.com/jpm4j/jpm4j.installers/raw/master/dist/biz.aQute.jpm.run.jar >jpm4j.jar -- java -jar jpm4j.jar -u init -- ~/jpm/bin/jpm install com.codacy:codacy-coverage-reporter:assembly - -after_success: -- ~/jpm/bin/codacy-coverage-reporter -l Java -r build/reports/jacoco/test/jacocoTestReport.xml deploy: - provider: script skip_cleanup: true - script: gradlew install bintrayUpload + script: gradlew install sendCoverageToCodacy bintrayUpload on: tags: true @@ -28,10 +22,10 @@ deploy: tags: true -# -#before_cache: -# - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock -# -#cache: -# directories: -# — $HOME/.gradle \ No newline at end of file + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + +cache: + directories: + — $HOME/.gradle \ No newline at end of file diff --git a/build.gradle b/build.gradle index c8482ee..9b46837 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,10 @@ repositories { maven { url "http://dl.bintray.com/typesafe/maven-releases" } } +configurations { + codacy +} + dependencies { compile group: 'com.mashape.unirest', name: 'unirest-java', version:'1.4.9' compile group: 'org.apache.httpcomponents', name: 'httpclient', version:'4.5.2' @@ -58,6 +62,8 @@ dependencies { testCompile group: 'commons-io', name: 'commons-io', version:'2.5' testCompile group: 'com.github.tomakehurst', name: 'wiremock', version:'2.5.1' testCompile group: 'org.slf4j', name: 'slf4j-jdk14', version:'1.7.25' + + codacy group: 'com.codacy', name: 'codacy-coverage-reporter', version: '1.0.13' } @@ -89,6 +95,17 @@ task javadocJar(type: Jar, dependsOn: javadoc) { from javadoc.destinationDir } +task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) { + main = "com.codacy.CodacyCoverageReporter" + classpath = configurations.codacy + args = [ + "-l", + "Java", + "-r", + "${buildDir}/reports/jacoco/test/jacocoTestReport.xml" + ] +} + // add javadoc/source jar tasks as artifacts artifacts { archives sourcesJar, javadocJar From e4c4fee8a3a90e8f3f662d2f42f053f11a4975d1 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 16:38:52 +0200 Subject: [PATCH 29/74] sendCoverageToCodacy --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d6b0cac..d3b73e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,10 +5,12 @@ jdk: before_install: - chmod +x ./gradlew +build: gradle check sendCoverageToCodacy + deploy: - provider: script skip_cleanup: true - script: gradlew install sendCoverageToCodacy bintrayUpload + script: gradlew install bintrayUpload on: tags: true From ef4803eaf05ec2f8f91f53249e1dc1c8dd96378b Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 16:46:33 +0200 Subject: [PATCH 30/74] gradlew check sendCoverageToCodacy --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3b73e3..b6c5ac7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,12 @@ language: java jdk: -- oraclejdk8 + - oraclejdk8 before_install: -- chmod +x ./gradlew + - chmod +x ./gradlew -build: gradle check sendCoverageToCodacy +script: + - gradlew check sendCoverageToCodacy deploy: - provider: script From 4d0d5e94534f023bbf40e8db81d0ec7a6b35bf24 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 3 Apr 2017 16:48:34 +0200 Subject: [PATCH 31/74] ./gradlew --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b6c5ac7..146df53 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ before_install: - chmod +x ./gradlew script: - - gradlew check sendCoverageToCodacy + - ./gradlew check sendCoverageToCodacy deploy: - provider: script From bc06fee293feeba1339a988883b490367af26651 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 08:51:55 +0200 Subject: [PATCH 32/74] Extended Tests, implemented checkProperties --- src/main/java/com/sybit/airtable/Table.java | 52 ++++++++++++++----- .../sybit/airtable/TableCreateRecordTest.java | 35 ++++++++++--- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 65023ed..487c4d7 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -13,6 +13,7 @@ import com.mashape.unirest.request.GetRequest; import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.exception.HttpResponseExceptionHandler; +import com.sybit.airtable.vo.Attachment; import com.sybit.airtable.vo.Delete; import com.sybit.airtable.vo.PostRecord; import com.sybit.airtable.vo.RecordItem; @@ -323,23 +324,13 @@ public T find(String id) throws AirtableException { * @throws InvocationTargetException * @throws NoSuchMethodException */ - public T create(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException { + public T create(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { RecordItem responseBody = null; - - if(propertyExists(item,"id") || propertyExists(item,"createdTime")){ - Field[] attributes = item.getClass().getDeclaredFields(); - for (Field attribute : attributes) { - String name = attribute.getName(); - if (name.equals("id") || name.equals("createdTime")) { - if(BeanUtils.getProperty(item,attribute.getName()) != null){ - throw new AirtableException("Property "+name+" should be null!"); - } - } - } - } - + + checkProperties(item); + PostRecord body = new PostRecord(); body.setFields(item); @@ -537,4 +528,37 @@ private static boolean propertyExists (Object bean, String property) { return PropertyUtils.isReadable(bean, property) && PropertyUtils.isWriteable(bean, property); } + + private void checkProperties(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + if(propertyExists(item,"id") || propertyExists(item,"createdTime")){ + Field[] attributes = item.getClass().getDeclaredFields(); + for (Field attribute : attributes) { + String name = attribute.getName(); + if (name.equals("id") || name.equals("createdTime")) { + if(BeanUtils.getProperty(item,attribute.getName()) != null){ + throw new AirtableException("Property "+name+" should be null!"); + } + } else if (name.equals("photos")){ + List obj = (List) BeanUtilsBean.getInstance().getPropertyUtils().getProperty(item, "photos"); + if(obj != null){ + for (int i = 0; i < obj.size(); i++) { + if(propertyExists(obj.get(i),"id") || propertyExists(obj.get(i),"size") || propertyExists(obj.get(i), "type") || propertyExists(obj.get(i), "filename")){ + Field[] attributesPhotos = item.getClass().getDeclaredFields(); + for (Field attributePhoto : attributesPhotos) { + String namePhotoAttribute = attributePhoto.getName(); + if (namePhotoAttribute.equals("id") || namePhotoAttribute.equals("size") || namePhotoAttribute.equals("Tpye") || namePhotoAttribute.equals("filename")) { + if(BeanUtils.getProperty(obj.get(i),namePhotoAttribute) != null){ + throw new AirtableException("Property "+namePhotoAttribute+" should be null!"); + } + } + } + } + } + } + } + } + } + + } } diff --git a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java index cfc9884..3a64930 100644 --- a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java +++ b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java @@ -25,7 +25,30 @@ public class TableCreateRecordTest extends WireMockBaseTest { @Test(expected = AirtableException.class) - public void createMovieWithId() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + public void createMovieWithPhotoIdTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + Base base = airtable.base("appe9941ff07fffcc"); + + Table movieTable = base.table("Movies", Movie.class); + Movie newMovie = new Movie(); + newMovie.setName("Neuer Film"); + + List photos = new ArrayList(); + Attachment photo1 = new Attachment(); + + photo1.setUrl("https://www.example.imgae.file1.de"); + photo1.setId("1"); + + photos.add(photo1); + + newMovie.setPhotos(photos); + + Movie test = movieTable.create(newMovie); + + } + + @Test(expected = AirtableException.class) + public void createMovieWithIdTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ Base base = airtable.base("appe9941ff07fffcc"); @@ -38,7 +61,7 @@ public void createMovieWithId() throws AirtableException, IllegalAccessException } @Test(expected = AirtableException.class) - public void createMovieWithCreatedTime() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + public void createMovieWithCreatedTimeTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ Base base = airtable.base("appe9941ff07fffcc"); @@ -51,7 +74,7 @@ public void createMovieWithCreatedTime() throws AirtableException, IllegalAccess } @Test - public void createActorTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + public void createActorTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ Base base = airtable.base("appe9941ff07fffcc"); @@ -65,7 +88,7 @@ public void createActorTest() throws AirtableException, IllegalAccessException, } @Test - public void createMovieWithAttachementTest() throws AirtableException, IllegalAccessException, NoSuchMethodException, NoSuchMethodException, InstantiationException, InvocationTargetException { + public void createMovieWithAttachementTest() throws AirtableException, IllegalAccessException, NoSuchMethodException, NoSuchMethodException, InstantiationException, InvocationTargetException, NoSuchFieldException { Base base = airtable.base("appe9941ff07fffcc"); @@ -95,7 +118,7 @@ public void createMovieWithAttachementTest() throws AirtableException, IllegalAc } @Test - public void createMovieTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException{ + public void createMovieTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ Base base = airtable.base("appe9941ff07fffcc"); @@ -114,8 +137,6 @@ public void createMovieTest() throws AirtableException, IllegalAccessException, List genre = new ArrayList<>(); genre.add("Drama"); newMovie.setGenre(genre); - //Date d = new Date(); - //newMovie.setCreatedTime(d); Movie test = movieTable.create(newMovie); From ae9050dd858b0677597fa9cfbdf0f4fa742218cb Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 11:21:19 +0200 Subject: [PATCH 33/74] Updated Readme and Documentation --- README.md | 20 ++++++++++++++++++++ src/main/java/com/sybit/airtable/Table.java | 16 +++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 97a404b..7f0be78 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,26 @@ Table actorTable = base.table("Actors", Actor.class); actorTable.destroy("recapJ3Js8AEwt0Bf"); ``` +## Create +First build your record. Then use Create to generate a specific records of table: + ++ `Table actorTable = base.table("Actors", Actor.class); + Actor newActor = new Actor(); + newActor.setName("Neuer Actor");`: build your record + + `Actor test = actorTable.create(newActor);`: create the recently build record + +### Example +```Java +// detailed Example see TableCreateTest.java +Base base = airtable.base("AIRTABLE_BASE"); + +Table actorTable = base.table("Actors", Actor.class); +Actor newActor = new Actor(); +newActor.setName("Neuer Actor"); +Actor test = actorTable.create(newActor); +``` + ## Annotations Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter. diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 487c4d7..e3cb06e 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -325,8 +325,7 @@ public T find(String id) throws AirtableException { * @throws NoSuchMethodException */ public T create(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { - - + RecordItem responseBody = null; checkProperties(item); @@ -334,7 +333,6 @@ public T create(T item) throws AirtableException, IllegalAccessException, Invoca PostRecord body = new PostRecord(); body.setFields(item); - HttpResponse response; try { response = Unirest.post( getTableEndpointUrl()) @@ -346,8 +344,7 @@ public T create(T item) throws AirtableException, IllegalAccessException, Invoca } catch (UnirestException e) { throw new AirtableException(e); } - - + int code = response.getStatus(); if(200 == code) { @@ -529,6 +526,15 @@ private static boolean propertyExists (Object bean, String property) { PropertyUtils.isWriteable(bean, property); } + /** + * Checks if the Property Values of the item are valid for the Request. + * + * @param item + * @throws AirtableException + * @throws IllegalAccessException + * @throws InvocationTargetException + * @throws NoSuchMethodException + */ private void checkProperties(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { if(propertyExists(item,"id") || propertyExists(item,"createdTime")){ From 03bdd0627a90ca2a1f9f55f3745a631c8214672c Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 11:25:51 +0200 Subject: [PATCH 34/74] Readme changes --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7f0be78..e12e502 100644 --- a/README.md +++ b/README.md @@ -147,15 +147,15 @@ Use the Gson Annotation @SerializedName to annotate Names which contain - or an + [x] Find Record -+ [ ] Create Record ++ [x] Create Record + [ ] Update Record + [x] Delete Record + [ ] Replace Record + General requirements - + [ ] Automatic ObjectMapping + + [x] Automatic ObjectMapping + [x] Read: convert to Objects + [x] Read: conversion of `Attachment`s & `Thumbnail`s - + [ ] Write: convert Objects to JSON + + [x] Write: convert Objects to JSON + [x] Errorhandling # Compiling project From d59a904e09e9a791a14d2c60427d29b833fd81f5 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 11:31:03 +0200 Subject: [PATCH 35/74] Fixed Readme --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index b0521d1..442b55e 100644 --- a/README.md +++ b/README.md @@ -156,13 +156,6 @@ newActor.setName("Neuer Actor"); Actor test = actorTable.create(newActor); ``` -## Annotations - -Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter. - -### Example -```Java -======= # Roadmap Short overview of features, which are supported: From 586b5e08e0b3c35ba7de582109df3a4d479f30d6 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 11:36:36 +0200 Subject: [PATCH 36/74] removed unused imports --- src/main/java/com/sybit/airtable/Table.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index e3cb06e..6e11fe0 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -26,17 +26,11 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; -import java.util.AbstractMap; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashMap; + import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.logging.Level; + import org.apache.commons.beanutils.BeanUtilsBean; /** From b646320189409938046e2dc4e0dd65e21888bbc0 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 11:57:30 +0200 Subject: [PATCH 37/74] extracted Method checkPropertiesOfAttachement --- src/main/java/com/sybit/airtable/Table.java | 35 ++++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 6e11fe0..3944e69 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -541,24 +541,29 @@ private void checkProperties(T item) throws AirtableException, IllegalAccessExce } } else if (name.equals("photos")){ List obj = (List) BeanUtilsBean.getInstance().getPropertyUtils().getProperty(item, "photos"); - if(obj != null){ - for (int i = 0; i < obj.size(); i++) { - if(propertyExists(obj.get(i),"id") || propertyExists(obj.get(i),"size") || propertyExists(obj.get(i), "type") || propertyExists(obj.get(i), "filename")){ - Field[] attributesPhotos = item.getClass().getDeclaredFields(); - for (Field attributePhoto : attributesPhotos) { - String namePhotoAttribute = attributePhoto.getName(); - if (namePhotoAttribute.equals("id") || namePhotoAttribute.equals("size") || namePhotoAttribute.equals("Tpye") || namePhotoAttribute.equals("filename")) { - if(BeanUtils.getProperty(obj.get(i),namePhotoAttribute) != null){ - throw new AirtableException("Property "+namePhotoAttribute+" should be null!"); - } - } - } - } - } - } + checkPropertiesOfAttachement(obj); } } } } + + private void checkPropertiesOfAttachement(List attachements) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{ + + if(attachements != null){ + for (int i = 0; i < attachements.size(); i++) { + if(propertyExists(attachements.get(i),"id") || propertyExists(attachements.get(i),"size") || propertyExists(attachements.get(i), "type") || propertyExists(attachements.get(i), "filename")){ + Field[] attributesPhotos = attachements.getClass().getDeclaredFields(); + for (Field attributePhoto : attributesPhotos) { + String namePhotoAttribute = attributePhoto.getName(); + if (namePhotoAttribute.equals("id") || namePhotoAttribute.equals("size") || namePhotoAttribute.equals("Tpye") || namePhotoAttribute.equals("filename")) { + if(BeanUtils.getProperty(attachements.get(i),namePhotoAttribute) != null){ + throw new AirtableException("Property "+namePhotoAttribute+" should be null!"); + } + } + } + } + } + } + } } From f3f295de16361a313abeca17a9ead47cd402e2b7 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 14:17:03 +0200 Subject: [PATCH 38/74] Implemented Update TableRecord with Tests --- src/main/java/com/sybit/airtable/Table.java | 67 ++++++++++++++++++- .../com/sybit/airtable/TableUpdateTest.java | 41 ++++++++++++ .../resources/__files/body-ActorUpdate.json | 28 ++++++++ .../mappings/mapping-ActorUpdate.json | 11 +++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/sybit/airtable/TableUpdateTest.java create mode 100644 src/test/resources/__files/body-ActorUpdate.json create mode 100644 src/test/resources/mappings/mapping-ActorUpdate.json diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 3944e69..d752134 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -356,9 +356,43 @@ public T create(T item) throws AirtableException, IllegalAccessException, Invoca return null; } - public T update(T item) { + public T update(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + RecordItem responseBody = null; + + String id = getIdOfItem(item); + + PostRecord body = new PostRecord(); + body.setFields(filterFields(item)); + + HttpResponse response; + try { + response = Unirest.patch( getTableEndpointUrl()+"/"+id) + .header("accept", "application/json") + .header("Authorization", getBearerToken()) + .header("Content-type","application/json") + .body(body) + .asObject(RecordItem.class); + } catch (UnirestException e) { + throw new AirtableException(e); + } + + int code = response.getStatus(); + + if(200 == code) { + responseBody = response.getBody(); + } else { + HttpResponseExceptionHandler.onResponse(response); + } + + try { + return transform(responseBody, this.type.newInstance() ); + } catch (InvocationTargetException | IllegalAccessException | InstantiationException e) { + LOG.error(e.getMessage(), e); + } + + return null; - throw new UnsupportedOperationException("not yet implemented"); } public T replace(T item) { @@ -566,4 +600,33 @@ private void checkPropertiesOfAttachement(List attachements) throws } } } + + private String getIdOfItem(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + if(propertyExists(item,"id")){ + String id = BeanUtils.getProperty(item, "id"); + if(!id.equals(null)){ + return id; + } + } + throw new AirtableException("Id of "+item+" not Found!"); + } + + private T filterFields(T item) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + + System.out.println(item); + + Field[] attributes = item.getClass().getDeclaredFields(); + + for (Field attribute : attributes) { + String name = attribute.getName(); + if (name.equals("id") || name.equals("createdTime")) { + if(BeanUtils.getProperty(item,attribute.getName()) != null){ + BeanUtilsBean.getInstance().getPropertyUtils().setProperty(item, name, null); + } + } + } + + return item; + } } diff --git a/src/test/java/com/sybit/airtable/TableUpdateTest.java b/src/test/java/com/sybit/airtable/TableUpdateTest.java new file mode 100644 index 0000000..e9a0b0d --- /dev/null +++ b/src/test/java/com/sybit/airtable/TableUpdateTest.java @@ -0,0 +1,41 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable; + +import com.sybit.airtable.exception.AirtableException; +import com.sybit.airtable.movies.Actor; +import com.sybit.airtable.test.WireMockBaseTest; +import java.lang.reflect.InvocationTargetException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +/** + * + * @author fzr + */ +public class TableUpdateTest extends WireMockBaseTest { + + @Test + public void testUpdateActor() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{ + + Base base = airtable.base("appe9941ff07fffcc"); + + Table actorTable = base.table("Actors", Actor.class); + Actor marlonBrando = new Actor(); + marlonBrando.setId("rec514228ed76ced1"); + marlonBrando.setName("Neuer Name"); + + Actor updated = actorTable.update(marlonBrando); + + assertEquals(updated.getName(),"Neuer Name"); + assertNotNull(updated.getBiography()); + assertNotNull(updated.getFilmography()); + assertNotNull(updated.getPhoto()); + assertNotNull(updated.getId()); + + } +} diff --git a/src/test/resources/__files/body-ActorUpdate.json b/src/test/resources/__files/body-ActorUpdate.json new file mode 100644 index 0000000..f06a759 --- /dev/null +++ b/src/test/resources/__files/body-ActorUpdate.json @@ -0,0 +1,28 @@ +{ + "id": "rec514228ed76ced1", + "fields": { + "Name": "Neuer Name", + "Filmography": [ + "rec6733da527dd0f1" + ], + "Photo": [ + { + "id": "att1b7c05d697c0c1", + "url": "https://www.filepicker.io/api/file/xlhctgHEQiSGNc0ieMec", + "filename": "220px-Marlon_Brando_-_The_Wild_One.jpg", + "size": 13845, + "type": "image/jpeg", + "thumbnails": { + "small": { + "url": "https://www.filepicker.io/api/file/Rh3L1DL7QAe8nleanQVV" + }, + "large": { + "url": "https://www.filepicker.io/api/file/hcrLCStVRX6LNVEHqtXA" + } + } + } + ], + "Biography": "Marlon Brando, Jr. (April 3, 1924 – July 1, 2004) was an American actor. He is hailed for bringing a gripping realism to film acting, and is widely co..." + }, + "createdTime": "2014-07-18T04:48:25.000Z" +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ActorUpdate.json b/src/test/resources/mappings/mapping-ActorUpdate.json new file mode 100644 index 0000000..29fb493 --- /dev/null +++ b/src/test/resources/mappings/mapping-ActorUpdate.json @@ -0,0 +1,11 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Actors/rec514228ed76ced1", + "method" : "PATCH", + "bodyPatterns" : [{"equalToJson" : "{\"fields\":{\"Name\": \"Neuer Name\"}}"}] + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ActorUpdate.json" + } +} \ No newline at end of file From bc24394b2e8f7e53efe8f2bd3beb650742d3c5a8 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 14:23:17 +0200 Subject: [PATCH 39/74] Updated Documentation --- README.md | 20 +++++++++++++++++-- src/main/java/com/sybit/airtable/Table.java | 22 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 442b55e..55a6bae 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ actorTable.destroy("recapJ3Js8AEwt0Bf"); Detailed example see [TableDestroyTest.java](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableDestroyTest.java) ## Create -First build your record. Then use Create to generate a specific records of table: +First build your record. Then use `create` to generate a specific records of table: + `Table actorTable = base.table("Actors", Actor.class); Actor newActor = new Actor(); @@ -156,6 +156,22 @@ newActor.setName("Neuer Actor"); Actor test = actorTable.create(newActor); ``` +## Update +Use `update` to update a record of table: + ++ `Actor.setName("New Name");`: update the value + + `Actor test = actorTable.update(Actor);`: updates the Actor + +### Example +```Java +// detailed Example see TableCreateTest.java +Base base = airtable.base("appe9941ff07fffcc"); + +Actor.setName("Neuer Name"); +Actor updated = actorTable.update(marlonBrando); +``` + # Roadmap Short overview of features, which are supported: @@ -174,7 +190,7 @@ Short overview of features, which are supported: + [x] Find Record + [x] Create Record -+ [ ] Update Record ++ [x] Update Record + [x] Delete/Destroy Record + [ ] Replace Record + General requirements diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index d752134..1fc91fc 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -600,6 +600,18 @@ private void checkPropertiesOfAttachement(List attachements) throws } } } + + /** + * + * Get the String Id from the item. + * + * @param item + * @return + * @throws AirtableException + * @throws IllegalAccessException + * @throws InvocationTargetException + * @throws NoSuchMethodException + */ private String getIdOfItem(T item) throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { @@ -612,6 +624,16 @@ private String getIdOfItem(T item) throws AirtableException, IllegalAccessExcept throw new AirtableException("Id of "+item+" not Found!"); } + /** + * + * Filter the Fields of the PostRecord Object. Id and created Time are set to null so Object Mapper doesent convert them to JSON. + * + * @param item + * @return + * @throws IllegalAccessException + * @throws InvocationTargetException + * @throws NoSuchMethodException + */ private T filterFields(T item) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { System.out.println(item); From eb370cc57f9e7f7af036b9f31bf5e37ccbc4b104 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 15:47:37 +0200 Subject: [PATCH 40/74] Updated Documentation --- README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 55a6bae..a2ce228 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,55 @@ The Java implementation of the Airtable API provides automatic Object mapping. * How to create objects * Basic objects (attachment, thumbnails, ...) +### Create an Object + +### Basic Objects +The Java implementation of the Airtable API provides an implementation of Basic Airtable Objects such as Attachements and Thumbnails. +Photos and Attached Files in Airtable are retrieved as Attachements. Photos furthermore cointain Thumbnail Objects in different sizes. + +## Attachement +All the Attachement Objects got the following attributes: +`public class Attachment { + + private String id; + private String url; + private String filename; + private Float size; + private String type; + +}` + +* String `id` +* String `url` +* String `filename` +* Float `size` +* String `type` + +Photos additionally have: +`private Map thumbnails;` + +* Map `thumbnails` + +## Thumbnails +A Thumbnail is generated for Photo Objects in Airtable. Thumbnails are bound to an Attachement Object as a key/value Map. +The Keys are `small` and `large` for the different sizes. The Value is a Thumbnail Object. + +A Thumbnail got the following Attributes: + +`public class Thumbnail { + + private String name; + + private String url; + private Float width; + private Float height; +}` +* String `name` +* String `url` +* Float `width` +* Float `height` + +Note: The `name` of a Thumbnail Object is identical with it´s key. ### Annotations @@ -159,9 +208,9 @@ Actor test = actorTable.create(newActor); ## Update Use `update` to update a record of table: -+ `Actor.setName("New Name");`: update the value ++ `Actor.setName("New Name");`: set or update to a new Value - `Actor test = actorTable.update(Actor);`: updates the Actor + `Actor test = actorTable.update(Actor);`: update the Actor in the Table ### Example ```Java @@ -192,7 +241,6 @@ Short overview of features, which are supported: + [x] Create Record + [x] Update Record + [x] Delete/Destroy Record -+ [ ] Replace Record + General requirements + [x] Automatic ObjectMapping + [x] Read: convert to Objects From 9d8162bdd7b8fa9a9dc2ab218ee017100740f42d Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 15:49:26 +0200 Subject: [PATCH 41/74] updated Readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a2ce228..ef36316 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Photos and Attached Files in Airtable are retrieved as Attachements. Photos furt ## Attachement All the Attachement Objects got the following attributes: -`public class Attachment { +```public class Attachment { private String id; private String url; @@ -90,7 +90,7 @@ All the Attachement Objects got the following attributes: private Float size; private String type; -}` +}``` * String `id` * String `url` @@ -99,7 +99,7 @@ All the Attachement Objects got the following attributes: * String `type` Photos additionally have: -`private Map thumbnails;` +```private Map thumbnails;``` * Map `thumbnails` @@ -109,14 +109,14 @@ The Keys are `small` and `large` for the different sizes. The Value is a Thumbna A Thumbnail got the following Attributes: -`public class Thumbnail { +```public class Thumbnail { private String name; private String url; private Float width; private Float height; -}` +}``` * String `name` * String `url` * Float `width` From cdcd46b1dfde9313664f57a52d3016192d364e8e Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 15:50:50 +0200 Subject: [PATCH 42/74] Updated Readme --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ef36316..d036ddc 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,8 @@ Photos and Attached Files in Airtable are retrieved as Attachements. Photos furt ## Attachement All the Attachement Objects got the following attributes: -```public class Attachment { +```Java +public class Attachment { private String id; private String url; @@ -90,7 +91,8 @@ All the Attachement Objects got the following attributes: private Float size; private String type; -}``` +} +``` * String `id` * String `url` @@ -99,7 +101,9 @@ All the Attachement Objects got the following attributes: * String `type` Photos additionally have: -```private Map thumbnails;``` +```Java +private Map thumbnails; +``` * Map `thumbnails` @@ -109,14 +113,16 @@ The Keys are `small` and `large` for the different sizes. The Value is a Thumbna A Thumbnail got the following Attributes: -```public class Thumbnail { +```Java +public class Thumbnail { private String name; private String url; private Float width; private Float height; -}``` +} +``` * String `name` * String `url` * Float `width` From fe367f868ff50f3392e7d86c7e88f00165973593 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 15:52:29 +0200 Subject: [PATCH 43/74] updated Readme --- README.md | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index d036ddc..b70d767 100644 --- a/README.md +++ b/README.md @@ -80,19 +80,8 @@ The Java implementation of the Airtable API provides automatic Object mapping. The Java implementation of the Airtable API provides an implementation of Basic Airtable Objects such as Attachements and Thumbnails. Photos and Attached Files in Airtable are retrieved as Attachements. Photos furthermore cointain Thumbnail Objects in different sizes. -## Attachement +#### Attachement All the Attachement Objects got the following attributes: -```Java -public class Attachment { - - private String id; - private String url; - private String filename; - private Float size; - private String type; - -} -``` * String `id` * String `url` @@ -101,28 +90,15 @@ public class Attachment { * String `type` Photos additionally have: -```Java -private Map thumbnails; -``` * Map `thumbnails` -## Thumbnails +#### Thumbnails A Thumbnail is generated for Photo Objects in Airtable. Thumbnails are bound to an Attachement Object as a key/value Map. The Keys are `small` and `large` for the different sizes. The Value is a Thumbnail Object. A Thumbnail got the following Attributes: -```Java -public class Thumbnail { - - private String name; - - private String url; - private Float width; - private Float height; -} -``` * String `name` * String `url` * Float `width` From baf2ae0c1b6bbb853d38ac4c77f2aff99fd734a0 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 4 Apr 2017 15:57:32 +0200 Subject: [PATCH 44/74] Updated Readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index b70d767..4a963d0 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,14 @@ The Java implementation of the Airtable API provides automatic Object mapping. * Basic objects (attachment, thumbnails, ...) ### Create an Object +The Java Objects represent records or 'values' in Airtable. So the Object attributes need to be adjusted to the Airtable Base. + +#### Example + +In Aritable we got a Table Actor. The coulumns represent the Object attributes. + +*TODO:* +* Add Table ### Basic Objects The Java implementation of the Airtable API provides an implementation of Basic Airtable Objects such as Attachements and Thumbnails. From 5d9f27209536055138e3d9122946c0eb4306c110 Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 5 Apr 2017 15:59:14 +0200 Subject: [PATCH 45/74] switch commands --- .travis.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 146df53..e085255 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,12 +9,6 @@ script: - ./gradlew check sendCoverageToCodacy deploy: - - provider: script - skip_cleanup: true - script: gradlew install bintrayUpload - on: - tags: true - - provider: releases api_key: secure: ltLzm1VWcBj5sLTqtEUQyd3JG5pYZ6nQG5czsWB28hvJ3wkVa6vt7L5j3OS8wZuaIdE6eDJ2rMfQ5qS1FAE91SiQfCsMArsZ5C2cWm7BSz70MAa2zCWgxxlMsvARTnSLaP9mVgbZN0js2p0ETVVuUj+MG1dQJGXhsggmFI3ZSxCnWpoAhtGDVvQr8BZp4w5hPJ0Xm144v9ZnT2oUwmwevlVFzO+QzjiUJwPCjy4y6rJAJDdYdY0mTUQq7Y9SwkjXQACNwDRs6ITQ4nbClCk7RtDIKUFYWvuq9IRD0OhVXibTtMC4yocl+PsM6XvCYCAWPjLon20Pc2fdepzWhYPkyoOf9SDDUFAHEjYQ+vw2BkQpx3WwMZDLJbGXI1z0+evYUhSxr7oRSzoRfpCYFtEJ7toLb8SPTsYkyQQp5N1EDNtnIgBZhsQpFdxDgZ8vrVeWiLVtzX5ARgz0GV/yL2v+2ZzPg7usEJSNC6xwyjGiPGDtggUy2HIsP1ohl56VVvU5RjfoKcXxysbm0L43sddZHIuNggyku7pNlYsgHdrUf/0qanxxrU46w8M4vUdyd1oC/pXwaUkpdjA6nFU+ouoX1ScihxZzlkE2TYEFJqbKcWQ8d9zeYW90pemc8oWZJcylyF0ef2MJKy3DgNplnoSJM6q6sDunAA5wGN5A+vu/Ahw= @@ -24,6 +18,11 @@ deploy: repo: Sybit-Education/airtable.java tags: true + - provider: script + skip_cleanup: true + script: gradlew install bintrayUpload + on: + tags: true before_cache: From 63caa9662155f11deeb9d7fff5160ecf988e3997 Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 5 Apr 2017 16:10:06 +0200 Subject: [PATCH 46/74] updated file filter --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e085255..b0f7097 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ deploy: api_key: secure: ltLzm1VWcBj5sLTqtEUQyd3JG5pYZ6nQG5czsWB28hvJ3wkVa6vt7L5j3OS8wZuaIdE6eDJ2rMfQ5qS1FAE91SiQfCsMArsZ5C2cWm7BSz70MAa2zCWgxxlMsvARTnSLaP9mVgbZN0js2p0ETVVuUj+MG1dQJGXhsggmFI3ZSxCnWpoAhtGDVvQr8BZp4w5hPJ0Xm144v9ZnT2oUwmwevlVFzO+QzjiUJwPCjy4y6rJAJDdYdY0mTUQq7Y9SwkjXQACNwDRs6ITQ4nbClCk7RtDIKUFYWvuq9IRD0OhVXibTtMC4yocl+PsM6XvCYCAWPjLon20Pc2fdepzWhYPkyoOf9SDDUFAHEjYQ+vw2BkQpx3WwMZDLJbGXI1z0+evYUhSxr7oRSzoRfpCYFtEJ7toLb8SPTsYkyQQp5N1EDNtnIgBZhsQpFdxDgZ8vrVeWiLVtzX5ARgz0GV/yL2v+2ZzPg7usEJSNC6xwyjGiPGDtggUy2HIsP1ohl56VVvU5RjfoKcXxysbm0L43sddZHIuNggyku7pNlYsgHdrUf/0qanxxrU46w8M4vUdyd1oC/pXwaUkpdjA6nFU+ouoX1ScihxZzlkE2TYEFJqbKcWQ8d9zeYW90pemc8oWZJcylyF0ef2MJKy3DgNplnoSJM6q6sDunAA5wGN5A+vu/Ahw= skip_cleanup: true - file: ./build/libs/* + file: ./build/libs/*.jar on: repo: Sybit-Education/airtable.java tags: true From cb1be8a1d371b5755654da7195ace3e7da06894b Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 5 Apr 2017 16:36:03 +0200 Subject: [PATCH 47/74] deploy correction --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b0f7097..1c5e0ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,8 @@ deploy: api_key: secure: ltLzm1VWcBj5sLTqtEUQyd3JG5pYZ6nQG5czsWB28hvJ3wkVa6vt7L5j3OS8wZuaIdE6eDJ2rMfQ5qS1FAE91SiQfCsMArsZ5C2cWm7BSz70MAa2zCWgxxlMsvARTnSLaP9mVgbZN0js2p0ETVVuUj+MG1dQJGXhsggmFI3ZSxCnWpoAhtGDVvQr8BZp4w5hPJ0Xm144v9ZnT2oUwmwevlVFzO+QzjiUJwPCjy4y6rJAJDdYdY0mTUQq7Y9SwkjXQACNwDRs6ITQ4nbClCk7RtDIKUFYWvuq9IRD0OhVXibTtMC4yocl+PsM6XvCYCAWPjLon20Pc2fdepzWhYPkyoOf9SDDUFAHEjYQ+vw2BkQpx3WwMZDLJbGXI1z0+evYUhSxr7oRSzoRfpCYFtEJ7toLb8SPTsYkyQQp5N1EDNtnIgBZhsQpFdxDgZ8vrVeWiLVtzX5ARgz0GV/yL2v+2ZzPg7usEJSNC6xwyjGiPGDtggUy2HIsP1ohl56VVvU5RjfoKcXxysbm0L43sddZHIuNggyku7pNlYsgHdrUf/0qanxxrU46w8M4vUdyd1oC/pXwaUkpdjA6nFU+ouoX1ScihxZzlkE2TYEFJqbKcWQ8d9zeYW90pemc8oWZJcylyF0ef2MJKy3DgNplnoSJM6q6sDunAA5wGN5A+vu/Ahw= skip_cleanup: true - file: ./build/libs/*.jar + file_glob: true + file: ./build/libs/* on: repo: Sybit-Education/airtable.java tags: true From 5dd3985b3369cae109d1bc68e8ef9c2a71035300 Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 5 Apr 2017 16:49:59 +0200 Subject: [PATCH 48/74] travis deploy --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1c5e0ff..2c2602b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,12 @@ script: - ./gradlew check sendCoverageToCodacy deploy: + - provider: script + skip_cleanup: true + script: gradlew install bintrayUpload + on: + tags: true + - provider: releases api_key: secure: ltLzm1VWcBj5sLTqtEUQyd3JG5pYZ6nQG5czsWB28hvJ3wkVa6vt7L5j3OS8wZuaIdE6eDJ2rMfQ5qS1FAE91SiQfCsMArsZ5C2cWm7BSz70MAa2zCWgxxlMsvARTnSLaP9mVgbZN0js2p0ETVVuUj+MG1dQJGXhsggmFI3ZSxCnWpoAhtGDVvQr8BZp4w5hPJ0Xm144v9ZnT2oUwmwevlVFzO+QzjiUJwPCjy4y6rJAJDdYdY0mTUQq7Y9SwkjXQACNwDRs6ITQ4nbClCk7RtDIKUFYWvuq9IRD0OhVXibTtMC4yocl+PsM6XvCYCAWPjLon20Pc2fdepzWhYPkyoOf9SDDUFAHEjYQ+vw2BkQpx3WwMZDLJbGXI1z0+evYUhSxr7oRSzoRfpCYFtEJ7toLb8SPTsYkyQQp5N1EDNtnIgBZhsQpFdxDgZ8vrVeWiLVtzX5ARgz0GV/yL2v+2ZzPg7usEJSNC6xwyjGiPGDtggUy2HIsP1ohl56VVvU5RjfoKcXxysbm0L43sddZHIuNggyku7pNlYsgHdrUf/0qanxxrU46w8M4vUdyd1oC/pXwaUkpdjA6nFU+ouoX1ScihxZzlkE2TYEFJqbKcWQ8d9zeYW90pemc8oWZJcylyF0ef2MJKy3DgNplnoSJM6q6sDunAA5wGN5A+vu/Ahw= @@ -19,12 +25,6 @@ deploy: repo: Sybit-Education/airtable.java tags: true - - provider: script - skip_cleanup: true - script: gradlew install bintrayUpload - on: - tags: true - before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock From 5f78b9ad67f2e43f60207c736c9444e68442feb0 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 7 Apr 2017 08:17:23 +0200 Subject: [PATCH 49/74] Edited Readme --- README.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4a963d0..7b50dc1 100644 --- a/README.md +++ b/README.md @@ -67,22 +67,108 @@ logging framework at deployment time. The API of Airtable itself is limited to 5 requests per second. If you exceed this rate, you will receive a 429 status code and will need to wait 30 seconds before subsequent requests will succeed. +*TODO:* +* How to create an Airtable Object +* How to create an Airtable Base + ## Object Mapping -The Java implementation of the Airtable API provides automatic Object mapping. +The Java implementation of the Airtable API provides automatic Object mapping. You can map any Table to your own Java Classes. +But first you need to specify those Classes. - *TODO:* - * How to create objects - * Basic objects (attachment, thumbnails, ...) - -### Create an Object -The Java Objects represent records or 'values' in Airtable. So the Object attributes need to be adjusted to the Airtable Base. +### Create a Object +The Java Objects represent records or 'values' in Airtable. So the Class attributes need to be adjusted to the Airtable Base. #### Example -In Aritable we got a Table Actor. The coulumns represent the Object attributes. +In Aritable we got a Table Actor. The coulumns represent the Class attributes. -*TODO:* -* Add Table +This is how our Actor Table looks like: + +|Index| Name | Photo | Biography | Filmography | +|:---:|:-------------:|:------------:|:----------:|:-------------------------------:| +| 1 | Marlon Brando | Some Photos | Long Text | Reference to the Movie Table | +| 2 | Bill Murray | Some Photos | Long Text | Reference to the Movie Table | +| 3 | Al Pacino | Some Photos | Long Text | Reference to the Movie Table | +| ... | ... | ... | ... | ... | + +Now our Java Class should look like this: +```Java + + public class Actor { + + private String id; + @SerializedName("Name") + private String name; + @SerializedName("Photo") + private List photo; + @SerializedName("Biography") + private String biography; + @SerializedName("Filmography") + private String[] filmography; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String[] getFilmography() { + return filmography; + } + + public void setFilmography(String[] Filmography) { + this.filmography = Filmography; + } + + public List getPhoto() { + return photo; + } + + public void setPhoto(List Photo) { + this.photo = Photo; + } + + public String getBiography() { + return biography; + } + + public void setBiography(String Biography) { + this.biography = Biography; + } + + + } + +``` +For each column we give the Java Class an attribute with the column name (Be carefull! See more about naming in the Annotation Section) +and add Getters and Setters for each attribute. The attribute types can be either primitive Java types like `String` and `Float` for Text and Numbers, +`String Array` for references on other Tables or `Attachment` for attached photos and files. + + +Now we got everything we need to create our first Airtable Table Object. +We use the Java class we just wrote to specify what kind of Object should be saved in our Table. Then we tell our `base` Object which Table we want to access. +All the Records saved in our Airtable DB now should be in our local Table Object. + +Example: + +```Java + + Base base = airtable.base(AIRTABLE_API_KEY); + Table actorTable = base.table(NAME OF THE TABLE, JAVA CLASS); + //Example with the Actor Table + Table actorTable = base.table("Actors", Actor.class); + +``` ### Basic Objects The Java implementation of the Airtable API provides an implementation of Basic Airtable Objects such as Attachements and Thumbnails. From 800bad718d79dde37769afc8b61c36fee88be2d6 Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 7 Apr 2017 08:28:52 +0200 Subject: [PATCH 50/74] updated Codacy Issues --- src/main/java/com/sybit/airtable/Table.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 1fc91fc..ef18db4 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -617,7 +617,7 @@ private String getIdOfItem(T item) throws AirtableException, IllegalAccessExcept if(propertyExists(item,"id")){ String id = BeanUtils.getProperty(item, "id"); - if(!id.equals(null)){ + if(id != null){ return id; } } @@ -642,10 +642,8 @@ private T filterFields(T item) throws IllegalAccessException, InvocationTargetEx for (Field attribute : attributes) { String name = attribute.getName(); - if (name.equals("id") || name.equals("createdTime")) { - if(BeanUtils.getProperty(item,attribute.getName()) != null){ - BeanUtilsBean.getInstance().getPropertyUtils().setProperty(item, name, null); - } + if ((name.equals("id") || name.equals("createdTime")) && (BeanUtils.getProperty(item,name) != null)) { + BeanUtilsBean.getInstance().getPropertyUtils().setProperty(item, name, null); } } From 4470ca234e4ab804af47904e79c0ba4c3ddd625f Mon Sep 17 00:00:00 2001 From: fzr Date: Fri, 7 Apr 2017 16:03:38 +0200 Subject: [PATCH 51/74] Started Parameter Tests --- src/main/java/com/sybit/airtable/Query.java | 10 ++ src/main/java/com/sybit/airtable/Table.java | 85 +++++++++ .../sybit/airtable/TableParameterTest.java | 164 ++++++++++++++++++ .../sybit/airtable/test/WireMockBaseTest.java | 2 +- 4 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/sybit/airtable/TableParameterTest.java diff --git a/src/main/java/com/sybit/airtable/Query.java b/src/main/java/com/sybit/airtable/Query.java index d22bfb6..43beb16 100644 --- a/src/main/java/com/sybit/airtable/Query.java +++ b/src/main/java/com/sybit/airtable/Query.java @@ -12,6 +12,16 @@ */ @SuppressWarnings("WeakerAccess") public interface Query { + + /** + * @return Fields to be loaded + */ + String [] getFields(); + + /** + * @return the number of records per page + */ + Integer getPageSize(); /** * @return number of max rows to load. diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 3944e69..e15c573 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -103,6 +103,16 @@ public List getSort() { public String filterByFormula() { return null; } + + @Override + public String[] getFields() { + return null; + } + + @Override + public Integer getPageSize() { + return null; + } }); } @@ -122,6 +132,9 @@ public List select(Query query) throws AirtableException { GetRequest request = Unirest.get(getTableEndpointUrl()) .header("accept", "application/json") .header("Authorization", getBearerToken()); + if(query.getFields() != null && query.getFields().length > 0){ + request.queryString("fields",query.getFields()); + } if(query.getMaxRecords() != null) { request.queryString("maxRecords", query.getMaxRecords()); } @@ -131,6 +144,13 @@ public List select(Query query) throws AirtableException { if(query.filterByFormula() != null) { request.queryString("filterByFormula", query.filterByFormula()); } + if(query.getPageSize() != null){ + if (query.getPageSize() > 100) { + request.queryString("pageSize",100); + } else { + request.queryString("pageSize",query.getPageSize()); + } + } if(query.getSort() != null) { int i = 0; for (Sort sort : query.getSort()) { @@ -180,6 +200,16 @@ public List getSort() { public String filterByFormula() { return null; } + + @Override + public String[] getFields() { + return null; + } + + @Override + public Integer getPageSize() { + return null; + } }); } @@ -211,6 +241,16 @@ public List getSort() { public String filterByFormula() { return null; } + + @Override + public String[] getFields() { + return null; + } + + @Override + public Integer getPageSize() { + return null; + } }); } @@ -245,6 +285,51 @@ public List getSort() { public String filterByFormula() { return null; } + + @Override + public String[] getFields() { + return null; + } + + @Override + public Integer getPageSize() { + return null; + } + }); + } + + public List select(String[] fields) throws AirtableException, HttpResponseException { + + return select(new Query() { + @Override + public Integer getMaxRecords() { + return null; + } + + @Override + public String getView() { + return null; + } + + @Override + public List getSort() { + return null; + } + + @Override + public String filterByFormula() { + return null; + } + + @Override + public String[] getFields() { + return fields; + } + + @Override + public Integer getPageSize() { + return null; + } }); } diff --git a/src/test/java/com/sybit/airtable/TableParameterTest.java b/src/test/java/com/sybit/airtable/TableParameterTest.java new file mode 100644 index 0000000..c9c5295 --- /dev/null +++ b/src/test/java/com/sybit/airtable/TableParameterTest.java @@ -0,0 +1,164 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.sybit.airtable; + +import com.sybit.airtable.exception.AirtableException; +import com.sybit.airtable.movies.Movie; +import com.sybit.airtable.test.WireMockBaseTest; +import java.util.ArrayList; +import java.util.List; +import org.apache.http.client.HttpResponseException; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +/** + * + * @author fzr + */ +public class TableParameterTest extends WireMockBaseTest { + + @Test + public void fieldsParamTest() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table movieTable = base.table("Movies", Movie.class); + + String[] fields = new String[1]; + fields[0] = "Name"; + + List listMovies = movieTable.select(fields); + assertNotNull(listMovies); + + } + + @Test + public void formulaParamTest() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table movieTable = base.table("Movies", Movie.class); + + Query query = new Query() { + @Override + public String[] getFields() { + return null; + } + + @Override + public Integer getPageSize() { + return null; + } + + @Override + public Integer getMaxRecords() { + return null; + } + + @Override + public String getView() { + return null; + } + + @Override + public List getSort() { + return null; + } + + @Override + public String filterByFormula() { + return "FORMULA"; + } + }; + + List listMovies = movieTable.select(query); + assertNotNull(listMovies); + + } + + @Test + public void maxRecordsParamTest() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table movieTable = base.table("Movies", Movie.class); + + int maxRecords = 10; + + List listMovies = movieTable.select(maxRecords); + assertNotNull(listMovies); + //Working + } + + //TODO both integer impossible + @Test + public void pageSizeParamTest() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table movieTable = base.table("Movies", Movie.class); + + Query query = new Query() { + @Override + public String[] getFields() { + return null; + } + + @Override + public Integer getPageSize() { + return 10; + } + + @Override + public Integer getMaxRecords() { + return null; + } + + @Override + public String getView() { + return null; + } + + @Override + public List getSort() { + return null; + } + + @Override + public String filterByFormula() { + return null; + } + }; + + List listMovies = movieTable.select(query); + assertNotNull(listMovies); + //working + } + + @Test + public void sortParamTest() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table movieTable = base.table("Movies", Movie.class); + + + List listMovies; + + } + + @Test + public void viewParamTest() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table movieTable = base.table("Movies", Movie.class); + + String view = "Comedies"; + + + List listMovies = movieTable.select(view); + assertNotNull(listMovies); + //working + } + + + +} diff --git a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java index a195117..2b39a60 100644 --- a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java +++ b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java @@ -31,7 +31,7 @@ public class WireMockBaseTest { @Before public void setup() throws AirtableException { airtable.configure(); - airtable.setEndpointUrl("http://localhost:8080/v0"); + //airtable.setEndpointUrl("http://localhost:8080/v0"); //set 404 as default stubFor(any(anyUrl()) From fbd9675fbda0a303a2b98bfbd8b41c2f7dff3b2e Mon Sep 17 00:00:00 2001 From: fzr Date: Mon, 10 Apr 2017 10:02:03 +0200 Subject: [PATCH 52/74] Implemented Tests for filter and additional Filter Methods --- src/main/java/com/sybit/airtable/Table.java | 31 ++++++++++++--- .../sybit/airtable/TableParameterTest.java | 30 +++++++++----- .../sybit/airtable/test/WireMockBaseTest.java | 2 +- .../__files/body-ParameterSelectFields.json | 39 +++++++++++++++++++ .../__files/body-ParameterSelectFormula.json | 18 +++++++++ .../body-ParameterSelectMaxRecords.json | 27 +++++++++++++ .../__files/body-ParameterSelectPageSize.json | 1 + .../__files/body-ParameterSelectSort.json | 1 + .../__files/body-ParameterSelectView.json | 1 + .../mapping-ParameterSelectFields.json | 10 +++++ .../mapping-ParameterSelectFormula.json | 10 +++++ .../mapping-ParameterSelectMaxRecords.json | 10 +++++ .../mapping-ParameterSelectPageSize.json | 10 +++++ .../mappings/mapping-ParameterSelectSort.json | 10 +++++ .../mappings/mapping-ParameterSelectView.json | 10 +++++ 15 files changed, 194 insertions(+), 16 deletions(-) create mode 100644 src/test/resources/__files/body-ParameterSelectFields.json create mode 100644 src/test/resources/__files/body-ParameterSelectFormula.json create mode 100644 src/test/resources/__files/body-ParameterSelectMaxRecords.json create mode 100644 src/test/resources/__files/body-ParameterSelectPageSize.json create mode 100644 src/test/resources/__files/body-ParameterSelectSort.json create mode 100644 src/test/resources/__files/body-ParameterSelectView.json create mode 100644 src/test/resources/mappings/mapping-ParameterSelectFields.json create mode 100644 src/test/resources/mappings/mapping-ParameterSelectFormula.json create mode 100644 src/test/resources/mappings/mapping-ParameterSelectMaxRecords.json create mode 100644 src/test/resources/mappings/mapping-ParameterSelectPageSize.json create mode 100644 src/test/resources/mappings/mapping-ParameterSelectSort.json create mode 100644 src/test/resources/mappings/mapping-ParameterSelectView.json diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index e15c573..6064b12 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -78,6 +78,8 @@ public void setParent(Base parent) { } /** + * + * If no Parameter ser all querys to null. * * @return * @throws AirtableException @@ -118,7 +120,7 @@ public Integer getPageSize() { } /** - * Select List of data of table. + * Select List of data of table with defined Query Parameters. * * @param query * @return @@ -132,8 +134,11 @@ public List select(Query query) throws AirtableException { GetRequest request = Unirest.get(getTableEndpointUrl()) .header("accept", "application/json") .header("Authorization", getBearerToken()); - if(query.getFields() != null && query.getFields().length > 0){ - request.queryString("fields",query.getFields()); + if(query.getFields() != null && query.getFields().length > 0){ + String[] fields = query.getFields(); + for (int i = 0; i < fields.length; i++) { + request.queryString("fields[]",fields[i]); + } } if(query.getMaxRecords() != null) { request.queryString("maxRecords", query.getMaxRecords()); @@ -178,7 +183,14 @@ public List select(Query query) throws AirtableException { return list; } - + /** + * select with Parameter maxRecords + * + * @param maxRecords + * @return + * @throws AirtableException + * @throws HttpResponseException + */ public List select(Integer maxRecords) throws AirtableException, HttpResponseException { return select(new Query() { @Override @@ -255,7 +267,8 @@ public Integer getPageSize() { } /** - * + *select Table data with defined sortation + * * @param sortation * @return * @throws AirtableException @@ -298,6 +311,14 @@ public Integer getPageSize() { }); } + /** + * select only Table data with defined Fields + * + * @param fields + * @return + * @throws AirtableException + * @throws HttpResponseException + */ public List select(String[] fields) throws AirtableException, HttpResponseException { return select(new Query() { diff --git a/src/test/java/com/sybit/airtable/TableParameterTest.java b/src/test/java/com/sybit/airtable/TableParameterTest.java index c9c5295..3461bc7 100644 --- a/src/test/java/com/sybit/airtable/TableParameterTest.java +++ b/src/test/java/com/sybit/airtable/TableParameterTest.java @@ -8,10 +8,11 @@ import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.movies.Movie; import com.sybit.airtable.test.WireMockBaseTest; -import java.util.ArrayList; import java.util.List; import org.apache.http.client.HttpResponseException; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import org.junit.Test; /** @@ -31,6 +32,9 @@ public void fieldsParamTest() throws AirtableException, HttpResponseException { List listMovies = movieTable.select(fields); assertNotNull(listMovies); + assertNull(listMovies.get(0).getDirector()); + assertNull(listMovies.get(0).getActors()); + assertNull(listMovies.get(0).getDescription()); } @@ -68,12 +72,14 @@ public List getSort() { @Override public String filterByFormula() { - return "FORMULA"; + return "NOT({Name} = '')"; } }; List listMovies = movieTable.select(query); assertNotNull(listMovies); + assertEquals(listMovies.size(),2); + } @@ -83,14 +89,14 @@ public void maxRecordsParamTest() throws AirtableException, HttpResponseExceptio Base base = airtable.base("appe9941ff07fffcc"); Table movieTable = base.table("Movies", Movie.class); - int maxRecords = 10; + int maxRecords = 2; List listMovies = movieTable.select(maxRecords); assertNotNull(listMovies); - //Working + assertEquals(listMovies.size(),2); + } - //TODO both integer impossible @Test public void pageSizeParamTest() throws AirtableException, HttpResponseException { @@ -131,7 +137,7 @@ public String filterByFormula() { List listMovies = movieTable.select(query); assertNotNull(listMovies); - //working + } @Test @@ -139,9 +145,12 @@ public void sortParamTest() throws AirtableException, HttpResponseException { Base base = airtable.base("appe9941ff07fffcc"); Table movieTable = base.table("Movies", Movie.class); + Sort sort = new Sort("Name", Sort.Direction.desc); - - List listMovies; + List listMovies = movieTable.select(sort); + assertNotNull(listMovies); + assertEquals(listMovies.get(9).getName(),"Billy Madison"); + } @@ -151,12 +160,13 @@ public void viewParamTest() throws AirtableException, HttpResponseException { Base base = airtable.base("appe9941ff07fffcc"); Table movieTable = base.table("Movies", Movie.class); - String view = "Comedies"; + String view = "Dramas"; List listMovies = movieTable.select(view); assertNotNull(listMovies); - //working + assertEquals(listMovies.size(),5); + } diff --git a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java index 2b39a60..a195117 100644 --- a/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java +++ b/src/test/java/com/sybit/airtable/test/WireMockBaseTest.java @@ -31,7 +31,7 @@ public class WireMockBaseTest { @Before public void setup() throws AirtableException { airtable.configure(); - //airtable.setEndpointUrl("http://localhost:8080/v0"); + airtable.setEndpointUrl("http://localhost:8080/v0"); //set 404 as default stubFor(any(anyUrl()) diff --git a/src/test/resources/__files/body-ParameterSelectFields.json b/src/test/resources/__files/body-ParameterSelectFields.json new file mode 100644 index 0000000..a3f88e6 --- /dev/null +++ b/src/test/resources/__files/body-ParameterSelectFields.json @@ -0,0 +1,39 @@ +{ + "records":[ + { + "id":"rec110972df115479", + "fields":{ + "Name":"Sister Act" + }, + "createdTime":"2014-07-18T04:42:06.000Z" + }, + { + "id":"rec2ed6bdd802c584", + "fields":{ + "Name":"Forrest Gump" + }, + "createdTime":"2014-07-18T04:56:05.000Z" + }, + { + "id":"rec3ce936056bbf7b", + "fields":{ + "Name":"You've got Mail" + }, + "createdTime":"2014-07-18T04:52:02.000Z" + }, + { + "id":"rec6733da527dd0f1", + "fields":{ + "Name":"The Godfather" + }, + "createdTime":"2014-07-18T04:42:06.000Z" + }, + { + "id":"rec6c1b6022782cd8", + "fields":{ + "Name":"Billy Madison" + }, + "createdTime":"2014-07-18T04:54:18.000Z" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/__files/body-ParameterSelectFormula.json b/src/test/resources/__files/body-ParameterSelectFormula.json new file mode 100644 index 0000000..d352570 --- /dev/null +++ b/src/test/resources/__files/body-ParameterSelectFormula.json @@ -0,0 +1,18 @@ +{ + "records":[ + { + "id":"rec110972df115479", + "fields":{ + "Name":"Sister Act" + }, + "createdTime":"2014-07-18T04:42:06.000Z" + }, + { + "id":"rec2ed6bdd802c584", + "fields":{ + "Name":"Forrest Gump" + }, + "createdTime":"2014-07-18T04:56:05.000Z" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/__files/body-ParameterSelectMaxRecords.json b/src/test/resources/__files/body-ParameterSelectMaxRecords.json new file mode 100644 index 0000000..18675f9 --- /dev/null +++ b/src/test/resources/__files/body-ParameterSelectMaxRecords.json @@ -0,0 +1,27 @@ +{ + "records":[{ + "id":"rec110972df115479", + "fields":{ + "Name":"Sister Act", + "Description":"Sister Act is a 1992 American comedy film released by Touchstone Pictures. Directed by Emile Ardolino, it features musical arrangements by Marc Shaiman and stars Whoopi Goldberg as a Reno lounge singer who has been put under protective custody in a San Francisco convent of Poor Clares and has to pretend to be a nun when a mob boss puts her on his hit list. Also in the cast are Maggie Smith, Kathy Najimy, Wendy Makkena, Mary Wickes, and Harvey Keitel.", + "Photos":[{ + "id":"att9141430d2b6dc1", + "url":"https://www.filepicker.io/api/file/tav0vGKoTjiyMcbjsx3r", + "filename":"Sister_Act_film_poster.jpg", + "size":19805, + "type":"image/jpeg", + "thumbnails":{ + "small":{ + "url":"https://www.filepicker.io/api/file/IiTD31iiQ32mRI6KYEzy" + }, + "large":{ + "url":"https://www.filepicker.io/api/file/Oczxr4sYQ2lrA3ppGMhg" + }} + }], + "Actors":["rec73fcac60a91bc1"], + "Director":["rec114faab248e582"], + "Genre":["Comedy"] + }, + "createdTime":"2014-07-18T04:42:06.000Z" + }] +} \ No newline at end of file diff --git a/src/test/resources/__files/body-ParameterSelectPageSize.json b/src/test/resources/__files/body-ParameterSelectPageSize.json new file mode 100644 index 0000000..2ef12a3 --- /dev/null +++ b/src/test/resources/__files/body-ParameterSelectPageSize.json @@ -0,0 +1 @@ +{"records":[{"id":"rec110972df115479","fields":{"Name":"Sister Act","Description":"Sister Act is a 1992 American comedy film released by Touchstone Pictures. Directed by Emile Ardolino, it features musical arrangements by Marc Shaiman and stars Whoopi Goldberg as a Reno lounge singer who has been put under protective custody in a San Francisco convent of Poor Clares and has to pretend to be a nun when a mob boss puts her on his hit list. Also in the cast are Maggie Smith, Kathy Najimy, Wendy Makkena, Mary Wickes, and Harvey Keitel.","Photos":[{"id":"att9141430d2b6dc1","url":"https://www.filepicker.io/api/file/tav0vGKoTjiyMcbjsx3r","filename":"Sister_Act_film_poster.jpg","size":19805,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/IiTD31iiQ32mRI6KYEzy"},"large":{"url":"https://www.filepicker.io/api/file/Oczxr4sYQ2lrA3ppGMhg"}}}],"Actors":["rec73fcac60a91bc1"],"Director":["rec114faab248e582"],"Genre":["Comedy"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"rec2ed6bdd802c584","fields":{"Name":"Forrest Gump","Description":"Forrest Gump is a 1994 American epic romantic comedy-drama film based on the 1986 novel of the same name by Winston Groom. The film was directed by Robert Zemeckis and starred Tom Hanks, Robin Wright, Gary Sinise and Sally Field. The story depicts several decades in the life of Forrest Gump, a na├»ve and slow-witted yet athletically prodigious native of Alabama who witnesses, and in some cases influences, some of the defining events of the latter half of the 20th century in the United States; more specifically, the period between Forrest's birth in 1944 and 1982.","Photos":[{"id":"att82e0b9087885c0","url":"https://www.filepicker.io/api/file/zJDqSxaWS5SaHvOh1bZT","filename":"220px-Forrest_Gump_poster.jpg","size":16749,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/CrFAmlQGuPXUvYo4bEXQ"},"large":{"url":"https://www.filepicker.io/api/file/QfqP0RxhT16M1Ihnl8s0"}}}],"Actors":["recf38022b2f0db0d"],"Director":["rec09887e80a2692e"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:56:05.000Z"},{"id":"rec3ce936056bbf7b","fields":{"Name":"You've got Mail","Description":"You've Got Mail is a 1998 American romantic comedy film directed by Nora Ephron, starring Tom Hanks and Meg Ryan. It was written by Nora and Delia Ephron based on the 1937[2] play Parfumerie by Mikl├│s L├íszl├│. The film is about two e-mailing lovers who are completely unaware that their sweetheart is, in fact, a person with whom they share a degree of animosity. An adaptation of Parfumerie was previously made as The Shop Around the Corner, a 1940 film by Ernst Lubitsch and also a 1949 musical remake, In the Good Old Summertime by Robert Z. Leonard starring Judy Garland. You've Got Mail updates that concept with the use of e-mail. Influences from Jane Austen's Pride and Prejudice can also be seen in the relationship between Joe Fox and Kathleen Kelly ÔÇö a reference pointed out by these characters actually discussing Mr. Darcy and Miss Bennet in the film. Ephron stated that You've Got Mail was as much about the Upper West Side itself as the characters, highlighting the \"small town community\" feel that pervades the Upper West Side.","Photos":[{"id":"atte28f9aa6e2118a","url":"https://www.filepicker.io/api/file/YxAJhvLQxieJ65jaFNVS","filename":"220px-You've_Got_Mail.jpg","size":24847,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/VFxf2YHAToyWmp164zbz"},"large":{"url":"https://www.filepicker.io/api/file/xG4toiPRfOeDcQa6e3cB"}}}],"Actors":["recf38022b2f0db0d","rece0feb637db7618"],"Director":["rec738f48b44cc24c"],"Genre":["Romantic Comedy"]},"createdTime":"2014-07-18T04:52:02.000Z"},{"id":"rec6733da527dd0f1","fields":{"Name":"The Godfather","Description":"The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selling novel novel of the same name. The film stars Marlon Brando and Al Pacino as the leaders of a fictional New York crime family. The story, spanning the years 1945 to 1955, centers on the transformation of Michael Corleone from reluctant family outsider to ruthless Mafia boss while also chronicling the family under the patriarch Vito Corleone.","Photos":[{"id":"att6dba4af5786df1","url":"https://www.filepicker.io/api/file/akW7wUX7QM66a2hjxb9k","filename":"220px-TheGodfatherAlPacinoMarlonBrando.jpg","size":16420,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/XvbySDtbSxymbbUJzCoN"},"large":{"url":"https://www.filepicker.io/api/file/Fpc86btaS1Stl79SvHX4"}}},{"id":"attzWvarnmYBBd2Wm","url":"https://dl.airtable.com/jJqBm304SBWBrF3dXn12_Lighthouse.jpg","filename":"Lighthouse.jpg","size":561276,"type":"image/jpeg","thumbnails":{"small":{"url":"https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg","width":48,"height":36},"large":{"url":"https://dl.airtable.com/8QX7f3nSAe6lrOxeuvTP_large_Lighthouse.jpg","width":512,"height":512}}}],"Actors":["recc8841a14245b0b","rec514228ed76ced1"],"Director":["recfaf64fe0db19a9"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"rec6c1b6022782cd8","fields":{"Name":"Billy Madison","Description":"Billy Madison is a 1995 American comedy film directed by Tamra Davis. It stars Adam Sandler in the title role, along with Bradley Whitford, Bridgette Wilson, Norm Macdonald and Darren McGavin. The film was written by Sandler and Tim Herlihy, and produced by Robert Simonds. It made over $26.4 million worldwide and debuted at #1.[1] The film is about a slacker (Billy Madison) who must go back to school in order to take over his father's company. The comedy also features Chris Farley and Steve Buscemi with uncredited appearances. Sandler would later form a production company, Happy Madison Productions, named after a combination of this film's title character and Happy Gilmore's.","Photos":[{"id":"att2a05739d6534e4","url":"https://www.filepicker.io/api/file/fVo6zj3jSJ6Ws2cnT2I1","filename":"220px-Billy_madison_poster.jpg","size":24774,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/d9InPcLIRfaKlWZyr1ka"},"large":{"url":"https://www.filepicker.io/api/file/oC6mPKYuSHO3rIOaEzpo"}}}],"Actors":["rece266d5762b5240"],"Director":["rec4270d52105811e"],"Genre":["Romantic Comedy"]},"createdTime":"2014-07-18T04:54:18.000Z"},{"id":"rec6f45f58180d5c7","fields":{"Name":"Seven Samurai","Description":"Seven Samurai[1] (???? Shichinin no Samurai?) is a 1954 Japanese period adventure drama film co-written, edited, and directed by Akira Kurosawa. The film takes place in 1587 during the Warring States Period of Japan. It follows the story of a village of farmers that hire seven masterless samurai (ronin) to combat bandits who will return after the harvest to steal their crops.","Photos":[{"id":"attfb51ccc438566b","url":"https://www.filepicker.io/api/file/dwIdgUEQweSkN4KzLLWQ","filename":"Seven_Samurai_movie_poster.jpg","size":37313,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/hAByh5GPS5CshvPRvSGI"},"large":{"url":"https://www.filepicker.io/api/file/Pfw2GtXBQanfuaxLgEKW"}}}],"Actors":["rec256a53744da609"],"Director":["rec051acc552ecc58"],"Genre":["Adventure","Drama"]},"createdTime":"2014-07-18T04:57:03.000Z"},{"id":"recbe0b3c80a7f198","fields":{"Name":"Pulp Fiction","Description":"Pulp Fiction is a 1994 American black comedy crime film directed by Quentin Tarantino, who also co-wrote the screenplay with Roger Avary.[4] The film is known for its eclectic dialogue, ironic mix of humor and violence, nonlinear storyline, and a host of cinematic allusions and pop culture references. The film was nominated for seven Oscars, including Best Picture; Tarantino and Avary won for Best Original Screenplay. It was also awarded the Palme d'Or at the 1994 Cannes Film Festival. A major critical and commercial success, it revitalized the career of its leading man, John Travolta, who received an Academy Award nomination, as did costars Samuel L. Jackson and Uma Thurman.","Photos":[{"id":"att2ffd5c8228a3b4","url":"https://www.filepicker.io/api/file/zmp3hzNfSBeVQ0VVgeGo","filename":"215px-Pulp_Fiction_cover.jpg","size":25639,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/SQUt2mMNRECklIZGo1YQ"},"large":{"url":"https://www.filepicker.io/api/file/bLnd5eRDR0CCqHvwYrzd"}}}],"Actors":["recb59fc29ee5d646","rec6e2912ac04090c","recaad7f7c2fc0250"],"Director":["rec6caf9605f137c9"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"recedd526ce84cbd2","fields":{"Name":"Caddyshack","Description":"Caddyshack is a 1980 American sports comedy film directed by Harold Ramis and written by Brian Doyle-Murray, Ramis and Douglas Kenney. It stars Chevy Chase, Rodney Dangerfield, Ted Knight, and Bill Murray. Doyle-Murray also has a supporting role.","Photos":[{"id":"att995467ff4b5f04","url":"https://www.filepicker.io/api/file/SslWgZqRA2Slb1ehJJ2w","filename":"220px-Caddyshack_poster.jpg","size":30647,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/nLMlyHwdR3OhodMZDIJY"},"large":{"url":"https://www.filepicker.io/api/file/n3NMoBTETeWOFJWaMljD"}}}],"Actors":["rec9b8f53c739a551"],"Director":["rec05389cff1679e5"],"Genre":["Comedy"]},"createdTime":"2014-07-18T04:45:28.000Z"},{"id":"recee114d18a0a3c8","fields":{"Name":"Get Smart","Description":"Get Smart is an American comedy television series that satirizes the secret agent genre. Created by Mel Brooks with Buck Henry,[1] the show stars Don Adams (as Maxwell Smart, Agent 86), Barbara Feldon (as Agent 99), and Edward Platt (as Chief). Henry said they created the show by request of Daniel Melnick, who was a partner, along with Leonard Stern and David Susskind, of the show's production company, Talent Associates, to capitalize on \"the two biggest things in the entertainment world today\"ÔÇöJames Bond and Inspector Clouseau.[2] Brooks said: \"It's an insane combination of James Bond and Mel Brooks comedy.\"[3]","Photos":[{"id":"attaef7e86f0bd75e","url":"https://www.filepicker.io/api/file/Rta8Uy2xQ8mtl1oWl0YI","filename":"250px-Get_Smart.gif","size":30619,"type":"image/gif","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/vxz10zbjRlSRe0RmV00z"},"large":{"url":"https://www.filepicker.io/api/file/ZmFQD36wRTuVzzgZei89"}}}],"Actors":["rec77b0b4ba0b730e","rec43ef994a3465e5"],"Director":["rec2bb32ef25348fa"],"Genre":["Comedy"]},"createdTime":"2014-07-18T04:50:49.000Z"},{"id":"recfb77014d57c75b","fields":{"Name":"Fight Club","Description":"Fight Club is a 1999 film based on the 1996 novel of the same name by Chuck Palahniuk. The film was directed by David Fincher and stars Edward Norton, Brad Pitt, and Helena Bonham Carter. Norton plays the unnamed protagonist, an \"everyman\" who is discontented with his white-collar job. He forms a \"fight club\" with soap maker Tyler Durden, played by Pitt, and they are joined by men who also want to fight recreationally. The narrator becomes embroiled in a relationship with Durden and a dissolute woman, Marla Singer, played by Bonham Carter.","Photos":[{"id":"att69a5df8e344259","url":"https://www.filepicker.io/api/file/xyCDil2QVapaBg6IOmpY","filename":"220px-Fight_Club_poster.jpg","size":17360,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/qsJN64oeTiOErlaJuY0a"},"large":{"url":"https://www.filepicker.io/api/file/qP62vcLrSJivZlZ0Hm9x"}}}],"Actors":["rec3e27ca40e9cb7e"],"Director":["rec16a8af30615da0"],"Genre":["Drama"]},"createdTime":"2014-07-18T05:00:11.000Z"}]} \ No newline at end of file diff --git a/src/test/resources/__files/body-ParameterSelectSort.json b/src/test/resources/__files/body-ParameterSelectSort.json new file mode 100644 index 0000000..d538c5c --- /dev/null +++ b/src/test/resources/__files/body-ParameterSelectSort.json @@ -0,0 +1 @@ +{"records":[{"id":"rec3ce936056bbf7b","fields":{"Name":"You've got Mail","Description":"You've Got Mail is a 1998 American romantic comedy film directed by Nora Ephron, starring Tom Hanks and Meg Ryan. It was written by Nora and Delia Ephron based on the 1937[2] play Parfumerie by Mikl├│s L├íszl├│. The film is about two e-mailing lovers who are completely unaware that their sweetheart is, in fact, a person with whom they share a degree of animosity. An adaptation of Parfumerie was previously made as The Shop Around the Corner, a 1940 film by Ernst Lubitsch and also a 1949 musical remake, In the Good Old Summertime by Robert Z. Leonard starring Judy Garland. You've Got Mail updates that concept with the use of e-mail. Influences from Jane Austen's Pride and Prejudice can also be seen in the relationship between Joe Fox and Kathleen Kelly ÔÇö a reference pointed out by these characters actually discussing Mr. Darcy and Miss Bennet in the film. Ephron stated that You've Got Mail was as much about the Upper West Side itself as the characters, highlighting the \"small town community\" feel that pervades the Upper West Side.","Photos":[{"id":"atte28f9aa6e2118a","url":"https://www.filepicker.io/api/file/YxAJhvLQxieJ65jaFNVS","filename":"220px-You've_Got_Mail.jpg","size":24847,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/VFxf2YHAToyWmp164zbz"},"large":{"url":"https://www.filepicker.io/api/file/xG4toiPRfOeDcQa6e3cB"}}}],"Actors":["recf38022b2f0db0d","rece0feb637db7618"],"Director":["rec738f48b44cc24c"],"Genre":["Romantic Comedy"]},"createdTime":"2014-07-18T04:52:02.000Z"},{"id":"rec6733da527dd0f1","fields":{"Name":"The Godfather","Description":"The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selling novel novel of the same name. The film stars Marlon Brando and Al Pacino as the leaders of a fictional New York crime family. The story, spanning the years 1945 to 1955, centers on the transformation of Michael Corleone from reluctant family outsider to ruthless Mafia boss while also chronicling the family under the patriarch Vito Corleone.","Photos":[{"id":"att6dba4af5786df1","url":"https://www.filepicker.io/api/file/akW7wUX7QM66a2hjxb9k","filename":"220px-TheGodfatherAlPacinoMarlonBrando.jpg","size":16420,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/XvbySDtbSxymbbUJzCoN"},"large":{"url":"https://www.filepicker.io/api/file/Fpc86btaS1Stl79SvHX4"}}},{"id":"attzWvarnmYBBd2Wm","url":"https://dl.airtable.com/jJqBm304SBWBrF3dXn12_Lighthouse.jpg","filename":"Lighthouse.jpg","size":561276,"type":"image/jpeg","thumbnails":{"small":{"url":"https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg","width":48,"height":36},"large":{"url":"https://dl.airtable.com/8QX7f3nSAe6lrOxeuvTP_large_Lighthouse.jpg","width":512,"height":512}}}],"Actors":["recc8841a14245b0b","rec514228ed76ced1"],"Director":["recfaf64fe0db19a9"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"rec110972df115479","fields":{"Name":"Sister Act","Description":"Sister Act is a 1992 American comedy film released by Touchstone Pictures. Directed by Emile Ardolino, it features musical arrangements by Marc Shaiman and stars Whoopi Goldberg as a Reno lounge singer who has been put under protective custody in a San Francisco convent of Poor Clares and has to pretend to be a nun when a mob boss puts her on his hit list. Also in the cast are Maggie Smith, Kathy Najimy, Wendy Makkena, Mary Wickes, and Harvey Keitel.","Photos":[{"id":"att9141430d2b6dc1","url":"https://www.filepicker.io/api/file/tav0vGKoTjiyMcbjsx3r","filename":"Sister_Act_film_poster.jpg","size":19805,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/IiTD31iiQ32mRI6KYEzy"},"large":{"url":"https://www.filepicker.io/api/file/Oczxr4sYQ2lrA3ppGMhg"}}}],"Actors":["rec73fcac60a91bc1"],"Director":["rec114faab248e582"],"Genre":["Comedy"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"rec6f45f58180d5c7","fields":{"Name":"Seven Samurai","Description":"Seven Samurai[1] (???? Shichinin no Samurai?) is a 1954 Japanese period adventure drama film co-written, edited, and directed by Akira Kurosawa. The film takes place in 1587 during the Warring States Period of Japan. It follows the story of a village of farmers that hire seven masterless samurai (ronin) to combat bandits who will return after the harvest to steal their crops.","Photos":[{"id":"attfb51ccc438566b","url":"https://www.filepicker.io/api/file/dwIdgUEQweSkN4KzLLWQ","filename":"Seven_Samurai_movie_poster.jpg","size":37313,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/hAByh5GPS5CshvPRvSGI"},"large":{"url":"https://www.filepicker.io/api/file/Pfw2GtXBQanfuaxLgEKW"}}}],"Actors":["rec256a53744da609"],"Director":["rec051acc552ecc58"],"Genre":["Adventure","Drama"]},"createdTime":"2014-07-18T04:57:03.000Z"},{"id":"recbe0b3c80a7f198","fields":{"Name":"Pulp Fiction","Description":"Pulp Fiction is a 1994 American black comedy crime film directed by Quentin Tarantino, who also co-wrote the screenplay with Roger Avary.[4] The film is known for its eclectic dialogue, ironic mix of humor and violence, nonlinear storyline, and a host of cinematic allusions and pop culture references. The film was nominated for seven Oscars, including Best Picture; Tarantino and Avary won for Best Original Screenplay. It was also awarded the Palme d'Or at the 1994 Cannes Film Festival. A major critical and commercial success, it revitalized the career of its leading man, John Travolta, who received an Academy Award nomination, as did costars Samuel L. Jackson and Uma Thurman.","Photos":[{"id":"att2ffd5c8228a3b4","url":"https://www.filepicker.io/api/file/zmp3hzNfSBeVQ0VVgeGo","filename":"215px-Pulp_Fiction_cover.jpg","size":25639,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/SQUt2mMNRECklIZGo1YQ"},"large":{"url":"https://www.filepicker.io/api/file/bLnd5eRDR0CCqHvwYrzd"}}}],"Actors":["recb59fc29ee5d646","rec6e2912ac04090c","recaad7f7c2fc0250"],"Director":["rec6caf9605f137c9"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"recee114d18a0a3c8","fields":{"Name":"Get Smart","Description":"Get Smart is an American comedy television series that satirizes the secret agent genre. Created by Mel Brooks with Buck Henry,[1] the show stars Don Adams (as Maxwell Smart, Agent 86), Barbara Feldon (as Agent 99), and Edward Platt (as Chief). Henry said they created the show by request of Daniel Melnick, who was a partner, along with Leonard Stern and David Susskind, of the show's production company, Talent Associates, to capitalize on \"the two biggest things in the entertainment world today\"ÔÇöJames Bond and Inspector Clouseau.[2] Brooks said: \"It's an insane combination of James Bond and Mel Brooks comedy.\"[3]","Photos":[{"id":"attaef7e86f0bd75e","url":"https://www.filepicker.io/api/file/Rta8Uy2xQ8mtl1oWl0YI","filename":"250px-Get_Smart.gif","size":30619,"type":"image/gif","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/vxz10zbjRlSRe0RmV00z"},"large":{"url":"https://www.filepicker.io/api/file/ZmFQD36wRTuVzzgZei89"}}}],"Actors":["rec77b0b4ba0b730e","rec43ef994a3465e5"],"Director":["rec2bb32ef25348fa"],"Genre":["Comedy"]},"createdTime":"2014-07-18T04:50:49.000Z"},{"id":"rec2ed6bdd802c584","fields":{"Name":"Forrest Gump","Description":"Forrest Gump is a 1994 American epic romantic comedy-drama film based on the 1986 novel of the same name by Winston Groom. The film was directed by Robert Zemeckis and starred Tom Hanks, Robin Wright, Gary Sinise and Sally Field. The story depicts several decades in the life of Forrest Gump, a na├»ve and slow-witted yet athletically prodigious native of Alabama who witnesses, and in some cases influences, some of the defining events of the latter half of the 20th century in the United States; more specifically, the period between Forrest's birth in 1944 and 1982.","Photos":[{"id":"att82e0b9087885c0","url":"https://www.filepicker.io/api/file/zJDqSxaWS5SaHvOh1bZT","filename":"220px-Forrest_Gump_poster.jpg","size":16749,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/CrFAmlQGuPXUvYo4bEXQ"},"large":{"url":"https://www.filepicker.io/api/file/QfqP0RxhT16M1Ihnl8s0"}}}],"Actors":["recf38022b2f0db0d"],"Director":["rec09887e80a2692e"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:56:05.000Z"},{"id":"recfb77014d57c75b","fields":{"Name":"Fight Club","Description":"Fight Club is a 1999 film based on the 1996 novel of the same name by Chuck Palahniuk. The film was directed by David Fincher and stars Edward Norton, Brad Pitt, and Helena Bonham Carter. Norton plays the unnamed protagonist, an \"everyman\" who is discontented with his white-collar job. He forms a \"fight club\" with soap maker Tyler Durden, played by Pitt, and they are joined by men who also want to fight recreationally. The narrator becomes embroiled in a relationship with Durden and a dissolute woman, Marla Singer, played by Bonham Carter.","Photos":[{"id":"att69a5df8e344259","url":"https://www.filepicker.io/api/file/xyCDil2QVapaBg6IOmpY","filename":"220px-Fight_Club_poster.jpg","size":17360,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/qsJN64oeTiOErlaJuY0a"},"large":{"url":"https://www.filepicker.io/api/file/qP62vcLrSJivZlZ0Hm9x"}}}],"Actors":["rec3e27ca40e9cb7e"],"Director":["rec16a8af30615da0"],"Genre":["Drama"]},"createdTime":"2014-07-18T05:00:11.000Z"},{"id":"recedd526ce84cbd2","fields":{"Name":"Caddyshack","Description":"Caddyshack is a 1980 American sports comedy film directed by Harold Ramis and written by Brian Doyle-Murray, Ramis and Douglas Kenney. It stars Chevy Chase, Rodney Dangerfield, Ted Knight, and Bill Murray. Doyle-Murray also has a supporting role.","Photos":[{"id":"att995467ff4b5f04","url":"https://www.filepicker.io/api/file/SslWgZqRA2Slb1ehJJ2w","filename":"220px-Caddyshack_poster.jpg","size":30647,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/nLMlyHwdR3OhodMZDIJY"},"large":{"url":"https://www.filepicker.io/api/file/n3NMoBTETeWOFJWaMljD"}}}],"Actors":["rec9b8f53c739a551"],"Director":["rec05389cff1679e5"],"Genre":["Comedy"]},"createdTime":"2014-07-18T04:45:28.000Z"},{"id":"rec6c1b6022782cd8","fields":{"Name":"Billy Madison","Description":"Billy Madison is a 1995 American comedy film directed by Tamra Davis. It stars Adam Sandler in the title role, along with Bradley Whitford, Bridgette Wilson, Norm Macdonald and Darren McGavin. The film was written by Sandler and Tim Herlihy, and produced by Robert Simonds. It made over $26.4 million worldwide and debuted at #1.[1] The film is about a slacker (Billy Madison) who must go back to school in order to take over his father's company. The comedy also features Chris Farley and Steve Buscemi with uncredited appearances. Sandler would later form a production company, Happy Madison Productions, named after a combination of this film's title character and Happy Gilmore's.","Photos":[{"id":"att2a05739d6534e4","url":"https://www.filepicker.io/api/file/fVo6zj3jSJ6Ws2cnT2I1","filename":"220px-Billy_madison_poster.jpg","size":24774,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/d9InPcLIRfaKlWZyr1ka"},"large":{"url":"https://www.filepicker.io/api/file/oC6mPKYuSHO3rIOaEzpo"}}}],"Actors":["rece266d5762b5240"],"Director":["rec4270d52105811e"],"Genre":["Romantic Comedy"]},"createdTime":"2014-07-18T04:54:18.000Z"}]} \ No newline at end of file diff --git a/src/test/resources/__files/body-ParameterSelectView.json b/src/test/resources/__files/body-ParameterSelectView.json new file mode 100644 index 0000000..092bf36 --- /dev/null +++ b/src/test/resources/__files/body-ParameterSelectView.json @@ -0,0 +1 @@ +{"records":[{"id":"recfb77014d57c75b","fields":{"Name":"Fight Club","Description":"Fight Club is a 1999 film based on the 1996 novel of the same name by Chuck Palahniuk. The film was directed by David Fincher and stars Edward Norton, Brad Pitt, and Helena Bonham Carter. Norton plays the unnamed protagonist, an \"everyman\" who is discontented with his white-collar job. He forms a \"fight club\" with soap maker Tyler Durden, played by Pitt, and they are joined by men who also want to fight recreationally. The narrator becomes embroiled in a relationship with Durden and a dissolute woman, Marla Singer, played by Bonham Carter.","Photos":[{"id":"att69a5df8e344259","url":"https://www.filepicker.io/api/file/xyCDil2QVapaBg6IOmpY","filename":"220px-Fight_Club_poster.jpg","size":17360,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/qsJN64oeTiOErlaJuY0a"},"large":{"url":"https://www.filepicker.io/api/file/qP62vcLrSJivZlZ0Hm9x"}}}],"Actors":["rec3e27ca40e9cb7e"],"Director":["rec16a8af30615da0"],"Genre":["Drama"]},"createdTime":"2014-07-18T05:00:11.000Z"},{"id":"rec2ed6bdd802c584","fields":{"Name":"Forrest Gump","Description":"Forrest Gump is a 1994 American epic romantic comedy-drama film based on the 1986 novel of the same name by Winston Groom. The film was directed by Robert Zemeckis and starred Tom Hanks, Robin Wright, Gary Sinise and Sally Field. The story depicts several decades in the life of Forrest Gump, a na├»ve and slow-witted yet athletically prodigious native of Alabama who witnesses, and in some cases influences, some of the defining events of the latter half of the 20th century in the United States; more specifically, the period between Forrest's birth in 1944 and 1982.","Photos":[{"id":"att82e0b9087885c0","url":"https://www.filepicker.io/api/file/zJDqSxaWS5SaHvOh1bZT","filename":"220px-Forrest_Gump_poster.jpg","size":16749,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/CrFAmlQGuPXUvYo4bEXQ"},"large":{"url":"https://www.filepicker.io/api/file/QfqP0RxhT16M1Ihnl8s0"}}}],"Actors":["recf38022b2f0db0d"],"Director":["rec09887e80a2692e"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:56:05.000Z"},{"id":"recbe0b3c80a7f198","fields":{"Name":"Pulp Fiction","Description":"Pulp Fiction is a 1994 American black comedy crime film directed by Quentin Tarantino, who also co-wrote the screenplay with Roger Avary.[4] The film is known for its eclectic dialogue, ironic mix of humor and violence, nonlinear storyline, and a host of cinematic allusions and pop culture references. The film was nominated for seven Oscars, including Best Picture; Tarantino and Avary won for Best Original Screenplay. It was also awarded the Palme d'Or at the 1994 Cannes Film Festival. A major critical and commercial success, it revitalized the career of its leading man, John Travolta, who received an Academy Award nomination, as did costars Samuel L. Jackson and Uma Thurman.","Photos":[{"id":"att2ffd5c8228a3b4","url":"https://www.filepicker.io/api/file/zmp3hzNfSBeVQ0VVgeGo","filename":"215px-Pulp_Fiction_cover.jpg","size":25639,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/SQUt2mMNRECklIZGo1YQ"},"large":{"url":"https://www.filepicker.io/api/file/bLnd5eRDR0CCqHvwYrzd"}}}],"Actors":["recb59fc29ee5d646","rec6e2912ac04090c","recaad7f7c2fc0250"],"Director":["rec6caf9605f137c9"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:42:06.000Z"},{"id":"rec6f45f58180d5c7","fields":{"Name":"Seven Samurai","Description":"Seven Samurai[1] (???? Shichinin no Samurai?) is a 1954 Japanese period adventure drama film co-written, edited, and directed by Akira Kurosawa. The film takes place in 1587 during the Warring States Period of Japan. It follows the story of a village of farmers that hire seven masterless samurai (ronin) to combat bandits who will return after the harvest to steal their crops.","Photos":[{"id":"attfb51ccc438566b","url":"https://www.filepicker.io/api/file/dwIdgUEQweSkN4KzLLWQ","filename":"Seven_Samurai_movie_poster.jpg","size":37313,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/hAByh5GPS5CshvPRvSGI"},"large":{"url":"https://www.filepicker.io/api/file/Pfw2GtXBQanfuaxLgEKW"}}}],"Actors":["rec256a53744da609"],"Director":["rec051acc552ecc58"],"Genre":["Adventure","Drama"]},"createdTime":"2014-07-18T04:57:03.000Z"},{"id":"rec6733da527dd0f1","fields":{"Name":"The Godfather","Description":"The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selling novel novel of the same name. The film stars Marlon Brando and Al Pacino as the leaders of a fictional New York crime family. The story, spanning the years 1945 to 1955, centers on the transformation of Michael Corleone from reluctant family outsider to ruthless Mafia boss while also chronicling the family under the patriarch Vito Corleone.","Photos":[{"id":"att6dba4af5786df1","url":"https://www.filepicker.io/api/file/akW7wUX7QM66a2hjxb9k","filename":"220px-TheGodfatherAlPacinoMarlonBrando.jpg","size":16420,"type":"image/jpeg","thumbnails":{"small":{"url":"https://www.filepicker.io/api/file/XvbySDtbSxymbbUJzCoN"},"large":{"url":"https://www.filepicker.io/api/file/Fpc86btaS1Stl79SvHX4"}}},{"id":"attzWvarnmYBBd2Wm","url":"https://dl.airtable.com/jJqBm304SBWBrF3dXn12_Lighthouse.jpg","filename":"Lighthouse.jpg","size":561276,"type":"image/jpeg","thumbnails":{"small":{"url":"https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg","width":48,"height":36},"large":{"url":"https://dl.airtable.com/8QX7f3nSAe6lrOxeuvTP_large_Lighthouse.jpg","width":512,"height":512}}}],"Actors":["recc8841a14245b0b","rec514228ed76ced1"],"Director":["recfaf64fe0db19a9"],"Genre":["Drama"]},"createdTime":"2014-07-18T04:42:06.000Z"}]} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ParameterSelectFields.json b/src/test/resources/mappings/mapping-ParameterSelectFields.json new file mode 100644 index 0000000..df8c99e --- /dev/null +++ b/src/test/resources/mappings/mapping-ParameterSelectFields.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies?fields%5B%5D=Name", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ParameterSelectFields.json" + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ParameterSelectFormula.json b/src/test/resources/mappings/mapping-ParameterSelectFormula.json new file mode 100644 index 0000000..0bfa97d --- /dev/null +++ b/src/test/resources/mappings/mapping-ParameterSelectFormula.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies?filterByFormula=NOT%28%7BName%7D+%3D+%27%27%29", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ParameterSelectFormula.json" + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ParameterSelectMaxRecords.json b/src/test/resources/mappings/mapping-ParameterSelectMaxRecords.json new file mode 100644 index 0000000..9b72d97 --- /dev/null +++ b/src/test/resources/mappings/mapping-ParameterSelectMaxRecords.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies?pageSize=10", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ParameterSelectPageSize.json" + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ParameterSelectPageSize.json b/src/test/resources/mappings/mapping-ParameterSelectPageSize.json new file mode 100644 index 0000000..7378b93 --- /dev/null +++ b/src/test/resources/mappings/mapping-ParameterSelectPageSize.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies?paheSize=10", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ParameterSelectPageSize.json" + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ParameterSelectSort.json b/src/test/resources/mappings/mapping-ParameterSelectSort.json new file mode 100644 index 0000000..b54a2db --- /dev/null +++ b/src/test/resources/mappings/mapping-ParameterSelectSort.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies?sort%5B0%5D%5Bfield%5D=Name&sort%5B0%5D%5Bdirection%5D=desc", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ParameterSelectSort.json" + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-ParameterSelectView.json b/src/test/resources/mappings/mapping-ParameterSelectView.json new file mode 100644 index 0000000..969144e --- /dev/null +++ b/src/test/resources/mappings/mapping-ParameterSelectView.json @@ -0,0 +1,10 @@ +{ + "request" : { + "url" : "/v0/appe9941ff07fffcc/Movies?view=Dramas", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "/body-ParameterSelectView.json" + } +} \ No newline at end of file From eacb0e3ec8b7b6d9112074d85bce585010ac79fc Mon Sep 17 00:00:00 2001 From: fzr Date: Mon, 10 Apr 2017 10:13:47 +0200 Subject: [PATCH 53/74] Edited Readme --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 442b55e..718bff9 100644 --- a/README.md +++ b/README.md @@ -97,9 +97,23 @@ Select list of items from table: + `table(name).select()`: get all records of table `name` + `table(name).select(Integer maxRecords)`: get max `maxRecords` records of table `name` ++ `table(name).select(String[] fields)`: get records of table `name` with only the specified `fields` ++ `table(name).select(String view)`: get records of table `name` with the specified `view` (more about [views](https://support.airtable.com/hc/en-us/sections/200644955-Views)) ++ `table(name).select(Sort sortation)`: get records of table `name` using `sort` to sort records (More about Sort [here](#sort)) + `table(name).select(Query query)`: get records of table `name` using `query` to filter -+ `...` +### Sort +With the integrated Sort element you can retrieve a list of sort objects that specifies how the records will be ordered. +Each sort object must have a field key specifying the name of the field to sort on, and an optional direction key that is either "asc" or "desc". +The default direction is "asc". + +For example, to sort records by Name, pass in: + +```Java +Sort sort = new Sort("Name", Sort.Direction.desc); +List listMovies = movieTable.select(sort); +``` +If you set the view parameter, the returned records in that view will be sorted by these fields. ### Example ```Java From bb9f1ae3bf5a28893301ddbb781b8779939d6242 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 10 Apr 2017 10:37:38 +0200 Subject: [PATCH 54/74] updated readme --- README.md | 93 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 7b50dc1..13b5834 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Java API for Airtable (http://www.airtable.com). The Airtable API provides a simple way of accessing your data within your Java project. -More information about the Airtable API coud be found at [https://airtable.com/api](https://airtable.com/api). +More information about the Airtable API could be found at [https://airtable.com/api](https://airtable.com/api). The documentation will provide detailed information about your created base. # Usage @@ -74,7 +74,7 @@ need to wait 30 seconds before subsequent requests will succeed. ## Object Mapping The Java implementation of the Airtable API provides automatic Object mapping. You can map any Table to your own Java Classes. But first you need to specify those Classes. - + ### Create a Object The Java Objects represent records or 'values' in Airtable. So the Class attributes need to be adjusted to the Airtable Base. @@ -84,16 +84,15 @@ In Aritable we got a Table Actor. The coulumns represent the Class attributes. This is how our Actor Table looks like: -|Index| Name | Photo | Biography | Filmography | -|:---:|:-------------:|:------------:|:----------:|:-------------------------------:| -| 1 | Marlon Brando | Some Photos | Long Text | Reference to the Movie Table | -| 2 | Bill Murray | Some Photos | Long Text | Reference to the Movie Table | -| 3 | Al Pacino | Some Photos | Long Text | Reference to the Movie Table | -| ... | ... | ... | ... | ... | - +| Index | Name | Photo | Biography | Filmography | +| :---: | :-----------: | :---------: | :-------: | :--------------------------: | +| 1 | Marlon Brando | Some Photos | Long Text | Reference to the Movie Table | +| 2 | Bill Murray | Some Photos | Long Text | Reference to the Movie Table | +| 3 | Al Pacino | Some Photos | Long Text | Reference to the Movie Table | +| ... | ... | ... | ... | ... | + Now our Java Class should look like this: ```Java - public class Actor { private String id; @@ -126,56 +125,52 @@ Now our Java Class should look like this: return filmography; } - public void setFilmography(String[] Filmography) { - this.filmography = Filmography; + public void setFilmography(String[] filmography) { + this.filmography = filmography; } public List getPhoto() { return photo; } - public void setPhoto(List Photo) { - this.photo = Photo; + public void setPhoto(List photo) { + this.photo = photo; } public String getBiography() { return biography; } - public void setBiography(String Biography) { - this.biography = Biography; + public void setBiography(String biography) { + this.biography = biography; } - - } - ``` -For each column we give the Java Class an attribute with the column name (Be carefull! See more about naming in the Annotation Section) +For each column we give the Java class an attribute with the column name (Be careful! See more about naming in the [Section 'Annotations'](#Annotations)) and add Getters and Setters for each attribute. The attribute types can be either primitive Java types like `String` and `Float` for Text and Numbers, `String Array` for references on other Tables or `Attachment` for attached photos and files. Now we got everything we need to create our first Airtable Table Object. -We use the Java class we just wrote to specify what kind of Object should be saved in our Table. Then we tell our `base` Object which Table we want to access. +We use the Java class we just wrote to specify what kind of Object should be saved in our Table. Then we tell our `base`-Object which Table we want to access. All the Records saved in our Airtable DB now should be in our local Table Object. Example: ```Java - Base base = airtable.base(AIRTABLE_API_KEY); - Table actorTable = base.table(NAME OF THE TABLE, JAVA CLASS); + Base base = airtable.base('AIRTABLE_API_KEY'); + Table actorTable = base.table("NAME OF THE TABLE", ); //Example with the Actor Table Table actorTable = base.table("Actors", Actor.class); - ``` ### Basic Objects -The Java implementation of the Airtable API provides an implementation of Basic Airtable Objects such as Attachements and Thumbnails. -Photos and Attached Files in Airtable are retrieved as Attachements. Photos furthermore cointain Thumbnail Objects in different sizes. +The Java implementation of the Airtable-API provides an implementation of basic Airtable objects such as attachments and Thumbnails. +Photos and attached files in Airtable are retrieved as `Attachment`s. Photos furthermore contain `Thumbnail`-Objects for different sizes. -#### Attachement -All the Attachement Objects got the following attributes: +#### Attachment +All the `Attachment`-Objects got the following attributes: * String `id` * String `url` @@ -188,21 +183,21 @@ Photos additionally have: * Map `thumbnails` #### Thumbnails -A Thumbnail is generated for Photo Objects in Airtable. Thumbnails are bound to an Attachement Object as a key/value Map. -The Keys are `small` and `large` for the different sizes. The Value is a Thumbnail Object. +A Thumbnail is generated for image files in Airtable. Thumbnails are bound to an Attachment Object as a key/value Map. +The Keys are `small` and `large` for the different sizes. The Value is a `Thumbnail`-Object. -A Thumbnail got the following Attributes: +A `Thumbnail`-Object got the following Attributes: * String `name` * String `url` * Float `width` * Float `height` -Note: The `name` of a Thumbnail Object is identical with it´s key. +Note: The `name` of a Thumbnail Object is identical with it´s key ( `small` or `large` ). ### Annotations -Use the Gson Annotation `@SerializedName` to annotate Names which contain `-`, emtpy characters or other not mappable characters. +Use the Java Annotation `@SerializedName` of [Gson](https://github.com/google/gson) to annotate column names containing `-`, empty characters or other not in Java mappable characters. The airtable.java API will respect these mappings automatically. #### Example @@ -228,7 +223,7 @@ Select list of items from table: ### Example ```Java -Base base = new Airtable().base(AIRTABLE_BASE); +Base base = new Airtable().base("AIRTABLE_BASE"); List retval = base.table("Movies", Movie.class).select(); ``` @@ -241,7 +236,7 @@ Use `find` to get specific records of table: ### Example ```Java -Base base = new Airtable().base(AIRTABLE_BASE); +Base base = new Airtable().base("AIRTABLE_BASE"); Table actorTable = base.table("Actors", Actor.class); Actor actor = actorTable.find("rec514228ed76ced1"); ``` @@ -255,7 +250,7 @@ Use `destroy` to delete a specific records of table: ### Example ```Java -Base base = airtable.base(AIRTABLE_BASE); +Base base = airtable.base("AIRTABLE_BASE"); Table actorTable = base.table("Actors", Actor.class); actorTable.destroy("recapJ3Js8AEwt0Bf"); ``` @@ -291,9 +286,9 @@ Use `update` to update a record of table: ### Example ```Java // detailed Example see TableCreateTest.java -Base base = airtable.base("appe9941ff07fffcc"); - -Actor.setName("Neuer Name"); + +Actor marlonBrando = ...; +marlonBrando.setName("Marlon Brando"); Actor updated = actorTable.update(marlonBrando); ``` @@ -322,7 +317,7 @@ Short overview of features, which are supported: + [x] Read: convert to Objects + [x] Read: conversion of `Attachment`s & `Thumbnail`s + [x] Write: convert Objects to JSON - + [x] Errorhandling ++ [x] Errorhandling # Contribute @@ -345,14 +340,22 @@ We use [Gradle](https://gradle.org) to compile and package project: ## Testing There are JUnit tests to verify the API. -The tests are based on the Airtable template [Movies](https://airtable.com/templates/groups-clubs-and-hobbies/exprTnrH3YV8Vv9BI/favorite-movies -) which could be created in your account. -For testing, the JSON-responses are mocked via [WireMock](http://wiremock.org/). +The tests are based on the Airtable template [Movies](https://airtable.com/templates/groups-clubs-and-hobbies/exprTnrH3YV8Vv9BI/favorite-movies) which could be created in your account. +For testing, the JSON-responses are mocked by [WireMock](http://wiremock.org/). + +# Other Airtable Projects + +- [Airtable.js](https://github.com/Airtable/airtable.js): JavaScript Client +- [Airtable Ruby Client](https://github.com/Airtable/airtable-ruby): Ruzby Client +- [Airtable Phyton](https://github.com/nicocanali/airtable-python): Phyton Client +- [Airtabler](https://github.com/bergant/airtabler): R interface to the Airtable API + +More Github-Projects using topic *[Airtable](https://github.com/search?q=topic%3Aairtable&type=Repositories)* # Credits -Thank you very much for these gread frameworks and ibraries provided open source! - +Thank you very much for these great frameworks and libraries provided open source! + We use following libraries: + [unirest](http://unirest.io/java.html) From a26f38b6bbba5555087d7df7f471f620ce081ec5 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 10 Apr 2017 10:43:33 +0200 Subject: [PATCH 55/74] typo corrected --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13b5834..ac68db6 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ The Java Objects represent records or 'values' in Airtable. So the Class attribu #### Example -In Aritable we got a Table Actor. The coulumns represent the Class attributes. +In Aritable we got a Table Actor. The columns represent the Class attributes. This is how our Actor Table looks like: @@ -146,7 +146,7 @@ Now our Java Class should look like this: } } ``` -For each column we give the Java class an attribute with the column name (Be careful! See more about naming in the [Section 'Annotations'](#Annotations)) +For each column we give the Java class an attribute with the column name (Be careful! See more about naming in the [Section 'Annotations'](#annotations)) and add Getters and Setters for each attribute. The attribute types can be either primitive Java types like `String` and `Float` for Text and Numbers, `String Array` for references on other Tables or `Attachment` for attached photos and files. From 91683f04fdae526896daeb91d1169278f4983f5d Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 10 Apr 2017 11:24:29 +0200 Subject: [PATCH 56/74] updated gradle-file --- build.gradle | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 9b46837..f7aa4cd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,3 @@ -import com.smokejumperit.gradle.report.DependencyLicensePlugin - /* * The MIT License (MIT) * Copyright (c) 2017 Sybit GmbH @@ -24,7 +22,6 @@ apply plugin: 'maven' apply plugin: 'com.palantir.jacoco-coverage' apply plugin: 'maven-publish' apply plugin: 'com.jfrog.bintray' -apply plugin: DependencyLicensePlugin group = 'com.sybit' version = '0.1' @@ -84,17 +81,22 @@ def getVersionName = { -> } } -// custom tasks for creating source/javadoc jars +// custom tasks for creating source jar task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' from sourceSets.main.allSource } - +// custom tasks for creating javadoc jar task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir } +// add javadoc/source jar tasks as artifacts +artifacts { + archives sourcesJar, javadocJar +} + task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) { main = "com.codacy.CodacyCoverageReporter" classpath = configurations.codacy @@ -106,10 +108,6 @@ task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) { ] } -// add javadoc/source jar tasks as artifacts -artifacts { - archives sourcesJar, javadocJar -} publishing { publications { From 385b1dc38efe36a77a6530e9e7ee1dde50d93b69 Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 10 Apr 2017 11:52:59 +0200 Subject: [PATCH 57/74] bintrayupload --- .travis.yml | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c2602b..f38565d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,34 +1,27 @@ language: java jdk: - - oraclejdk8 - +- oraclejdk8 before_install: - - chmod +x ./gradlew - +- chmod +x ./gradlew script: - - ./gradlew check sendCoverageToCodacy - +- "./gradlew check sendCoverageToCodacy" deploy: - - provider: script - skip_cleanup: true - script: gradlew install bintrayUpload - on: - tags: true - - - provider: releases - api_key: - secure: ltLzm1VWcBj5sLTqtEUQyd3JG5pYZ6nQG5czsWB28hvJ3wkVa6vt7L5j3OS8wZuaIdE6eDJ2rMfQ5qS1FAE91SiQfCsMArsZ5C2cWm7BSz70MAa2zCWgxxlMsvARTnSLaP9mVgbZN0js2p0ETVVuUj+MG1dQJGXhsggmFI3ZSxCnWpoAhtGDVvQr8BZp4w5hPJ0Xm144v9ZnT2oUwmwevlVFzO+QzjiUJwPCjy4y6rJAJDdYdY0mTUQq7Y9SwkjXQACNwDRs6ITQ4nbClCk7RtDIKUFYWvuq9IRD0OhVXibTtMC4yocl+PsM6XvCYCAWPjLon20Pc2fdepzWhYPkyoOf9SDDUFAHEjYQ+vw2BkQpx3WwMZDLJbGXI1z0+evYUhSxr7oRSzoRfpCYFtEJ7toLb8SPTsYkyQQp5N1EDNtnIgBZhsQpFdxDgZ8vrVeWiLVtzX5ARgz0GV/yL2v+2ZzPg7usEJSNC6xwyjGiPGDtggUy2HIsP1ohl56VVvU5RjfoKcXxysbm0L43sddZHIuNggyku7pNlYsgHdrUf/0qanxxrU46w8M4vUdyd1oC/pXwaUkpdjA6nFU+ouoX1ScihxZzlkE2TYEFJqbKcWQ8d9zeYW90pemc8oWZJcylyF0ef2MJKy3DgNplnoSJM6q6sDunAA5wGN5A+vu/Ahw= - skip_cleanup: true - file_glob: true - file: ./build/libs/* - on: - repo: Sybit-Education/airtable.java - tags: true - - +- provider: releases + api_key: + secure: ltLzm1VWcBj5sLTqtEUQyd3JG5pYZ6nQG5czsWB28hvJ3wkVa6vt7L5j3OS8wZuaIdE6eDJ2rMfQ5qS1FAE91SiQfCsMArsZ5C2cWm7BSz70MAa2zCWgxxlMsvARTnSLaP9mVgbZN0js2p0ETVVuUj+MG1dQJGXhsggmFI3ZSxCnWpoAhtGDVvQr8BZp4w5hPJ0Xm144v9ZnT2oUwmwevlVFzO+QzjiUJwPCjy4y6rJAJDdYdY0mTUQq7Y9SwkjXQACNwDRs6ITQ4nbClCk7RtDIKUFYWvuq9IRD0OhVXibTtMC4yocl+PsM6XvCYCAWPjLon20Pc2fdepzWhYPkyoOf9SDDUFAHEjYQ+vw2BkQpx3WwMZDLJbGXI1z0+evYUhSxr7oRSzoRfpCYFtEJ7toLb8SPTsYkyQQp5N1EDNtnIgBZhsQpFdxDgZ8vrVeWiLVtzX5ARgz0GV/yL2v+2ZzPg7usEJSNC6xwyjGiPGDtggUy2HIsP1ohl56VVvU5RjfoKcXxysbm0L43sddZHIuNggyku7pNlYsgHdrUf/0qanxxrU46w8M4vUdyd1oC/pXwaUkpdjA6nFU+ouoX1ScihxZzlkE2TYEFJqbKcWQ8d9zeYW90pemc8oWZJcylyF0ef2MJKy3DgNplnoSJM6q6sDunAA5wGN5A+vu/Ahw= + skip_cleanup: true + file_glob: true + file: "./build/libs/*" + on: + repo: Sybit-Education/airtable.java + tags: true +- provider: script + skip_cleanup: true + script: gradlew install bintrayUpload + on: + repo: Sybit-Education/airtable.java + tags: true before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - +- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock cache: - directories: - — $HOME/.gradle \ No newline at end of file + directories: "— $HOME/.gradle" From 56dea95fba90c1d074d533662ce38ba7e5c8bc0d Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 10 Apr 2017 12:06:32 +0200 Subject: [PATCH 58/74] corrected bintray-task --- build.gradle | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index 9b46837..d2e2221 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,21 @@ import com.smokejumperit.gradle.report.DependencyLicensePlugin +/* + * Gets the version name from the latest Git tag + */ +def getVersionName = { -> + try { + def stdout = new ByteArrayOutputStream() + exec { + commandLine 'git', 'describe', '--tags' + standardOutput = stdout + } + return stdout.toString().trim() + } + catch (ignored) { + return version; + } +} /* * The MIT License (MIT) * Copyright (c) 2017 Sybit GmbH @@ -27,7 +43,7 @@ apply plugin: 'com.jfrog.bintray' apply plugin: DependencyLicensePlugin group = 'com.sybit' -version = '0.1' +version = getVersionName() description = """com.sybit airtable""" @@ -67,23 +83,6 @@ dependencies { } -/* - * Gets the version name from the latest Git tag - */ -def getVersionName = { -> - try { - def stdout = new ByteArrayOutputStream() - exec { - commandLine 'git', 'describe', '--tags' - standardOutput = stdout - } - return stdout.toString().trim() - } - catch (ignored) { - return version; - } -} - // custom tasks for creating source/javadoc jars task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' @@ -130,17 +129,21 @@ bintray { user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') - publications = ['mavenJava'] + //publications = ['mavenJava'] + configurations = ['archives'] dryRun = false //Whether to run this as dry-run, without deploying publish = true //If version should be auto published after an upload - version getVersionName() + pkg { repo = 'maven' userOrg = 'sybit-education' name = 'airtable.java' licenses = ['MIT License'] vcsUrl = 'https://github.com/Sybit-Education/airtable.java.git' - + version { + name = getVersionName() + released = new Date() + } } } \ No newline at end of file From 56ab51da83348bff27c0d71533aa3d920814304b Mon Sep 17 00:00:00 2001 From: stritti Date: Mon, 10 Apr 2017 12:10:29 +0200 Subject: [PATCH 59/74] one more try --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f38565d..55af54f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ deploy: tags: true - provider: script skip_cleanup: true - script: gradlew install bintrayUpload + script: "./gradlew install bintrayUpload" on: repo: Sybit-Education/airtable.java tags: true From d9d7f439dc715ea9152fcecb8cb5806ce90bfeb9 Mon Sep 17 00:00:00 2001 From: fzr Date: Mon, 10 Apr 2017 14:11:44 +0200 Subject: [PATCH 60/74] Edited Readme --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d7c17f7..f99c432 100644 --- a/README.md +++ b/README.md @@ -67,9 +67,14 @@ logging framework at deployment time. The API of Airtable itself is limited to 5 requests per second. If you exceed this rate, you will receive a 429 status code and will need to wait 30 seconds before subsequent requests will succeed. -*TODO:* -* How to create an Airtable Object -* How to create an Airtable Base +### Connecting to Airtable +To use this Libraray you will need a Airtable Object. Simply create one! `Airtable airtable = new Airtable();`. +This Object needs an API-Key or it won't work properly so `airtable.configure(AIRTABLE_API_KEY);`. +Now the Airtable Object needs to know on which base you want access. This Method will return a Base Object which will be used in the Future. +`Base base = airtable.base(AIRTABLE_BASE);` + +With the Base object you can perform all kind of Operations see more [here](#crud-operations-on-table-records). + ## Object Mapping The Java implementation of the Airtable API provides automatic Object mapping. You can map any Table to your own Java Classes. @@ -146,7 +151,7 @@ Now our Java Class should look like this: } } ``` -For each column we give the Java class an attribute with the column name (Be careful! See more about naming in the [Section 'Annotations'](#annotations)) +For each column we give the Java class an attribute with the column name (Be careful! See more about naming in the Section [Annotations](#annotations)) and add Getters and Setters for each attribute. The attribute types can be either primitive Java types like `String` and `Float` for Text and Numbers, `String Array` for references on other Tables or `Attachment` for attached photos and files. @@ -318,8 +323,8 @@ Short overview of features, which are supported: + [x] Select Records + [x] SelectAll + [x] Queries (`maxRecords`, `sort` & `view` ) - + [ ] Support of `filterByFormula` - + [ ] Support of Paging + + [x] Support of `filterByFormula` + + [x] Support of Paging + [x] Find Record From 63fcf60d0515882ea2f4e8417da396a9ac09ca2d Mon Sep 17 00:00:00 2001 From: fzr Date: Mon, 10 Apr 2017 15:10:03 +0200 Subject: [PATCH 61/74] Edited Readme --- README.md | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index f99c432..9bada87 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,21 @@ The airtable.java API will respect these mappings automatically. @SerializedName("First- & Lastname") private String name; ``` +### Sort +With the integrated Sort element you can retrieve a list of sort objects that specifies how the records will be ordered. +Each sort object must have a field key specifying the name of the field to sort on, and an optional direction key that is either "asc" or "desc". +The default direction is "asc". + +For example, to sort records by Name, pass in: + +```Java +Sort sort = new Sort("Name", Sort.Direction.desc); +List listMovies = movieTable.select(sort); +``` +If you set the view parameter, the returned records in that view will be sorted by these fields. + +Detailed Example see [TableParameterTest](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableParameterTest.java) + ## CRUD-Operations on Table Records @@ -227,18 +242,6 @@ Select list of items from table: + `table(name).select(Sort sortation)`: get records of table `name` using `sort` to sort records (More about Sort [here](#sort)) + `table(name).select(Query query)`: get records of table `name` using `query` to filter -### Sort -With the integrated Sort element you can retrieve a list of sort objects that specifies how the records will be ordered. -Each sort object must have a field key specifying the name of the field to sort on, and an optional direction key that is either "asc" or "desc". -The default direction is "asc". - -For example, to sort records by Name, pass in: - -```Java -Sort sort = new Sort("Name", Sort.Direction.desc); -List listMovies = movieTable.select(sort); -``` -If you set the view parameter, the returned records in that view will be sorted by these fields. ### Example ```Java @@ -295,6 +298,8 @@ newActor.setName("Neuer Actor"); Actor test = actorTable.create(newActor); ``` +Detailed example see [TableDestroyTest.java](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableCreateRecordTest.java) + ## Update Use `update` to update a record of table: @@ -311,6 +316,8 @@ marlonBrando.setName("Marlon Brando"); Actor updated = actorTable.update(marlonBrando); ``` +Detailed example see [TableUpdateTest](https://github.com/Sybit-Education/airtable.java/blob/develop/src/test/java/com/sybit/airtable/TableUpdateTest.java) + # Roadmap Short overview of features, which are supported: From 328dcbc5586d535c734c320cb16727547c2a9a41 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 11 Apr 2017 12:05:04 +0200 Subject: [PATCH 62/74] Class Table is now public --- src/main/java/com/sybit/airtable/Table.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index b888cbd..5f9626b 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -38,7 +38,7 @@ * * @since 0.1 */ -class Table { +public class Table { private static final Logger LOG = LoggerFactory.getLogger( Table.class ); From d2eaff1a12f4f49db7da25241b8f70b4ce08fd5c Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 11 Apr 2017 12:54:55 +0200 Subject: [PATCH 63/74] Deleted Property file --- src/main/resources/credentials.properties | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/main/resources/credentials.properties diff --git a/src/main/resources/credentials.properties b/src/main/resources/credentials.properties deleted file mode 100644 index f0e2759..0000000 --- a/src/main/resources/credentials.properties +++ /dev/null @@ -1,5 +0,0 @@ -# To change this license header, choose License Headers in Project Properties. -# To change this template file, choose Tools | Templates -# and open the template in the editor. -AIRTABLE_API_KEY=keyrguODZpsZdrPRd - From 042e84682ee4a59f5c209f7d50d03f803109cb9d Mon Sep 17 00:00:00 2001 From: stritti Date: Tue, 11 Apr 2017 13:42:23 +0200 Subject: [PATCH 64/74] reordered --- build.gradle | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/build.gradle b/build.gradle index d9976ff..4dff004 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,10 @@ +/* + * The MIT License (MIT) + * Copyright (c) 2017 Sybit GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + */ + /* * Gets the version name from the latest Git tag */ @@ -14,12 +21,6 @@ def getVersionName = { -> return version; } } -/* - * The MIT License (MIT) - * Copyright (c) 2017 Sybit GmbH - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - */ buildscript { repositories { @@ -79,23 +80,6 @@ dependencies { codacy group: 'com.codacy', name: 'codacy-coverage-reporter', version: '1.0.13' } -/* - * Gets the version name from the latest Git tag - */ -def getVersionName = { -> - try { - def stdout = new ByteArrayOutputStream() - exec { - commandLine 'git', 'describe', '--tags' - standardOutput = stdout - } - return stdout.toString().trim() - } - catch (ignored) { - return version; - } -} - // custom tasks for creating source jar task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' @@ -160,4 +144,4 @@ bintray { released = new Date() } } -} \ No newline at end of file +} From 69ee23dabad136b8c95c9f8ea39d10db7f961b54 Mon Sep 17 00:00:00 2001 From: fzr Date: Tue, 11 Apr 2017 13:45:27 +0200 Subject: [PATCH 65/74] edited Javadoc --- src/main/java/com/sybit/airtable/Table.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/sybit/airtable/Table.java b/src/main/java/com/sybit/airtable/Table.java index 5f9626b..0df2acb 100644 --- a/src/main/java/com/sybit/airtable/Table.java +++ b/src/main/java/com/sybit/airtable/Table.java @@ -125,7 +125,6 @@ public Integer getPageSize() { * @param query * @return * @throws AirtableException - * @throws HttpResponseException */ @SuppressWarnings("WeakerAccess") public List select(Query query) throws AirtableException { From 17fdd07415e7aa7fb76b968c088985ffb7613812 Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 12 Apr 2017 08:36:59 +0200 Subject: [PATCH 66/74] verbose logging for bintray --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 55af54f..206cf7c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,8 @@ deploy: repo: Sybit-Education/airtable.java tags: true - provider: script - skip_cleanup: true - script: "./gradlew install bintrayUpload" + skip_cleanup: false + script: "./gradlew -i bintrayUpload" on: repo: Sybit-Education/airtable.java tags: true From 01aa397447c1d9faafd6a2fb50f343c78dd8441d Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 12 Apr 2017 08:47:13 +0200 Subject: [PATCH 67/74] bintray publish --- .travis.yml | 2 +- build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 206cf7c..258aca6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ deploy: repo: Sybit-Education/airtable.java tags: true - provider: script - skip_cleanup: false + skip_cleanup: true script: "./gradlew -i bintrayUpload" on: repo: Sybit-Education/airtable.java diff --git a/build.gradle b/build.gradle index 4dff004..932a0bd 100644 --- a/build.gradle +++ b/build.gradle @@ -127,8 +127,8 @@ bintray { user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') - //publications = ['mavenJava'] - configurations = ['archives'] + publications = ['mavenJava'] + //configurations = ['archives'] dryRun = false //Whether to run this as dry-run, without deploying publish = true //If version should be auto published after an upload From 4d042fdb3a8ffe89d0dac3b36732771fc0c28cfd Mon Sep 17 00:00:00 2001 From: stritti Date: Wed, 12 Apr 2017 10:42:15 +0200 Subject: [PATCH 68/74] one more try --- build.gradle | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 932a0bd..9f31086 100644 --- a/build.gradle +++ b/build.gradle @@ -27,18 +27,23 @@ buildscript { jcenter() } - dependencies { - classpath 'com.palantir:jacoco-coverage:0.4.0' - classpath "com.smokejumperit.gradle.license:Gradle-License-Report:0.0.2" - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' - } + dependencies { + classpath 'com.palantir:jacoco-coverage:0.4.0' + classpath "com.smokejumperit.gradle.license:Gradle-License-Report:0.0.2" + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + } } -apply plugin: 'java' -apply plugin: 'maven' -apply plugin: 'com.palantir.jacoco-coverage' -apply plugin: 'maven-publish' -apply plugin: 'com.jfrog.bintray' +allprojects { + repositories { + jcenter() + } + apply plugin: 'java' + apply plugin: 'maven' + apply plugin: 'maven-publish' + apply plugin: 'com.palantir.jacoco-coverage' + apply plugin: 'com.jfrog.bintray' +} group = 'com.sybit' version = getVersionName() @@ -110,12 +115,15 @@ task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) { publishing { publications { - mavenJava(MavenPublication) { + MyPublication(MavenPublication) { if (plugins.hasPlugin('war')) { from components.web } else { from components.java } + groupId group + artifactId rootProject.name + version getVersionName() artifact sourcesJar artifact javadocJar @@ -127,7 +135,7 @@ bintray { user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') - publications = ['mavenJava'] + publications = ['MyPublication'] //configurations = ['archives'] dryRun = false //Whether to run this as dry-run, without deploying From cb07eac97e760d96dfb7cf1d0563a2695f1c3e2b Mon Sep 17 00:00:00 2001 From: stritti Date: Thu, 13 Apr 2017 09:53:16 +0200 Subject: [PATCH 69/74] Change scope of required libraries to "compile" --- build.gradle | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build.gradle b/build.gradle index 9f31086..9529641 100644 --- a/build.gradle +++ b/build.gradle @@ -131,6 +131,17 @@ publishing { } } +//we have to change scope from runtime to compile. especially for Gson-lib. +publishing.publications.all { + pom.withXml { + asNode().dependencies.'*'.findAll() { + it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> + dep.name == it.artifactId.text() + } + }.each { it.scope*.value = 'compile'} + } +} + bintray { user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') From 7d092138e0052c5cae0cfa379634960319b9c241 Mon Sep 17 00:00:00 2001 From: stritti Date: Thu, 13 Apr 2017 14:57:57 +0200 Subject: [PATCH 70/74] change scope of dependend libs to compile --- build.gradle | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index 9529641..f6d4fe0 100644 --- a/build.gradle +++ b/build.gradle @@ -128,39 +128,39 @@ publishing { artifact sourcesJar artifact javadocJar } - } -} -//we have to change scope from runtime to compile. especially for Gson-lib. -publishing.publications.all { - pom.withXml { - asNode().dependencies.'*'.findAll() { - it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> - dep.name == it.artifactId.text() + all { + //we have to change scope from runtime to compile. especially for Gson-lib. + pom.withXml { + asNode().dependencies.'*'.findAll() { + it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> + dep.name == it.artifactId.text() + } + }.each { it.scope*.value = 'compile' } } - }.each { it.scope*.value = 'compile'} + } } -} -bintray { - user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') - key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') - - publications = ['MyPublication'] - //configurations = ['archives'] - - dryRun = false //Whether to run this as dry-run, without deploying - publish = true //If version should be auto published after an upload - - pkg { - repo = 'maven' - userOrg = 'sybit-education' - name = 'airtable.java' - licenses = ['MIT License'] - vcsUrl = 'https://github.com/Sybit-Education/airtable.java.git' - version { - name = getVersionName() - released = new Date() + bintray { + user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') + key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') + + publications = ['MyPublication'] + //configurations = ['archives'] + + dryRun = false //Whether to run this as dry-run, without deploying + publish = true //If version should be auto published after an upload + + pkg { + repo = 'maven' + userOrg = 'sybit-education' + name = 'airtable.java' + licenses = ['MIT License'] + vcsUrl = 'https://github.com/Sybit-Education/airtable.java.git' + version { + name = getVersionName() + released = new Date() + } } } -} +} \ No newline at end of file From 941e2ac7c9f34987fb4412b24063f587e33acdf5 Mon Sep 17 00:00:00 2001 From: stritti Date: Thu, 13 Apr 2017 15:37:05 +0200 Subject: [PATCH 71/74] improved script --- build.gradle | 61 ++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index f6d4fe0..9bd88ee 100644 --- a/build.gradle +++ b/build.gradle @@ -101,6 +101,7 @@ artifacts { archives sourcesJar, javadocJar } +//task to send coverage data to Codacy task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) { main = "com.codacy.CodacyCoverageReporter" classpath = configurations.codacy @@ -115,7 +116,17 @@ task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) { publishing { publications { + MyPublication(MavenPublication) { + //we have to change scope from runtime to compile. Especially for Gson-lib. + pom.withXml { + asNode().dependencies.'*'.findAll() { + it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> + dep.name == it.artifactId.text() + } + }.each { it.scope*.value = 'compile' } + } + if (plugins.hasPlugin('war')) { from components.web } else { @@ -129,38 +140,28 @@ publishing { artifact javadocJar } - all { - //we have to change scope from runtime to compile. especially for Gson-lib. - pom.withXml { - asNode().dependencies.'*'.findAll() { - it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> - dep.name == it.artifactId.text() - } - }.each { it.scope*.value = 'compile' } - } - } } +} - bintray { - user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') - key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') - - publications = ['MyPublication'] - //configurations = ['archives'] - - dryRun = false //Whether to run this as dry-run, without deploying - publish = true //If version should be auto published after an upload - - pkg { - repo = 'maven' - userOrg = 'sybit-education' - name = 'airtable.java' - licenses = ['MIT License'] - vcsUrl = 'https://github.com/Sybit-Education/airtable.java.git' - version { - name = getVersionName() - released = new Date() - } +bintray { + user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') + key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') + + publications = ['MyPublication'] + //configurations = ['archives'] + + dryRun = false //Whether to run this as dry-run, without deploying + publish = true //If version should be auto published after an upload + + pkg { + repo = 'maven' + userOrg = 'sybit-education' + name = 'airtable.java' + licenses = ['MIT License'] + vcsUrl = 'https://github.com/Sybit-Education/airtable.java.git' + version { + name = getVersionName() + released = new Date() } } } \ No newline at end of file From c0290594ce632ad823c93297c338bb709e7b6487 Mon Sep 17 00:00:00 2001 From: kobisuissa Date: Tue, 18 Apr 2017 17:04:09 +0200 Subject: [PATCH 72/74] allow injection of custom object mapper --- .../java/com/sybit/airtable/Airtable.java | 51 +++++-- .../airtable/TableSelectJacksonOMTest.java | 138 ++++++++++++++++++ 2 files changed, 177 insertions(+), 12 deletions(-) create mode 100644 src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index 46682d6..777de94 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -7,6 +7,7 @@ package com.sybit.airtable; +import com.mashape.unirest.http.ObjectMapper; import com.mashape.unirest.http.Unirest; import com.sybit.airtable.converter.ListConverter; import com.sybit.airtable.converter.MapConverter; @@ -54,11 +55,24 @@ public class Airtable { * Configure, AIRTABLE_API_KEY passed by Java property, enviroment variable * or within credentials.properties. * - * @return configured Airtable object. + * @return An Airtable instance configured with GsonObjectMapper * @throws com.sybit.airtable.exception.AirtableException Missing API-Key */ @SuppressWarnings("UnusedReturnValue") public Airtable configure() throws AirtableException { + return this.configure(new GsonObjectMapper()); + } + + /** + * Configure, AIRTABLE_API_KEY passed by Java property, enviroment variable + * or within credentials.properties. + * + * @param objectMapper A custom ObjectMapper implementation + * @return An Airtable instance configured with supplied ObjectMapper + * @throws com.sybit.airtable.exception.AirtableException Missing API-Key + */ + @SuppressWarnings("UnusedReturnValue") + public Airtable configure(ObjectMapper objectMapper) throws AirtableException { LOG.info( "System-Property: Using Java property '-D" + AIRTABLE_API_KEY + "' to get apikey."); String airtableApi = System.getProperty(AIRTABLE_API_KEY); @@ -71,7 +85,7 @@ public Airtable configure() throws AirtableException { airtableApi = getCredentialProperty(AIRTABLE_API_KEY); } - return this.configure(airtableApi); + return this.configure(airtableApi, objectMapper); } @@ -80,12 +94,25 @@ public Airtable configure() throws AirtableException { * Configure Airtable. * * @param apiKey API-Key of Airtable. - * @return + * @return An Airtable instance configured with GsonObjectMapper * @throws com.sybit.airtable.exception.AirtableException Missing API-Key */ @SuppressWarnings("WeakerAccess") public Airtable configure(String apiKey) throws AirtableException { - return configure(new Configuration(apiKey, Configuration.ENDPOINT_URL)); + return configure(apiKey, new GsonObjectMapper()); + } + + /** + * Configure Airtable. + * + * @param apiKey API-Key of Airtable. + * @param objectMapper A custom ObjectMapper implementation + * @return + * @throws com.sybit.airtable.exception.AirtableException Missing API-Key + */ + @SuppressWarnings("WeakerAccess") + public Airtable configure(String apiKey, ObjectMapper objectMapper) throws AirtableException { + return configure(new Configuration(apiKey, Configuration.ENDPOINT_URL), objectMapper); } /** @@ -95,7 +122,7 @@ public Airtable configure(String apiKey) throws AirtableException { * @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint */ @SuppressWarnings("WeakerAccess") - public Airtable configure(Configuration config) throws AirtableException { + public Airtable configure(Configuration config, ObjectMapper objectMapper) throws AirtableException { if(config.getApiKey() == null) { throw new AirtableException("Missing Airtable API-Key"); } @@ -113,22 +140,22 @@ public Airtable configure(Configuration config) throws AirtableException { setProxy(config.getEndpointUrl()); // Only one time - Unirest.setObjectMapper(new GsonObjectMapper()); + Unirest.setObjectMapper(objectMapper); + - // Add specific Converter for Date DateTimeConverter dtConverter = new DateConverter(); ListConverter lConverter = new ListConverter(); MapConverter thConverter = new MapConverter(); - + lConverter.setListClass(Attachment.class); thConverter.setMapClass(Thumbnail.class); dtConverter.setPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - + ConvertUtils.register(dtConverter, Date.class); ConvertUtils.register(lConverter, List.class); ConvertUtils.register(thConverter, Map.class); - + return this; } @@ -142,8 +169,8 @@ public Airtable configure(Configuration config) throws AirtableException { private void setProxy(String endpointUrl) { final String httpProxy = System.getenv("http_proxy"); if(httpProxy != null - && (endpointUrl.contains("127.0.0.1") - || endpointUrl.contains("localhost"))) { + && (endpointUrl.contains("127.0.0.1") + || endpointUrl.contains("localhost"))) { LOG.info("Use Proxy: ignored for 'localhost' ann '127.0.0.1'"); Unirest.setProxy(null); } else if(httpProxy != null) { diff --git a/src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java b/src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java new file mode 100644 index 0000000..3d01f33 --- /dev/null +++ b/src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java @@ -0,0 +1,138 @@ +package com.sybit.airtable; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.mashape.unirest.http.ObjectMapper; +import com.sybit.airtable.exception.AirtableException; +import com.sybit.airtable.movies.ActorSerializedNames; +import com.sybit.airtable.movies.Movie; +import com.sybit.airtable.test.WireMockBaseTest; +import org.apache.http.client.HttpResponseException; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.List; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.any; +import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Created by kobisuissa on 18/04/17. + */ +public class TableSelectJacksonOMTest extends WireMockBaseTest { + + @Before + public void setup() throws AirtableException { + airtable.configure(new ObjectMapper() { + + final com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper(); + + @Override + public T readValue(final String value, final Class valueType) { + try { + return objectMapper.readValue(value, valueType); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String writeValue(final Object value) { + try { + return objectMapper.writeValueAsString(value); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + }); + airtable.setEndpointUrl("http://localhost:8080/v0"); + + //set 404 as default + stubFor(any(anyUrl()) + .atPriority(10) + .willReturn(aResponse() + .withStatus(404) + .withBody("{\"error\":{\"type\":\"NOT_FOUND\",\"message\":\"Not found\"}}"))); + + } + + @Test + public void testSelectTable() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + List retval = base.table("Movies", Movie.class).select(); + assertNotNull(retval); + assertEquals(10, retval.size()); + Movie mov = retval.get(0); + assertEquals("Sister Act", mov.getName()); + } + + @Test + public void testSelectTableMaxRecords() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + List retval = base.table("Movies", Movie.class).select(2); + assertNotNull(retval); + assertEquals(2, retval.size()); + Movie mov = retval.get(0); + assertEquals("Sister Act", mov.getName()); + } + + @Test + public void testSelectTableSorted() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + Table table = base.table("Movies", Movie.class); + + List retval = table.select(new Sort("Name", Sort.Direction.asc)); + assertNotNull(retval); + assertEquals(10, retval.size()); + Movie mov = retval.get(0); + assertEquals("Billy Madison", mov.getName()); + + retval = table.select(new Sort("Name", Sort.Direction.desc)); + assertNotNull(retval); + assertEquals(10, retval.size()); + mov = retval.get(0); + assertEquals("You've got Mail", mov.getName()); + + } + + @Test + public void testSelectTableView() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + List retval = base.table("Movies", Movie.class).select("Main View"); + assertNotNull(retval); + assertEquals(10, retval.size()); + Movie mov = retval.get(0); + assertEquals("The Godfather", mov.getName()); + } + + @Test(expected = AirtableException.class) + public void testSelectNonExistingTable() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + List retval = base.table("NotExists", Movie.class).select(); + assertNotNull(retval); + } + + @Test + public void testSelectWithSerializedNames() throws AirtableException, HttpResponseException { + + Base base = airtable.base("appe9941ff07fffcc"); + + List retval = base.table("SerializedNames", ActorSerializedNames.class).select(); + assertNotNull(retval); + assertEquals("Marlon Brando", retval.get(0).getName()); + } + +} From 5cc333fdbd641f94a184a39e5684c707425dbb31 Mon Sep 17 00:00:00 2001 From: kobisuissa Date: Thu, 27 Apr 2017 19:43:35 +0200 Subject: [PATCH 73/74] Merge branch 'develop' of https://github.com/hubrick/airtable.java into feature/allow-object-mapper-injection # Conflicts: # .travis.yml # build.gradle # src/main/java/com/sybit/airtable/Airtable.java --- .../airtable/TableSelectJacksonOMTest.java | 2 +- .../java/com/sybit/airtable/Airtable.java | 15 +- .../sybit/airtable/TableConverterTest.java | 94 ---------- .../sybit/airtable/TableCreateRecordTest.java | 153 --------------- .../com/sybit/airtable/TableDestroyTest.java | 43 ----- .../sybit/airtable/TableParameterTest.java | 174 ------------------ .../com/sybit/airtable/TableUpdateTest.java | 41 ----- 7 files changed, 15 insertions(+), 507 deletions(-) rename src/{test => itest}/java/com/sybit/airtable/TableSelectJacksonOMTest.java (98%) delete mode 100644 src/test/java/com/sybit/airtable/TableConverterTest.java delete mode 100644 src/test/java/com/sybit/airtable/TableCreateRecordTest.java delete mode 100644 src/test/java/com/sybit/airtable/TableDestroyTest.java delete mode 100644 src/test/java/com/sybit/airtable/TableParameterTest.java delete mode 100644 src/test/java/com/sybit/airtable/TableUpdateTest.java diff --git a/src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java b/src/itest/java/com/sybit/airtable/TableSelectJacksonOMTest.java similarity index 98% rename from src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java rename to src/itest/java/com/sybit/airtable/TableSelectJacksonOMTest.java index 3d01f33..709e6ef 100644 --- a/src/test/java/com/sybit/airtable/TableSelectJacksonOMTest.java +++ b/src/itest/java/com/sybit/airtable/TableSelectJacksonOMTest.java @@ -5,7 +5,7 @@ import com.sybit.airtable.exception.AirtableException; import com.sybit.airtable.movies.ActorSerializedNames; import com.sybit.airtable.movies.Movie; -import com.sybit.airtable.test.WireMockBaseTest; +import com.sybit.airtable.mock.WireMockBaseTest; import org.apache.http.client.HttpResponseException; import org.junit.Before; import org.junit.Test; diff --git a/src/main/java/com/sybit/airtable/Airtable.java b/src/main/java/com/sybit/airtable/Airtable.java index 5d858de..be13a52 100644 --- a/src/main/java/com/sybit/airtable/Airtable.java +++ b/src/main/java/com/sybit/airtable/Airtable.java @@ -122,6 +122,19 @@ public Airtable configure(String apiKey, ObjectMapper objectMapper) throws Airta * @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint */ @SuppressWarnings("WeakerAccess") + public Airtable configure(Configuration config) throws AirtableException { + return configure(config, new GsonObjectMapper()); + } + + + /** + * + * @param config + * @param objectMapper A custom ObjectMapper implementation + * @return + * @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint + */ + @SuppressWarnings("WeakerAccess") public Airtable configure(Configuration config, ObjectMapper objectMapper) throws AirtableException { if(config.getApiKey() == null) { throw new AirtableException("Missing Airtable API-Key"); @@ -140,7 +153,7 @@ public Airtable configure(Configuration config, ObjectMapper objectMapper) throw setProxy(config.getEndpointUrl()); // Only one time - Unirest.setObjectMapper(new GsonObjectMapper()); + Unirest.setObjectMapper(objectMapper); // Add specific Converter for Date DateTimeConverter dtConverter = new DateConverter(); diff --git a/src/test/java/com/sybit/airtable/TableConverterTest.java b/src/test/java/com/sybit/airtable/TableConverterTest.java deleted file mode 100644 index f94d08b..0000000 --- a/src/test/java/com/sybit/airtable/TableConverterTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.sybit.airtable; - -import com.sybit.airtable.exception.AirtableException; -import com.sybit.airtable.movies.Actor; -import com.sybit.airtable.movies.Movie; -import com.sybit.airtable.test.WireMockBaseTest; -import com.sybit.airtable.vo.Attachment; -import com.sybit.airtable.vo.Thumbnail; -import java.util.List; -import java.util.Map; -import org.apache.http.client.HttpResponseException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import org.junit.Test; - -/** - * - * @author fzr - */ -public class TableConverterTest extends WireMockBaseTest { - - //TODO Test für nicht gülitiges bzw String - - @Test - public void testConvertMovie() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie movie = movieTable.find("rec6733da527dd0f1"); - assertNotNull(movie); - - assertEquals(movie.getId(),"rec6733da527dd0f1"); - assertEquals(movie.getName(),"The Godfather"); - assertEquals(movie.getDescription(),"The Godfather is a 1972 American crime film film directed by Francis Ford Coppola and produced by Albert S. Ruddy and based on Mario Puzo's best-selli..."); - assertEquals(movie.getPhotos().size(),2); - assertEquals(movie.getDirector().size(),1); - assertEquals(movie.getActors().size(),2); - assertEquals(movie.getGenre().size(),1); - //TODO Test für Datum - - } - - @Test - public void testConvertAttachement() throws AirtableException, HttpResponseException { - - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie movie = movieTable.find("rec6733da527dd0f1"); - assertNotNull(movie); - - assertEquals(movie.getPhotos().size(),2); - - Attachment photo1 = movie.getPhotos().get(0); - assertNotNull(photo1); - Attachment photo2 = movie.getPhotos().get(0); - assertNotNull(photo2); - - assertEquals(photo1.getId(),"att6dba4af5786df1"); - assertEquals(photo1.getUrl(),"https://www.filepicker.io/api/file/akW7wUX7QM66a2hjxb9k"); - assertEquals(photo1.getFilename(),"220px-TheGodfatherAlPacinoMarlonBrando.jpg"); - assertEquals(photo1.getSize(),16420.0,0); - assertEquals(photo1.getType(),"image/jpeg"); - assertEquals(photo1.getThumbnails().size(),2); - - } - - @Test - public void testConvertThumbnails() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie movie = movieTable.find("rec6733da527dd0f1"); - assertNotNull(movie); - - assertEquals(movie.getPhotos().get(0).getThumbnails().size(),2); - assertEquals(movie.getPhotos().get(1).getThumbnails().size(),2); - Map thumbnails = movie.getPhotos().get(1).getThumbnails(); - Thumbnail thumb = thumbnails.get("small"); - assertEquals(thumb.getUrl(),"https://dl.airtable.com/MbdRAn4ZQLuNyUqrHONp_small_Lighthouse.jpg"); - assertEquals(thumb.getHeight(),36.0, 0); - assertEquals(thumb.getWidth(),48.0, 0); - - } - -} diff --git a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java b/src/test/java/com/sybit/airtable/TableCreateRecordTest.java deleted file mode 100644 index 3a64930..0000000 --- a/src/test/java/com/sybit/airtable/TableCreateRecordTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.sybit.airtable; - -import com.sybit.airtable.exception.AirtableException; -import com.sybit.airtable.movies.Actor; -import com.sybit.airtable.movies.Movie; -import com.sybit.airtable.test.WireMockBaseTest; -import com.sybit.airtable.vo.Attachment; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import org.junit.Test; - -/** - * - * @author fzr - */ -public class TableCreateRecordTest extends WireMockBaseTest { - - @Test(expected = AirtableException.class) - public void createMovieWithPhotoIdTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie newMovie = new Movie(); - newMovie.setName("Neuer Film"); - - List photos = new ArrayList(); - Attachment photo1 = new Attachment(); - - photo1.setUrl("https://www.example.imgae.file1.de"); - photo1.setId("1"); - - photos.add(photo1); - - newMovie.setPhotos(photos); - - Movie test = movieTable.create(newMovie); - - } - - @Test(expected = AirtableException.class) - public void createMovieWithIdTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie newMovie = new Movie(); - newMovie.setName("Neuer Film"); - newMovie.setId("1"); - Movie test = movieTable.create(newMovie); - - } - - @Test(expected = AirtableException.class) - public void createMovieWithCreatedTimeTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie newMovie = new Movie(); - newMovie.setName("Neuer Film"); - newMovie.setCreatedTime(new Date()); - Movie test = movieTable.create(newMovie); - - } - - @Test - public void createActorTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ - - Base base = airtable.base("appe9941ff07fffcc"); - - Table actorTable = base.table("Actors", Actor.class); - Actor newActor = new Actor(); - newActor.setName("Neuer Actor"); - Actor test = actorTable.create(newActor); - assertEquals(test.getName(),newActor.getName()); - assertEquals(test.getId(),"rec123456789"); - - } - - @Test - public void createMovieWithAttachementTest() throws AirtableException, IllegalAccessException, NoSuchMethodException, NoSuchMethodException, InstantiationException, InvocationTargetException, NoSuchFieldException { - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie newMovie = new Movie(); - - newMovie.setName("Neuer Film"); - List photos = new ArrayList(); - Attachment photo1 = new Attachment(); - Attachment photo2 = new Attachment(); - photo1.setUrl("https://www.example.imgae.file1.de"); - photo2.setUrl("https://www.example.imgae.file2.de"); - photos.add(photo1); - photos.add(photo2); - - newMovie.setPhotos(photos); - - Movie test = movieTable.create(newMovie); - - assertEquals("https://www.example.imgae.file1.de", test.getPhotos().get(0).getUrl()); - assertEquals("https://www.example.imgae.file2.de", test.getPhotos().get(1).getUrl()); - - assertNotNull(test.getPhotos().get(0).getId()); - assertNotNull(test.getPhotos().get(1).getId()); - - - } - - @Test - public void createMovieTest() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException, NoSuchFieldException{ - - Base base = airtable.base("appe9941ff07fffcc"); - - Table movieTable = base.table("Movies", Movie.class); - Movie newMovie = new Movie(); - - newMovie.setName("Neuer Film"); - newMovie.setDescription("Irgendwas"); - List director = new ArrayList<>(); - director.add("recfaf64fe0db19a9"); - newMovie.setDirector(director); - List actors = new ArrayList<>(); - actors.add("recc8841a14245b0b"); - actors.add("rec514228ed76ced1"); - newMovie.setActors(actors); - List genre = new ArrayList<>(); - genre.add("Drama"); - newMovie.setGenre(genre); - - Movie test = movieTable.create(newMovie); - - assertEquals(newMovie.getName(),test.getName()); - assertEquals(newMovie.getActors(),test.getActors()); - assertEquals(newMovie.getGenre(),test.getGenre()); - assertEquals(newMovie.getDescription(),test.getDescription()); - assertEquals("rec987654321",test.getId()); - assertNotNull(test.getCreatedTime()); - - - } - -} diff --git a/src/test/java/com/sybit/airtable/TableDestroyTest.java b/src/test/java/com/sybit/airtable/TableDestroyTest.java deleted file mode 100644 index 833a8c1..0000000 --- a/src/test/java/com/sybit/airtable/TableDestroyTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.sybit.airtable; - -import com.sybit.airtable.exception.AirtableException; -import com.sybit.airtable.movies.Actor; -import com.sybit.airtable.test.WireMockBaseTest; -import java.util.List; -import org.apache.http.client.HttpResponseException; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -/** - * - * @author fzr - */ -public class TableDestroyTest extends WireMockBaseTest { - - - - @Test - public void testDestroyMovie() throws AirtableException, HttpResponseException{ - - Base base = airtable.base("appe9941ff07fffcc"); - Table actorTable = base.table("Actors", Actor.class); - - actorTable.destroy("recapJ3Js8AEwt0Bf"); - - } - - @Test (expected = AirtableException.class) - public void testDestroyMovieException() throws AirtableException{ - - Base base = airtable.base("appe9941ff07fffcc"); - Table actorTable = base.table("Actors", Actor.class); - - actorTable.destroy("not succesfull"); - } - -} diff --git a/src/test/java/com/sybit/airtable/TableParameterTest.java b/src/test/java/com/sybit/airtable/TableParameterTest.java deleted file mode 100644 index 3461bc7..0000000 --- a/src/test/java/com/sybit/airtable/TableParameterTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.sybit.airtable; - -import com.sybit.airtable.exception.AirtableException; -import com.sybit.airtable.movies.Movie; -import com.sybit.airtable.test.WireMockBaseTest; -import java.util.List; -import org.apache.http.client.HttpResponseException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import org.junit.Test; - -/** - * - * @author fzr - */ -public class TableParameterTest extends WireMockBaseTest { - - @Test - public void fieldsParamTest() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - Table movieTable = base.table("Movies", Movie.class); - - String[] fields = new String[1]; - fields[0] = "Name"; - - List listMovies = movieTable.select(fields); - assertNotNull(listMovies); - assertNull(listMovies.get(0).getDirector()); - assertNull(listMovies.get(0).getActors()); - assertNull(listMovies.get(0).getDescription()); - - } - - @Test - public void formulaParamTest() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - Table movieTable = base.table("Movies", Movie.class); - - Query query = new Query() { - @Override - public String[] getFields() { - return null; - } - - @Override - public Integer getPageSize() { - return null; - } - - @Override - public Integer getMaxRecords() { - return null; - } - - @Override - public String getView() { - return null; - } - - @Override - public List getSort() { - return null; - } - - @Override - public String filterByFormula() { - return "NOT({Name} = '')"; - } - }; - - List listMovies = movieTable.select(query); - assertNotNull(listMovies); - assertEquals(listMovies.size(),2); - - - } - - @Test - public void maxRecordsParamTest() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - Table movieTable = base.table("Movies", Movie.class); - - int maxRecords = 2; - - List listMovies = movieTable.select(maxRecords); - assertNotNull(listMovies); - assertEquals(listMovies.size(),2); - - } - - @Test - public void pageSizeParamTest() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - Table movieTable = base.table("Movies", Movie.class); - - Query query = new Query() { - @Override - public String[] getFields() { - return null; - } - - @Override - public Integer getPageSize() { - return 10; - } - - @Override - public Integer getMaxRecords() { - return null; - } - - @Override - public String getView() { - return null; - } - - @Override - public List getSort() { - return null; - } - - @Override - public String filterByFormula() { - return null; - } - }; - - List listMovies = movieTable.select(query); - assertNotNull(listMovies); - - } - - @Test - public void sortParamTest() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - Table movieTable = base.table("Movies", Movie.class); - Sort sort = new Sort("Name", Sort.Direction.desc); - - List listMovies = movieTable.select(sort); - assertNotNull(listMovies); - assertEquals(listMovies.get(9).getName(),"Billy Madison"); - - - } - - @Test - public void viewParamTest() throws AirtableException, HttpResponseException { - - Base base = airtable.base("appe9941ff07fffcc"); - Table movieTable = base.table("Movies", Movie.class); - - String view = "Dramas"; - - - List listMovies = movieTable.select(view); - assertNotNull(listMovies); - assertEquals(listMovies.size(),5); - - } - - - -} diff --git a/src/test/java/com/sybit/airtable/TableUpdateTest.java b/src/test/java/com/sybit/airtable/TableUpdateTest.java deleted file mode 100644 index e9a0b0d..0000000 --- a/src/test/java/com/sybit/airtable/TableUpdateTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.sybit.airtable; - -import com.sybit.airtable.exception.AirtableException; -import com.sybit.airtable.movies.Actor; -import com.sybit.airtable.test.WireMockBaseTest; -import java.lang.reflect.InvocationTargetException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import org.junit.Test; - -/** - * - * @author fzr - */ -public class TableUpdateTest extends WireMockBaseTest { - - @Test - public void testUpdateActor() throws AirtableException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{ - - Base base = airtable.base("appe9941ff07fffcc"); - - Table actorTable = base.table("Actors", Actor.class); - Actor marlonBrando = new Actor(); - marlonBrando.setId("rec514228ed76ced1"); - marlonBrando.setName("Neuer Name"); - - Actor updated = actorTable.update(marlonBrando); - - assertEquals(updated.getName(),"Neuer Name"); - assertNotNull(updated.getBiography()); - assertNotNull(updated.getFilmography()); - assertNotNull(updated.getPhoto()); - assertNotNull(updated.getId()); - - } -} From 0bbf382abf2507a04b68ea01bf4f03edac27dd4f Mon Sep 17 00:00:00 2001 From: kobisuissa Date: Fri, 28 Apr 2017 11:07:52 +0200 Subject: [PATCH 74/74] Merge branch 'develop' of https://github.com/hubrick/airtable.java into feature/allow-object-mapper-injection # Conflicts: # .travis.yml # build.gradle # src/main/java/com/sybit/airtable/Airtable.java --- src/{test => itest}/java/com/sybit/airtable/AirtableTest.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{test => itest}/java/com/sybit/airtable/AirtableTest.java (100%) diff --git a/src/test/java/com/sybit/airtable/AirtableTest.java b/src/itest/java/com/sybit/airtable/AirtableTest.java similarity index 100% rename from src/test/java/com/sybit/airtable/AirtableTest.java rename to src/itest/java/com/sybit/airtable/AirtableTest.java