Skip to content
This repository was archived by the owner on Mar 31, 2025. It is now read-only.

Commit 843f599

Browse files
authored
Merge pull request #2 from Sybit-Education/feauture/AttachementConverter
Feauture/attachement converter
2 parents 2cd8c72 + bc37efa commit 843f599

11 files changed

Lines changed: 681 additions & 34 deletions

File tree

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ For adding dependency, you could use bintray-repository:
1717

1818
The files are stored at: [https://dl.bintray.com/sybit-education/maven/](https://dl.bintray.com/sybit-education/maven/)
1919

20+
## Gradle
21+
For Gradle add compile `com.sybit:airtable.java:[version]` to compile dependencies.
22+
Also add `jcenter` repository to dependencies:
23+
```
24+
repositories {
25+
jcenter()
26+
...
27+
}
28+
```
2029

2130
## Initializing
2231

@@ -71,6 +80,19 @@ Table<Actor> actorTable = base.table("Actors", Actor.class);
7180
Actor actor = actorTable.find("rec514228ed76ced1");
7281
```
7382

83+
## Annotations
84+
85+
Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter.
86+
87+
### Example
88+
```Java
89+
90+
import com.google.gson.annotations.SerializedName;
91+
92+
@SerializedName("First- & Lastname")
93+
private String name;
94+
```
95+
7496
# Roadmap
7597

7698
+ [x] Select

src/main/java/com/sybit/airtable/Airtable.java

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
*/
77
package com.sybit.airtable;
88

9-
import com.google.gson.Gson;
10-
import com.google.gson.GsonBuilder;
11-
import com.mashape.unirest.http.ObjectMapper;
9+
1210
import com.mashape.unirest.http.Unirest;
1311
import com.sybit.airtable.exception.AirtableException;
12+
import com.sybit.airtable.vo.Attachment;
13+
import com.sybit.airtable.vo.Thumbnail;
14+
15+
import org.apache.http.HttpHost;
1416
import org.apache.commons.beanutils.ConvertUtils;
1517
import org.apache.commons.beanutils.converters.DateConverter;
1618
import org.apache.commons.beanutils.converters.DateTimeConverter;
@@ -20,8 +22,11 @@
2022
import java.io.IOException;
2123
import java.io.InputStream;
2224
import java.util.Date;
25+
import java.util.List;
26+
import java.util.Map;
2327
import java.util.Properties;
2428

29+
2530
/**
2631
* Representation Class of Airtable.
2732
* It is the entry class to access Airtable data.
@@ -49,6 +54,7 @@ public class Airtable {
4954
* or within credentials.properties.
5055
*
5156
* @return configured Airtable object.
57+
* @throws com.sybit.airtable.exception.AirtableException Missing API-Key
5258
*/
5359
@SuppressWarnings("UnusedReturnValue")
5460
public Airtable configure() throws AirtableException {
@@ -74,6 +80,7 @@ public Airtable configure() throws AirtableException {
7480
*
7581
* @param apiKey API-Key of Airtable.
7682
* @return
83+
* @throws com.sybit.airtable.exception.AirtableException Missing API-Key
7784
*/
7885
@SuppressWarnings("WeakerAccess")
7986
public Airtable configure(String apiKey) throws AirtableException {
@@ -85,6 +92,7 @@ public Airtable configure(String apiKey) throws AirtableException {
8592
* @param apiKey
8693
* @param endpointUrl
8794
* @return
95+
* @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint
8896
*/
8997
@SuppressWarnings("WeakerAccess")
9098
public Airtable configure(String apiKey, String endpointUrl) throws AirtableException {
@@ -98,40 +106,55 @@ public Airtable configure(String apiKey, String endpointUrl) throws AirtableExce
98106
this.apiKey = apiKey;
99107
this.endpointUrl = endpointUrl;
100108

101-
102-
final String httpProxy = System.getenv("http_proxy");
103-
if(httpProxy != null) {
104-
LOG.info("Use Proxy: Environment variable 'http_proxy' found and used: " + httpProxy);
105-
//Unirest.setProxy(HttpHost.create(httpProxy));
106-
}
107-
109+
setProxy(endpointUrl);
108110

109111
// Only one time
110-
Unirest.setObjectMapper(new ObjectMapper() {
111-
final Gson gson = new GsonBuilder().create();
112-
113-
public <T> T readValue(String value, Class<T> valueType) {
114-
LOG.debug("readValue: \n" + value);
115-
return gson.fromJson(value, valueType);
116-
}
117-
118-
public String writeValue(Object value) {
119-
return gson.toJson(value);
120-
}
121-
});
112+
Unirest.setObjectMapper(new GsonObjectMapper());
122113

114+
123115
// Add specific Converter for Date
124116
DateTimeConverter dtConverter = new DateConverter();
117+
ListConverter lConverter = new ListConverter();
118+
MapConverter thConverter = new MapConverter();
119+
120+
lConverter.setListClass(Attachment.class);
121+
thConverter.setMapClass(Thumbnail.class);
125122
dtConverter.setPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
123+
126124
ConvertUtils.register(dtConverter, Date.class);
125+
ConvertUtils.register(lConverter, List.class);
126+
ConvertUtils.register(thConverter, Map.class);
127+
127128

128129
return this;
129130
}
130131

132+
/**
133+
* Set Proxy environment for Unirest.
134+
*
135+
* Proxy will be ignored for endpointUrls containing <code>localhost</code> or <code>127.0.0.1,/code>
136+
* @param endpointUrl
137+
*/
138+
private void setProxy(String endpointUrl) {
139+
final String httpProxy = System.getenv("http_proxy");
140+
if(httpProxy != null
141+
&& (endpointUrl.contains("127.0.0.1")
142+
|| endpointUrl.contains("localhost"))) {
143+
LOG.info("Use Proxy: ignored for 'localhost' ann '127.0.0.1'");
144+
Unirest.setProxy(null);
145+
} else if(httpProxy != null) {
146+
LOG.info("Use Proxy: Environment variable 'http_proxy' found and used: " + httpProxy);
147+
Unirest.setProxy(HttpHost.create(httpProxy));
148+
} else {
149+
Unirest.setProxy(null);
150+
}
151+
}
152+
131153
/**
132154
* Getting the base by given property <code>AIRTABLE_BASE</code>.
133155
*
134156
* @return the base object.
157+
* @throws com.sybit.airtable.exception.AirtableException Missing Airtable_BASE
135158
*/
136159
public Base base() throws AirtableException {
137160

@@ -153,6 +176,7 @@ public Base base() throws AirtableException {
153176
* Builder method to create base of given base id.
154177
* @param base the base id.
155178
* @return
179+
* @throws com.sybit.airtable.exception.AirtableException AIRTABLE_BASE was Null
156180
*/
157181
public Base base(String base) throws AirtableException {
158182
if(base == null) {
@@ -210,5 +234,6 @@ private String getCredentialProperty(String key) {
210234

211235
public void setEndpointUrl(String endpointUrl) {
212236
this.endpointUrl = endpointUrl;
237+
setProxy(endpointUrl);
213238
}
214239
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* To change this license header, choose License Headers in Project Properties.
3+
* To change this template file, choose Tools | Templates
4+
* and open the template in the editor.
5+
*/
6+
package com.sybit.airtable;
7+
8+
import com.google.gson.Gson;
9+
import com.google.gson.GsonBuilder;
10+
import com.mashape.unirest.http.ObjectMapper;
11+
import java.util.logging.Level;
12+
import java.util.logging.Logger;
13+
14+
/**
15+
*
16+
* @author fzr
17+
*/
18+
class GsonObjectMapper implements ObjectMapper{
19+
private static final Logger LOG = Logger.getLogger( GsonObjectMapper.class.getName() );
20+
private final Gson gson;
21+
22+
public GsonObjectMapper() {
23+
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
24+
25+
}
26+
27+
public <T> T readValue(String value, Class<T> valueType) {
28+
LOG.log(Level.INFO, "readValue: \n" + value);
29+
return gson.fromJson(value, valueType);
30+
}
31+
32+
public String writeValue(Object value) {
33+
return gson.toJson(value);
34+
}
35+
36+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* To change this license header, choose License Headers in Project Properties.
3+
* To change this template file, choose Tools | Templates
4+
* and open the template in the editor.
5+
*/
6+
package com.sybit.airtable;
7+
8+
import com.google.gson.internal.LinkedTreeMap;
9+
import java.lang.reflect.InvocationTargetException;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
import org.apache.commons.beanutils.BeanUtils;
13+
import org.apache.commons.beanutils.converters.AbstractConverter;
14+
15+
/**
16+
*
17+
* org.apache.commons.beanutils.Converter implementaion
18+
* that handles conversion to and from List&lt;T&gt; objects.
19+
*
20+
* <p>This implementation converts List&lt;T&gt; to List&lt;innerClass&gt;.
21+
* The innerClass can be set to the Class that is needed.</p>
22+
*
23+
* @author fzr
24+
*/
25+
public class ListConverter extends AbstractConverter {
26+
27+
private Class listClass;
28+
29+
/**
30+
*
31+
* Method overwritten so it doesent return only the first Element of the Array.
32+
*
33+
* @param value The Input Value
34+
* @return value The value to be returned
35+
*/
36+
@Override
37+
protected Object convertArray(final Object value) {
38+
return value;
39+
}
40+
41+
/**
42+
*
43+
* Convert the Input Object into a List of Attachements
44+
*
45+
* This Method handles the conversion from a List of LinkedHashMaps to a List of Attachement Objects.
46+
*
47+
* <p>If the Input Object is no List or the List Item is no LinkedHashMap everything will be converted into a (List?) String.</p>
48+
*
49+
* @param type The type of the Input Object
50+
* @param value The value of the Input Object
51+
* @return A List
52+
* @throws java.lang.InstantiationException If no Instance of the listClass can be instantiated
53+
* @throws java.lang.IllegalAccessException If the Object can't be accest
54+
* @throws java.lang.reflect.InvocationTargetException If th Target can't be accessed
55+
*/
56+
@Override
57+
protected <T> T convertToType(final Class<T> type, Object value) throws InstantiationException, IllegalAccessException, InvocationTargetException {
58+
59+
List<T> returnList = new ArrayList<>();
60+
61+
if(value instanceof List){
62+
for (T item: ((List<T>) value)){
63+
if(item instanceof LinkedTreeMap){
64+
Object instanz = this.listClass.newInstance();
65+
for (String key : ((LinkedTreeMap<String, Object>) item).keySet()) {
66+
Object val = ((LinkedTreeMap) item).get(key);
67+
BeanUtils.setProperty(instanz,key,val);
68+
}
69+
returnList = toClassList(item.getClass(),instanz,returnList);
70+
}
71+
if(item instanceof String){
72+
returnList = toStringList(item.getClass(),item.toString(),returnList);
73+
}
74+
75+
}
76+
return (T) returnList;
77+
}
78+
79+
80+
//TODO überarbeiten
81+
if(value instanceof String){
82+
return (T) toStringList(value.getClass(),value.toString(),returnList);
83+
}
84+
85+
final String stringValue = value.toString().trim();
86+
if (stringValue.length() == 0) {
87+
return handleMissing(type);
88+
}
89+
90+
return (T) toStringList(value.getClass(),stringValue,returnList);
91+
}
92+
93+
/**
94+
* Default toString conversion
95+
*
96+
* @param type The type of the Class
97+
* @param value The String value
98+
* @param returnList A List of all currently converted Objects
99+
* @return A List
100+
*/
101+
private List toStringList(final Class type, final String value,List returnList) {
102+
103+
if (type.equals(String.class)) {
104+
returnList.add(String.valueOf(value));
105+
return returnList;
106+
}
107+
108+
returnList.add(String.valueOf(value));
109+
return returnList;
110+
}
111+
112+
/**
113+
* Default conversion to specified Class.
114+
*
115+
* <p>If conversion is not possible default toString.</p>
116+
*
117+
* @param type The type of the Class
118+
* @param value The value of the Input Object
119+
* @param returnList A List of all currently converted Objects
120+
* @return A List
121+
*/
122+
private List toClassList(final Class type, final Object value, List returnList) {
123+
124+
if (type.equals(LinkedTreeMap.class)) {
125+
returnList.add(value);
126+
return returnList;
127+
}
128+
129+
return toStringList(type,value.toString(),returnList);
130+
}
131+
132+
/**
133+
* @param listClass the listClass to set
134+
*/
135+
public void setListClass(Class listClass) {
136+
this.listClass = listClass;
137+
}
138+
139+
//TODO Default überlegen
140+
@Override
141+
protected Class<?> getDefaultType() {
142+
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
143+
}
144+
145+
146+
147+
148+
149+
150+
151+
152+
153+
154+
155+
}

0 commit comments

Comments
 (0)