├── .classpath ├── .gitignore ├── .project ├── .settings └── org.eclipse.jdt.core.prefs ├── README.md ├── pom.xml ├── pom_android.xml └── src ├── main └── java │ └── com │ └── simplegeo │ └── client │ ├── AbstractSimpleGeoClient.java │ ├── SimpleGeoClient.java │ ├── SimpleGeoContextClient.java │ ├── SimpleGeoPlaces12Client.java │ ├── SimpleGeoPlacesClient.java │ ├── SimpleGeoStorageClient.java │ ├── callbacks │ └── SimpleGeoCallback.java │ ├── concurrent │ ├── NamedThreadFactory.java │ └── RequestThreadPoolExecutor.java │ ├── http │ ├── OAuthClient.java │ ├── OAuthHttpClient.java │ ├── SimpleGeoHandler.java │ ├── SimpleGeoHttpRequestInterceptor.java │ ├── SimpleGeoRedirectHandler.java │ └── exceptions │ │ ├── APIException.java │ │ ├── NoSuchEntityException.java │ │ └── NotAuthorizedException.java │ └── types │ ├── Annotation.java │ ├── Category.java │ ├── CategoryCollection.java │ ├── Feature.java │ ├── FeatureCollection.java │ ├── Geometry.java │ ├── GeometryCollection.java │ ├── Layer.java │ ├── LayerCollection.java │ ├── MultiPolygon.java │ ├── Point.java │ ├── Polygon.java │ └── Record.java └── test └── java └── com └── simplegeo └── client ├── SimpleGeoContextClientTest.java ├── SimpleGeoPlaces12ClientTest.java ├── SimpleGeoPlacesClientTest.java ├── SimpleGeoStorageClientTest.java ├── test └── TestEnvironment.java └── types ├── FeatureTest.java ├── MultiPolygonTest.java ├── PointTest.java └── PolygonTest.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | target/ 3 | .DS_Store 4 | .settings/ 5 | .project 6 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | java-simplegeo 3 | Sonatype helps open source projects to set up Maven repositories on https://oss.sonatype.org/. NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. 4 | 5 | 6 | 7 | org.eclipse.jdt.core.javabuilder 8 | 9 | 10 | org.eclipse.m2e.core.maven2Builder 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Nature 15 | org.eclipse.jdt.core.javanature 16 | 17 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | #Wed Aug 03 14:22:47 PDT 2011 2 | eclipse.preferences.version=1 3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.6 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.6 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # java-simplegeo 2 | 3 | A thread-safe, Java HttpClient used to interface with the SimpleGeo Places, Context and Storage API. Both synchronous and asynchronous calls are provided. 4 | 5 | ## Disclaimer 6 | 7 | Version 3.0 of this client is non-backwards compatible. Older versions of the client are still available by selecting a 1.x or 2.x tag from the drop down. 8 | 9 | ## Changes from 2.0 10 | 11 | * Optional parameters are now truly optional. Instead of setting things to null or empty strings, optional parameters are to be specified in a HashMap 12 | * Individual clients are no longer singletons. The use case didn't seem to fit everyone's needs, so we're leaving it up to you from now on whether you want that structure. 13 | * All return types are now Strings. These Strings are actually JSON and can be converted directly to JSONObject or JSONArray. Also, most data structures contain static methods that will convert the String to that structure for you. 14 | * Handlers have gone away. Previously we allowed specific handlers to be specified to format returned data for you. Now if you want to do this, simply use the appropriate fromJSONString method of the data structure you want with the resulting json String. 15 | * Querying by multiple categories, filtering by multiple sections in context, etc. is now fully supported. To query by multiple categories, simply populate the String array in your queryParams HashMap as so. 16 | HashMap queryParams = new HashMap(); 17 | queryParams.put("category", new String[] {"restaurant", "bar"}); 18 | * Demographics searching for Context is also fully supported. Simply create a query parameter with type demographics.acs\_\_table and add as many table names to the String[]. 19 | * The entire project has been converted to Maven in order to help automate builds and documentation. 20 | 21 | ## Adding to a Java project 22 | 23 | ### Maven 24 | 25 | If you're developing a Java project with Maven, adding the SimpleGeo jar to your project is super simple. Just add this snippet to to your pom.xml 26 | 27 | 28 | com.simplegeo 29 | java-simplegeo 30 | 3.x 31 | 32 | 33 | ### Using maven to build a jar 34 | 35 | If you're developing a java project that doesn't use maven, you can download the jar from github or package one yourself using maven. 36 | 37 | $ cd ~/path/to/java-simplegeo 38 | $ mvn package -Dmaven.test.skip=true 39 | 40 | You should then have a jar with the name java-simplegeo-3.x.jar. Feel free to rename this and then add it to your project. If you want to run the tests, remove the option and make sure your _TestEnvironment.java_ is set up with your oauth info. 41 | 42 | 43 | ### Eclipse 44 | 45 | 1. Right click (ctrl + click) on your project 46 | 2. Build Path 47 | 3. Configure Build Path 48 | 4. Select the Libraries tab 49 | 5. Add JARs (if the SimpleGeo jar is in your workspace)/Add External JARs (if the SimpleGeo jar is on your filesystem) 50 | 6. Navigate to the jar you want to add and click OK. The jar has been added to your project and you can start using it by getting an instance and setting your OAuth Token like so: 51 | 52 | SimpleGeoPlacesClient placesClient = new SimpleGeoPlacesClient(); 53 | placesClient.getHttpClient().setToken("oauth-key", "oauth-secret"); 54 | 55 | ## Adding to an Android project 56 | 57 | 1. Add java-simplegeo-3.1.2.jar to your build path. 58 | 1. Add signpost-core-1.2.1.1.jar, signpost-commonshttp4-1.2.1.1.jar and commons-codec-1.5.jar to your build path. 59 | 60 | ## Dependencies 61 | 62 | In case you decide not to use maven on your project, the following jars are required in order for the SimpleGeo jar to work. 63 | 64 | * junit-4.8.2.jar (testing only) 65 | * signpost-core-1.2.1.1.jar 66 | * signpost-commonshttp4-1.2.1.1.jar 67 | * httpclient-4.0.jar (java only) 68 | * httpcore-4.0.jar (java only) 69 | * commons-codec-1.5.jar 70 | * commons-logging-1.1.1.jar (java only) 71 | * json-20090211.jar (java only) 72 | 73 | All of these jars should be widely available on line, but I suggest search.maven.org as a central place that you'll be able to find all of them easily. 74 | 75 | ## Tests 76 | 77 | If you're interested in running the tests, you need to do a small piece of set up and then you can run them one of two ways. 78 | 79 | ### Setup 80 | 81 | * Find file TestEnvironment.java in the com.simplegeo.client.test package in the src/test/java folder. 82 | * Replace consumerKey and consumerSecret with your oauth key and secret from https://simplegeo.com. 83 | * If you have a paid account, set paidAccount to true, else leave it false. 84 | 85 | ### From the command line 86 | 87 | $ cd ~/path/to/java-simplegeo 88 | $ mvn test 89 | 90 | ### From Eclipse 91 | 92 | * Ctrl + click on the src/test/java 93 | * Run As 94 | * JUnit Test 95 | 96 | ## Documentation 97 | 98 | The docs are generated using `javadoc` and are updated as often as we build the client in our public Jenkins environment. You can view them [here](https://ci.public.simplegeo.com/job/java-simplegeo/javadoc) 99 | 100 | ### Simple Example 101 | 102 | import java.io.IOException; 103 | import java.util.ArrayList; 104 | 105 | import org.json.JSONException; 106 | 107 | import com.simplegeo.client.SimpleGeoPlacesClient; 108 | import com.simplegeo.client.types.Feature; 109 | import com.simplegeo.client.types.FeatureCollection; 110 | 111 | public class HelloWorld { 112 | public static void main(String[] args) { 113 | SimpleGeoPlacesClient placesClient = new SimpleGeoPlacesClient(); 114 | placesClient.getHttpClient().setToken("oauth-key", "oauth-secret"); 115 | HashMap queryParams = new HashMap(); 116 | queryParams.put("category", new String[] {"sushi"}); 117 | try { 118 | String sushiString = placesClient.search(37.800426, -122.439516, queryParams); 119 | FeatureCollection sushiFeatureCollection = FeatureCollection.fromJSONString(sushiString); 120 | ArrayList sushiFeatures = sushiFeatureCollection.getFeatures(); 121 | for (Feature feature: sushiFeatures) { 122 | System.out.println(feature.getProperties().get("name")); 123 | } 124 | } catch (IOException e) { 125 | e.printStackTrace(); 126 | } catch (JSONException e) { 127 | e.printStackTrace(); 128 | } 129 | } 130 | } 131 | 132 | ### Copyright (C) 2011 SimpleGeo Inc. All rights reserved. 133 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.simplegeo 5 | java-simplegeo 6 | 3.1.1 7 | jar 8 | 9 | org.sonatype.oss 10 | oss-parent 11 | 7 12 | 13 | 14 | 15 | junit 16 | junit 17 | 4.8.2 18 | test 19 | 20 | 21 | com.google.android 22 | android 23 | 2.3.3 24 | provided 25 | true 26 | 27 | 28 | oauth.signpost 29 | signpost-core 30 | 1.2.1.1 31 | provided 32 | 33 | 34 | oauth.signpost 35 | signpost-commonshttp4 36 | 1.2.1.1 37 | provided 38 | 39 | 40 | org.apache.httpcomponents 41 | httpclient 42 | 4.0 43 | provided 44 | 45 | 46 | org.apache.httpcomponents 47 | httpcore 48 | 4.0 49 | provided 50 | 51 | 52 | org.json 53 | json 54 | 20090211 55 | provided 56 | 57 | 58 | 59 | 60 | 61 | maven-assembly-plugin 62 | 2.2.1 63 | 64 | 65 | jar-with-dependencies 66 | 67 | 68 | 69 | 70 | org.apache.maven.plugins 71 | maven-compiler-plugin 72 | 73 | 1.6 74 | 1.6 75 | 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-gpg-plugin 80 | 81 | 82 | sign-artifacts 83 | verify 84 | 85 | sign 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | SimpleGeo, Inc. 94 | https://simplegeo.com 95 | 96 | 97 | git@github.com:simplegeo/java-simplegeo.git 98 | scm:git@github.com:simplegeo/java-simplegeo.git 99 | scm:git@github.com:simplegeo/java-simplegeo.git 100 | 101 | 102 | 103 | caseycrites 104 | Casey Crites 105 | casey@simplegeo.com 106 | SimpleGeo, Inc. 107 | https://simplegeo.com 108 | 109 | developer 110 | 111 | 112 | 113 | 114 | 115 | Pranil Kanderi 116 | pranil@mokriya.com 117 | Mokriya, LLC 118 | www.mokriya.com 119 | 120 | 121 | 122 | 123 | Apache License, Version 2.0 124 | http://www.apache.org/licenses/LICENSE-2.0.txt 125 | repo 126 | 127 | 128 | -------------------------------------------------------------------------------- /pom_android.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.simplegeo 5 | java-simplegeo 6 | 3.1.1 7 | jar 8 | 9 | org.sonatype.oss 10 | oss-parent 11 | 7 12 | 13 | 14 | 15 | com.google.android 16 | android 17 | 2.3.3 18 | provided 19 | 20 | 21 | junit 22 | junit 23 | 4.8.2 24 | test 25 | 26 | 27 | oauth.signpost 28 | signpost-core 29 | 1.2.1.1 30 | 31 | 32 | oauth.signpost 33 | signpost-commonshttp4 34 | 1.2.1.1 35 | 36 | 37 | 38 | 39 | 40 | false 41 | 42 | central 43 | Maven Repository Switchboard 44 | http://repo1.maven.org/maven2 45 | 46 | 47 | 48 | 49 | 50 | never 51 | 52 | 53 | false 54 | 55 | central 56 | Maven Plugin Repository 57 | http://repo1.maven.org/maven2 58 | 59 | 60 | 61 | 62 | 63 | com.jayway.maven.plugins.android.generation2 64 | android-maven-plugin 65 | 3.0.0-alpha-11 66 | true 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-compiler-plugin 71 | 2.3.2 72 | 73 | 1.6 74 | 1.6 75 | 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-javadoc-plugin 80 | 2.3.2 81 | 82 | 83 | 84 | 85 | SimpleGeo, Inc. 86 | https://simplegeo.com 87 | 88 | 89 | git@github.com:simplegeo/java-simplegeo.git 90 | scm:git@github.com:simplegeo/java-simplegeo.git 91 | scm:git@github.com:simplegeo/java-simplegeo.git 92 | 93 | 94 | 95 | caseycrites 96 | Casey Crites 97 | casey@simplegeo.com 98 | SimpleGeo, Inc. 99 | https://simplegeo.com 100 | 101 | developer 102 | 103 | 104 | 105 | 106 | 107 | Pranil Kanderi 108 | pranil@mokriya.com 109 | Mokriya, LLC 110 | www.mokriya.com 111 | 112 | 113 | 114 | 115 | Apache License, Version 2.0 116 | http://www.apache.org/licenses/LICENSE-2.0.txt 117 | repo 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/AbstractSimpleGeoClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.io.UnsupportedEncodingException; 5 | import java.net.URLEncoder; 6 | import java.util.HashMap; 7 | import java.util.Locale; 8 | import java.util.Map.Entry; 9 | import java.util.Set; 10 | import java.util.logging.Logger; 11 | 12 | import oauth.signpost.exception.OAuthCommunicationException; 13 | import oauth.signpost.exception.OAuthExpectationFailedException; 14 | import oauth.signpost.exception.OAuthMessageSignerException; 15 | 16 | import org.apache.http.client.ClientProtocolException; 17 | import org.apache.http.conn.scheme.Scheme; 18 | import org.apache.http.conn.scheme.SchemeRegistry; 19 | import org.apache.http.conn.ssl.SSLSocketFactory; 20 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 21 | import org.apache.http.params.BasicHttpParams; 22 | import org.apache.http.params.HttpParams; 23 | import org.apache.http.params.HttpProtocolParams; 24 | import org.json.JSONException; 25 | 26 | import com.simplegeo.client.callbacks.SimpleGeoCallback; 27 | import com.simplegeo.client.concurrent.RequestThreadPoolExecutor; 28 | import com.simplegeo.client.http.OAuthClient; 29 | import com.simplegeo.client.http.OAuthHttpClient; 30 | import com.simplegeo.client.http.SimpleGeoHandler; 31 | import com.simplegeo.client.http.SimpleGeoHttpRequestInterceptor; 32 | import com.simplegeo.client.http.SimpleGeoRedirectHandler; 33 | import com.simplegeo.client.http.exceptions.APIException; 34 | import com.simplegeo.client.types.Annotation; 35 | 36 | /** 37 | * Extracts as much common code as possible from the SimpleGeoPlacesClient, 38 | * SimpleGeoContextClient and SimpleGeoStorageClient. 39 | * 40 | * @author Casey Crites 41 | */ 42 | 43 | public abstract class AbstractSimpleGeoClient implements SimpleGeoClient { 44 | 45 | private RequestThreadPoolExecutor threadExecutor; 46 | private OAuthHttpClient httpClient; 47 | 48 | protected static Logger logger = Logger.getLogger(AbstractSimpleGeoClient.class.getName()); 49 | 50 | public HashMap endpoints = new HashMap(); 51 | 52 | /** 53 | * Main constructor class for setting up the client that the specific Places/Context clients 54 | * extend from. 55 | */ 56 | protected AbstractSimpleGeoClient() { 57 | 58 | HttpParams params = new BasicHttpParams(); 59 | HttpProtocolParams.setUseExpectContinue(params, false); 60 | HttpProtocolParams.setUserAgent(params, "SimpleGeo Java Client"); 61 | SchemeRegistry schemeRegistry = new SchemeRegistry(); 62 | schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), PORT)); 63 | ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(params, schemeRegistry); 64 | 65 | this.httpClient = new OAuthHttpClient(connManager, params); 66 | this.httpClient.addRequestInterceptor(new SimpleGeoHttpRequestInterceptor()); 67 | this.httpClient.setRedirectHandler(new SimpleGeoRedirectHandler()); 68 | this.threadExecutor = new RequestThreadPoolExecutor("SimpleGeoClient"); 69 | 70 | endpoints.put("features", "1.2/places/%s.json"); 71 | endpoints.put("annotations", "1.0/features/%s/annotations.json"); 72 | } 73 | 74 | /** 75 | * Method for executing HttpRequests synchronously. 76 | * @param urlString String URL endpoint. 77 | * @param method {@link com.simplegeo.client.SimpleGeoClient.HttpRequestMethod} 78 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 79 | * @param jsonPayload String A string with the json that will be sent with the request. 80 | * @return String 81 | * @throws ClientProtocolException 82 | * @throws IOException 83 | */ 84 | protected String execute(String urlString, HttpRequestMethod method, HashMap queryParams, String jsonPayload) throws ClientProtocolException, IOException { 85 | 86 | String response = ""; 87 | try { 88 | response = httpClient.executeOAuthRequest(urlString + this.buildQueryString(queryParams), method, jsonPayload, new SimpleGeoHandler()); 89 | } catch (OAuthMessageSignerException e) { 90 | dealWithAuthorizationException(e); 91 | } catch (OAuthExpectationFailedException e) { 92 | dealWithAuthorizationException(e); 93 | } catch (OAuthCommunicationException e) { 94 | dealWithAuthorizationException(e); 95 | } 96 | 97 | return response; 98 | 99 | } 100 | 101 | /** 102 | * Method for executing HttpRequests asynchronously. 103 | * @param urlString String URL endpoint. 104 | * @param method {@link com.simplegeo.client.SimpleGeoClient.HttpRequestMethod} 105 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 106 | * @param jsonPayload String A string with the json that will be sent with the request. 107 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the SimpleGeoCallback interface 108 | * @throws ClientProtocolException 109 | * @throws IOException 110 | */ 111 | protected void execute(String urlString, final HttpRequestMethod method, HashMap queryParams, final String jsonPayload, final SimpleGeoCallback callback) throws ClientProtocolException, IOException { 112 | 113 | final String finalUrlString = urlString + this.buildQueryString(queryParams); 114 | 115 | threadExecutor.execute(new Thread() { 116 | @Override 117 | public void run() { 118 | String response = ""; 119 | try { 120 | response = httpClient.executeOAuthRequest(finalUrlString, method, jsonPayload, new SimpleGeoHandler()); 121 | } catch (OAuthMessageSignerException e) { 122 | callback.onError(e.getMessage()); 123 | } catch (OAuthExpectationFailedException e) { 124 | callback.onError(e.getMessage()); 125 | } catch (OAuthCommunicationException e) { 126 | callback.onError(e.getMessage()); 127 | } catch (IOException e) { 128 | callback.onError(e.getMessage()); 129 | } 130 | callback.onSuccess(response); 131 | } 132 | }); 133 | } 134 | 135 | /** 136 | * Method called when AuthorizationExceptions are raised during execute. 137 | * @param e 138 | * @throws APIException 139 | */ 140 | protected void dealWithAuthorizationException(Exception e) throws APIException { 141 | e.printStackTrace(); 142 | throw new APIException(SimpleGeoHandler.NOT_AUTHORIZED, e.getMessage()); 143 | } 144 | 145 | /** 146 | * Return the OAuthHttpClient 147 | */ 148 | public OAuthClient getHttpClient() { 149 | return httpClient; 150 | } 151 | 152 | // Common API endpoints 153 | 154 | /** 155 | * Synchronously retrieve a SimpleGeo feature. 156 | * 157 | * @param simpleGeoId String corresponding to an existing place. 158 | * @return String 159 | * @throws IOException 160 | * @throws ClientProtocolException 161 | */ 162 | public String getFeature(String simpleGeoId) throws ClientProtocolException, IOException { 163 | return this.execute(String.format(Locale.US, this.getEndpoint("features"), URLEncoder.encode(simpleGeoId, "UTF-8")), HttpRequestMethod.GET, null, ""); 164 | } 165 | 166 | /** 167 | * Asynchronously retrieve a SimpleGeo feature. 168 | * 169 | * @param simpleGeoId String corresponding to an existing place. 170 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 171 | * @throws IOException 172 | * @throws ClientProtocolException 173 | */ 174 | public void getFeature(String simpleGeoId, SimpleGeoCallback callback) throws ClientProtocolException, IOException { 175 | this.execute(String.format(Locale.US, this.getEndpoint("features"), URLEncoder.encode(simpleGeoId, "UTF-8")), HttpRequestMethod.GET, null, "", callback); 176 | } 177 | 178 | /** 179 | * Synchronously retrieve a SimpleGeo feature's annotations. 180 | * 181 | * @param simpleGeoId String corresponding to an existing place. 182 | * @return String 183 | * @throws IOException 184 | * @throws ClientProtocolException 185 | */ 186 | public String getFeatureAnnotations(String simpleGeoId) throws ClientProtocolException, IOException { 187 | return this.execute(String.format(Locale.US, this.getEndpoint("annotations"), simpleGeoId), HttpRequestMethod.GET, null, ""); 188 | } 189 | 190 | /** 191 | * Asynchronously retrieve a SimpleGeo feature's annotations. 192 | * 193 | * @param simpleGeoId String corresponding to an existing place. 194 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 195 | * @throws IOException 196 | * @throws ClientProtocolException 197 | */ 198 | public void getFeatureAnnotations(String simpleGeoId, SimpleGeoCallback callback) throws ClientProtocolException, IOException { 199 | this.execute(String.format(Locale.US, this.getEndpoint("annotations"), simpleGeoId), HttpRequestMethod.GET, null, "", callback); 200 | } 201 | 202 | /** 203 | * Synchronously retrieve a SimpleGeo feature's annotations. 204 | * 205 | * @param simpleGeoId String corresponding to an existing place. 206 | * @param annotation {@link Annotation}. 207 | * @return String 208 | * @throws IOException 209 | * @throws ClientProtocolException 210 | * @throws JSONException 211 | */ 212 | public String setFeatureAnnotations(String simpleGeoId, Annotation annotation) throws ClientProtocolException, IOException, JSONException { 213 | return this.execute(String.format(Locale.US, this.getEndpoint("annotations"), simpleGeoId), HttpRequestMethod.POST, null, annotation.toJSONString()); 214 | } 215 | 216 | /** 217 | * Asynchronously retrieve a SimpleGeo feature's annotations. 218 | * 219 | * @param simpleGeoId String corresponding to an existing place. 220 | * @param annotation {@link Annotation}. 221 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 222 | * @throws IOException 223 | * @throws ClientProtocolException 224 | * @throws JSONException 225 | */ 226 | public void setFeatureAnnotations(String simpleGeoId, Annotation annotation, SimpleGeoCallback callback) throws ClientProtocolException, IOException, JSONException { 227 | this.execute(String.format(Locale.US, this.getEndpoint("annotations"), simpleGeoId), HttpRequestMethod.POST, null, annotation.toJSONString(), callback); 228 | } 229 | 230 | // Util methods 231 | 232 | private String buildQueryString(HashMap params) throws UnsupportedEncodingException { 233 | if (params == null || params.size() == 0) { return ""; } 234 | Set> entries = params.entrySet(); 235 | StringBuffer queryBuffer = new StringBuffer("?"); 236 | for (Entry entry : entries) { 237 | for (String value : entry.getValue()) { 238 | if (queryBuffer.length() > 1) { queryBuffer.append("&"); } 239 | queryBuffer.append(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8")); 240 | } 241 | } 242 | return queryBuffer.toString(); 243 | } 244 | 245 | /** 246 | * Grab the desired endpoint and add it to the server and version. 247 | * @param endpointName 248 | * @return String A URL pointing at the desired server 249 | */ 250 | protected String getEndpoint(String endpointName) { 251 | return String.format(Locale.US, "%s/%s", HOST, endpoints.get(endpointName)); 252 | } 253 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/SimpleGeoClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import com.simplegeo.client.http.OAuthClient; 4 | 5 | public interface SimpleGeoClient { 6 | 7 | public static final String HOST = "https://api.simplegeo.com"; 8 | public static final int PORT = 443; 9 | 10 | static public enum Handler { JSON, GEOJSON, SIMPLEGEO } 11 | static public enum HttpRequestMethod { GET, POST, PUT, DELETE } 12 | 13 | /** 14 | * @return the Http client used to execute all requests 15 | */ 16 | public OAuthClient getHttpClient(); 17 | 18 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/SimpleGeoContextClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.net.URLEncoder; 5 | import java.util.HashMap; 6 | import java.util.Locale; 7 | 8 | import com.simplegeo.client.callbacks.SimpleGeoCallback; 9 | import com.simplegeo.client.http.OAuthClient; 10 | 11 | 12 | /** 13 | * Class for interacting with the SimpleGeo Context API. 14 | * 15 | * @author Casey Crites 16 | */ 17 | 18 | public class SimpleGeoContextClient extends AbstractSimpleGeoClient { 19 | 20 | /** 21 | * {@link com.simplegeo.client.SimpleGeoContextClient} constructor 22 | */ 23 | public SimpleGeoContextClient() { 24 | super(); 25 | 26 | endpoints.put("address", "1.0/context/address.json?address=%s"); 27 | endpoints.put("context", "1.0/context/%f,%f.json"); 28 | endpoints.put("ip", "1.0/context/%s.json"); 29 | endpoints.put("myIp", "1.0/context/ip.json"); 30 | endpoints.put("boundingBox", "1.0/context/%f,%f,%f,%f.json"); 31 | endpoints.put("searchDemographics", "1.0/context/demographics/search.json"); 32 | } 33 | 34 | /** 35 | * Synchronously get context for the given latitude and longitude. 36 | * 37 | * https://simplegeo.com/docs/api-endpoints/simplegeo-context 38 | * 39 | * @param lat double latitude 40 | * @param lon double longitude 41 | * @param queryParams HashMap 42 | * @return String 43 | * @throws IOException 44 | */ 45 | public String getContext(double lat, double lon, HashMap queryParams) throws IOException { 46 | return this.execute(String.format(Locale.US, this.getEndpoint("context"), lat, lon), HttpRequestMethod.GET, queryParams, ""); 47 | } 48 | 49 | /** 50 | * Asynchronously get context for the given latitude and longitude. 51 | * 52 | * @param lat double latitude 53 | * @param lon double longitude 54 | * @param queryParams HashMap 55 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 56 | * @throws IOException 57 | */ 58 | public void getContext(double lat, double lon, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 59 | this.execute(String.format(Locale.US, this.getEndpoint("context"), lat, lon), HttpRequestMethod.GET, null, "", callback); 60 | } 61 | 62 | /** 63 | * Synchronously get context for a specific IP. 64 | * 65 | * @param ip String IP Address If blank, your IP address will be used 66 | * @param queryParams HashMap 67 | * @return String 68 | * @throws IOException 69 | */ 70 | public String getContextByIP(String ip, HashMap queryParams) throws IOException { 71 | if (ip == null || "".equals(ip)) { return this.getContextByIP(queryParams); } 72 | return this.execute(String.format(Locale.US, this.getEndpoint("ip"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 73 | } 74 | 75 | /** 76 | * Asynchronously get context for a specific IP. 77 | * 78 | * @param ip String IP Address If blank, your IP address will be used 79 | * @param queryParams HashMap 80 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 81 | * @throws IOException 82 | */ 83 | public void getContextByIP(String ip, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 84 | if (ip == null || "".equals(ip)) { 85 | this.getContextByIP(queryParams, callback); 86 | } else { 87 | this.execute(String.format(Locale.US, this.getEndpoint("ip"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 88 | } 89 | } 90 | 91 | /** 92 | * Synchronously get context for your IP. 93 | * 94 | * @param queryParams HashMap 95 | * @return String containing weather, features, demographics and query 96 | * @throws IOException 97 | */ 98 | public String getContextByIP(HashMap queryParams) throws IOException { 99 | return this.execute(this.getEndpoint("myIp"), HttpRequestMethod.GET, queryParams, ""); 100 | } 101 | 102 | /** 103 | * Asynchronously get context for your IP. 104 | * 105 | * @param queryParams HashMap 106 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 107 | * @throws IOException 108 | */ 109 | public void getContextByIP(HashMap queryParams, SimpleGeoCallback callback) throws IOException { 110 | this.execute(this.getEndpoint("myIp"), HttpRequestMethod.GET, queryParams, "", callback); 111 | } 112 | 113 | /** 114 | * Synchronously get context for a physical street address. 115 | * 116 | * @param address String Physical street address 117 | * @param queryParams HashMap 118 | * @return HashMap HashMap containing weather, features, demographics and query 119 | * @throws IOException 120 | */ 121 | public String getContextByAddress(String address, HashMap queryParams) throws IOException { 122 | return this.execute(String.format(Locale.US, this.getEndpoint("address"), URLEncoder.encode(address, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 123 | } 124 | 125 | /** 126 | * Asynchronously get context for a physical street address. 127 | * 128 | * @param address String Physical street address 129 | * @param queryParams HashMap 130 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 131 | * @throws IOException 132 | */ 133 | public void getContextByAddress(String address, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 134 | this.execute(String.format(Locale.US, this.getEndpoint("address"), URLEncoder.encode(address, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 135 | } 136 | 137 | /** 138 | * Synchronously get context for the given bounding box. 139 | * 140 | * https://simplegeo.com/docs/api-endpoints/simplegeo-context 141 | * 142 | * @param nwLat double Northwest corner latitude 143 | * @param nwLon double Northwest corner longitude 144 | * @param seLat double Southeast corner latitude 145 | * @param seLon double Southeast corner longitude 146 | * @param queryParams HashMap 147 | * @return String 148 | * @throws IOException 149 | */ 150 | public String getContextByBoundingBox(double nwLat, double nwLon, double seLat, double seLon, HashMap queryParams) throws IOException { 151 | return this.execute(String.format(Locale.US, this.getEndpoint("boundingBox"), nwLat, nwLon, seLat, seLon), HttpRequestMethod.GET, queryParams, ""); 152 | } 153 | 154 | /** 155 | * Asynchronously get context for the given bounding box. 156 | * 157 | * https://simplegeo.com/docs/api-endpoints/simplegeo-context 158 | * 159 | * @param nwLat double Northwest corner latitude 160 | * @param nwLon double Northwest corner longitude 161 | * @param seLat double Southeast corner latitude 162 | * @param seLon double Southeast corner longitude 163 | * @param queryParams HashMap 164 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 165 | * @throws IOException 166 | */ 167 | public void getContextByBoundingBox(double nwLat, double nwLon, double seLat, double seLon, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 168 | this.execute(String.format(Locale.US, this.getEndpoint("boundingBox"), nwLat, nwLon, seLat, seLon), HttpRequestMethod.GET, null, "", callback); 169 | } 170 | 171 | /** 172 | * Synchronously search demographics. 173 | * 174 | * https://simplegeo.com/docs/api-endpoints/simplegeo-context#demographics 175 | * 176 | * @param queryParams HashMap 177 | * @return String 178 | * @throws IOException 179 | */ 180 | public String searchDemographics(HashMap queryParams) throws IOException { 181 | return this.execute(String.format(Locale.US, this.getEndpoint("searchDemographics")), HttpRequestMethod.GET, queryParams, ""); 182 | } 183 | 184 | /** 185 | * Asynchronously search demographics. 186 | * 187 | * https://simplegeo.com/docs/api-endpoints/simplegeo-context#demographics 188 | * 189 | * @param queryParams HashMap 190 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 191 | * @throws IOException 192 | */ 193 | public void searchDemographics(HashMap queryParams, SimpleGeoCallback callback) throws IOException { 194 | this.execute(String.format(Locale.US, this.getEndpoint("searchDemographics")), HttpRequestMethod.GET, queryParams, "", callback); 195 | } 196 | 197 | @Override 198 | public OAuthClient getHttpClient() { 199 | return super.getHttpClient(); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/SimpleGeoPlaces12Client.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.net.URLEncoder; 5 | import java.util.HashMap; 6 | import java.util.Locale; 7 | 8 | import com.simplegeo.client.callbacks.SimpleGeoCallback; 9 | 10 | /** 11 | * Class for interacting with the SimpleGeo Places 1.2 API. 12 | * 13 | * @author Casey Crites 14 | */ 15 | 16 | public class SimpleGeoPlaces12Client extends AbstractSimpleGeoClient { 17 | 18 | /** 19 | * {@link com.simplegeo.client.SimpleGeoPlacesClient} constructor 20 | * 21 | */ 22 | public SimpleGeoPlaces12Client() { 23 | super(); 24 | 25 | endpoints.put("address12", "1.2/places/address.json"); 26 | endpoints.put("search12", "1.2/places/%f,%f.json"); 27 | endpoints.put("searchNonGeo", "1.2/places/search.json"); 28 | endpoints.put("searchByIP12", "1.2/places/%s.json"); 29 | endpoints.put("searchByMyIP12", "1.2/places/ip.json"); 30 | endpoints.put("searchByBoundingBox", "1.2/places/%f,%f,%f,%f.json"); 31 | } 32 | 33 | /** 34 | * Synchronously search for nearby places. 35 | * 36 | * @param lat double latitude 37 | * @param lon double longitude 38 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 39 | * @return String JSON string that can be converted to a {@link com.simplegeo.client.types.FeatureCollection} containing search results. 40 | * @throws IOException 41 | */ 42 | public String search(double lat, double lon, HashMap queryParams) throws IOException { 43 | return this.execute(String.format(Locale.US, this.getEndpoint("search12"), lat, lon), HttpRequestMethod.GET, queryParams, ""); 44 | } 45 | 46 | /** 47 | * Asynchronously search for nearby places. 48 | * 49 | * @param lat Double latitude 50 | * @param lon double longitude 51 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 52 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 53 | * @throws IOException 54 | */ 55 | public void search(double lat, double lon, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 56 | this.execute(String.format(Locale.US, this.getEndpoint("search12"), lat, lon), HttpRequestMethod.GET, queryParams, "", callback); 57 | } 58 | 59 | /** 60 | * Synchronously search for places. 61 | * 62 | * @param query String Search phrase. 63 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 64 | * @return String JSON string that can be converted to a {@link com.simplegeo.client.types.FeatureCollection} containing search results. 65 | * @throws IOException 66 | */ 67 | public String search(String query, HashMap queryParams) throws IOException { 68 | if (queryParams == null) queryParams = new HashMap(); 69 | queryParams.put("q", new String[] { query }); 70 | return this.execute(String.format(Locale.US, this.getEndpoint("searchNonGeo")), HttpRequestMethod.GET, queryParams, ""); 71 | } 72 | 73 | /** 74 | * Asynchronously search for places. 75 | * 76 | * @param query String Search phrase. 77 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 78 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 79 | * @throws IOException 80 | */ 81 | public void search(String query, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 82 | if (queryParams == null) queryParams = new HashMap(); 83 | queryParams.put("q", new String[] { query }); 84 | this.execute(String.format(Locale.US, this.getEndpoint("searchNonGeo")), HttpRequestMethod.GET, queryParams, "", callback); 85 | } 86 | 87 | /** 88 | * Synchronously search by a physical address. 89 | * 90 | * @param address String Physical address, such as 41 Decatur St, San Francisco, CA 91 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 92 | * @return String JSON string that can be converted to a {@link com.simplegeo.client.types.FeatureCollection} containing search results. 93 | * @throws IOException 94 | */ 95 | public String searchByAddress(String address, HashMap queryParams) throws IOException { 96 | if (queryParams == null) queryParams = new HashMap(); 97 | queryParams.put("address", new String[] {address}); 98 | return this.execute(this.getEndpoint("address12"), HttpRequestMethod.GET, queryParams, ""); 99 | } 100 | 101 | /** 102 | * Asynchronously search by a physical address. 103 | * 104 | * @param address Physical address, such as 41 Decatur St, San Francisco, CA 105 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 106 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 107 | * @throws IOException 108 | */ 109 | public void searchByAddress(String address, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 110 | if (queryParams == null) queryParams = new HashMap(); 111 | queryParams.put("address", new String[] {address}); 112 | this.execute(this.getEndpoint("address12"), HttpRequestMethod.GET, queryParams, "", callback); 113 | } 114 | 115 | /** 116 | * Synchronously search by a specific IP. 117 | * 118 | * @param ip String IP address If blank, your IP address will be used 119 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 120 | * @return String JSON string that can be converted to a {@link com.simplegeo.client.types.FeatureCollection} containing search results. 121 | * @throws IOException 122 | */ 123 | public String searchByIP(String ip, HashMap queryParams) throws IOException { 124 | if (ip == null || "".equals(ip)) return this.searchByIP(queryParams); 125 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByIP12"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 126 | } 127 | 128 | /** 129 | * Asynchronously search by a specific IP. 130 | * 131 | * @param ip String IP address If blank, your IP address will be used 132 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 133 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 134 | * @throws IOException 135 | */ 136 | public void searchByIP(String ip, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 137 | if (ip == null || "".equals(ip)) { 138 | this.searchByIP(queryParams, callback); 139 | } else { 140 | this.execute(String.format(Locale.US, this.getEndpoint("searchByIP12"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 141 | } 142 | } 143 | 144 | /** 145 | * Synchronously search by your IP. 146 | * 147 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 148 | * @return String JSON string that can be converted to a {@link com.simplegeo.client.types.FeatureCollection} containing search results. 149 | * @throws IOException 150 | */ 151 | public String searchByIP(HashMap queryParams) throws IOException { 152 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByMyIP12")), HttpRequestMethod.GET, queryParams, ""); 153 | } 154 | 155 | /** 156 | * Asynchronously search by your IP. 157 | * 158 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 159 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 160 | * @throws IOException 161 | */ 162 | public void searchByIP(HashMap queryParams, SimpleGeoCallback callback) throws IOException { 163 | this.execute(String.format(Locale.US, this.getEndpoint("searchByMyIP12")), HttpRequestMethod.GET, queryParams, "", callback); 164 | } 165 | 166 | /** 167 | * Synchronously search for places in a bounding box. 168 | * 169 | * @param nwLat double Northwest corner latitude 170 | * @param nwLon double Northwest corner longitude 171 | * @param seLat double Southeast corner latitude 172 | * @param seLon double Southeast corner longitude 173 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 174 | * @return String JSON string that can be converted to a {@link com.simplegeo.client.types.FeatureCollection} containing search results. 175 | * @throws IOException 176 | */ 177 | public String searchByBoundingBox(double nwLat, double nwLon, double seLat, double seLon, HashMap queryParams) throws IOException { 178 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByBoundingBox"), nwLat, nwLon, seLat, seLon), HttpRequestMethod.GET, queryParams, null); 179 | } 180 | 181 | /** 182 | * Asynchronously search for places in a bounding box. 183 | * 184 | * @param nwLat double Northwest corner latitude 185 | * @param nwLon double Northwest corner longitude 186 | * @param seLat double Southeast corner latitude 187 | * @param seLon double Southeast corner longitude 188 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 189 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 190 | * @throws IOException 191 | */ 192 | public void searchByBoundingBox(double nwLat, double nwLon, double seLat, double seLon, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 193 | this.execute(String.format(Locale.US, this.getEndpoint("searchByBoundingBox"), nwLat, nwLon, seLat, seLon), HttpRequestMethod.GET, queryParams, null, callback); 194 | } 195 | 196 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/SimpleGeoPlacesClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.net.URLEncoder; 5 | import java.util.HashMap; 6 | import java.util.Locale; 7 | 8 | import org.json.JSONException; 9 | 10 | import com.simplegeo.client.callbacks.SimpleGeoCallback; 11 | import com.simplegeo.client.http.OAuthClient; 12 | import com.simplegeo.client.types.Feature; 13 | 14 | /** 15 | * Class for interacting with the SimpleGeo Places API. 16 | * 17 | * @author Casey Crites 18 | */ 19 | 20 | public class SimpleGeoPlacesClient extends AbstractSimpleGeoClient { 21 | 22 | /** 23 | * {@link com.simplegeo.client.SimpleGeoPlacesClient} constructor 24 | * 25 | */ 26 | public SimpleGeoPlacesClient() { 27 | super(); 28 | 29 | endpoints.put("categories", "1.0/features/categories.json"); 30 | endpoints.put("address", "1.0/places/address.json"); 31 | endpoints.put("places", "1.0/places"); 32 | endpoints.put("delete", "1.0/features/%s.json"); 33 | endpoints.put("search", "1.0/places/%f,%f.json"); 34 | endpoints.put("searchByIP", "1.0/places/%s.json"); 35 | endpoints.put("searchByMyIP", "1.0/places/ip.json"); 36 | } 37 | 38 | /** 39 | * Synchronously get a list of all the possible Feature categories 40 | * 41 | * @return String containing a JSONArray of categories 42 | */ 43 | public String getCategories() throws IOException{ 44 | return this.execute(this.getEndpoint("categories"), HttpRequestMethod.GET, null, ""); 45 | } 46 | 47 | /** 48 | * Asynchronously get a list of all the possible Feature categories 49 | * 50 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 51 | */ 52 | public void getCategories(SimpleGeoCallback callback) throws IOException{ 53 | this.execute(this.getEndpoint("categories"), HttpRequestMethod.GET, null, "", callback); 54 | } 55 | 56 | /** 57 | * Synchronously add a new place to the places database 58 | * 59 | * @param feature {@link com.simplegeo.client.types.Feature} representing a new place. 60 | * @return String containing a polling token, simplegeoid and a uri. 61 | * @throws IOException 62 | * @throws JSONException 63 | */ 64 | public String addPlace(Feature feature) throws IOException, JSONException { 65 | return this.execute(String.format(Locale.US, this.getEndpoint("places")), HttpRequestMethod.POST, null, feature.toJSONString()); 66 | } 67 | 68 | /** 69 | * Asynchronously add a new place to the places database 70 | * 71 | * @param feature {@link com.simplegeo.client.types.Feature} representing a new place. 72 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 73 | * @throws IOException 74 | * @throws JSONException 75 | */ 76 | public void addPlace(Feature feature, SimpleGeoCallback callback) throws IOException, JSONException { 77 | this.execute(String.format(Locale.US, this.getEndpoint("places")), HttpRequestMethod.POST, null, feature.toJSONString(), callback); 78 | } 79 | 80 | /** 81 | * Synchronously update an existing place in the places database. 82 | * 83 | * @param feature {@link com.simplegeo.client.types.Feature} representing an existing place. 84 | * @return String containing a polling token. 85 | * @throws IOException 86 | * @throws JSONException 87 | */ 88 | public String updatePlace(Feature feature) throws IOException, JSONException { 89 | return this.execute(String.format(Locale.US, this.getEndpoint("places"), URLEncoder.encode(feature.getSimpleGeoId(), "UTF-8")), HttpRequestMethod.POST, null, feature.toJSONString()); 90 | } 91 | 92 | /** 93 | * Asynchronously update an existing place in the places database. 94 | * 95 | * @param feature {@link com.simplegeo.client.types.Feature} representing an existing place. 96 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 97 | * @throws IOException 98 | * @throws JSONException 99 | */ 100 | public void updatePlace(Feature feature, SimpleGeoCallback callback) throws IOException, JSONException { 101 | this.execute(String.format(Locale.US, this.getEndpoint("places"), URLEncoder.encode(feature.getSimpleGeoId(), "UTF-8")), HttpRequestMethod.POST, null, feature.toJSONString(), callback); 102 | } 103 | 104 | /** 105 | * Synchronously delete an existing place from the places database. 106 | * 107 | * @param simpleGeoId String corresponding to an existing place. 108 | * @return String containing a polling token. 109 | * @throws IOException 110 | */ 111 | public String deletePlace(String simpleGeoId) throws IOException { 112 | return this.execute(String.format(Locale.US, this.getEndpoint("delete"), URLEncoder.encode(simpleGeoId, "UTF-8")), HttpRequestMethod.DELETE, null, ""); 113 | } 114 | 115 | /** 116 | * Asynchronously delete an existing place from the places database. 117 | * 118 | * @param simpleGeoId String corresponding to an existing place. 119 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 120 | * @throws IOException 121 | */ 122 | public void deletePlace(String simpleGeoId, SimpleGeoCallback callback) throws IOException { 123 | this.execute(String.format(Locale.US, this.getEndpoint("delete"), URLEncoder.encode(simpleGeoId, "UTF-8")), HttpRequestMethod.DELETE, null, "", callback); 124 | } 125 | 126 | /** 127 | * Synchronously search for nearby places. 128 | * 129 | * @param lat double latitude 130 | * @param lon double longitude 131 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 132 | * @return {@link com.simplegeo.client.types.FeatureCollection} {@link com.simplegeo.client.types.FeatureCollection} containing search results. 133 | * @throws IOException 134 | */ 135 | public String search(double lat, double lon, HashMap queryParams) throws IOException { 136 | return this.execute(String.format(Locale.US, this.getEndpoint("search"), lat, lon), HttpRequestMethod.GET, queryParams, ""); 137 | } 138 | 139 | /** 140 | * Asynchronously search for nearby places. 141 | * 142 | * @param lat Double latitude 143 | * @param lon double longitude 144 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 145 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 146 | * @throws IOException 147 | */ 148 | public void search(double lat, double lon, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 149 | this.execute(String.format(Locale.US, this.getEndpoint("search"), lat, lon), HttpRequestMethod.GET, queryParams, "", callback); 150 | } 151 | 152 | /** 153 | * Synchronously search by a physical address. 154 | * 155 | * @param address String Physical address, such as 41 Decatur St, San Francisco, CA 156 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 157 | * @return {@link com.simplegeo.client.types.FeatureCollection} {@link com.simplegeo.client.types.FeatureCollection} containing search results. 158 | * @throws IOException 159 | */ 160 | public String searchByAddress(String address, HashMap queryParams) throws IOException { 161 | if (queryParams == null) { queryParams = new HashMap(); } 162 | queryParams.put("address", new String[] {address}); 163 | return this.execute(this.getEndpoint("address"), HttpRequestMethod.GET, queryParams, ""); 164 | } 165 | 166 | /** 167 | * Asynchronously search by a physical address. 168 | * 169 | * @param address Physical address, such as 41 Decatur St, San Francisco, CA 170 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 171 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 172 | * @throws IOException 173 | */ 174 | public void searchByAddress(String address, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 175 | if (queryParams == null) { queryParams = new HashMap(); } 176 | queryParams.put("address", new String[] {address}); 177 | this.execute(this.getEndpoint("address"), HttpRequestMethod.GET, queryParams, "", callback); 178 | } 179 | 180 | /** 181 | * Synchronously search by a specific IP. 182 | * 183 | * @param ip String IP address If blank, your IP address will be used 184 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 185 | * @return {@link com.simplegeo.client.types.FeatureCollection} {@link com.simplegeo.client.types.FeatureCollection} containing search results. 186 | * @throws IOException 187 | */ 188 | public String searchByIP(String ip, HashMap queryParams) throws IOException { 189 | if (ip == null || "".equals(ip)) { return this.searchByIP(queryParams); } 190 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByIP"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 191 | } 192 | 193 | /** 194 | * Asynchronously search by a specific IP. 195 | * 196 | * @param ip String IP address If blank, your IP address will be used 197 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 198 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 199 | * @throws IOException 200 | */ 201 | public void searchByIP(String ip, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 202 | if (ip == null || "".equals(ip)) { 203 | this.searchByIP(queryParams, callback); 204 | } else { 205 | this.execute(String.format(Locale.US, this.getEndpoint("searchByIP"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 206 | } 207 | } 208 | 209 | /** 210 | * Synchronously search by your IP. 211 | * 212 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 213 | * @return {@link com.simplegeo.client.types.FeatureCollection} {@link com.simplegeo.client.types.FeatureCollection} containing search results. 214 | * @throws IOException 215 | */ 216 | public String searchByIP(HashMap queryParams) throws IOException { 217 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByMyIP")), HttpRequestMethod.GET, queryParams, ""); 218 | } 219 | 220 | /** 221 | * Asynchronously search by your IP. 222 | * 223 | * @param queryParams HashMap Extra parameters to put in the query string such as, radius, q and category. 224 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 225 | * @throws IOException 226 | */ 227 | public void searchByIP(HashMap queryParams, SimpleGeoCallback callback) throws IOException { 228 | this.execute(String.format(Locale.US, this.getEndpoint("searchByMyIP")), HttpRequestMethod.GET, queryParams, "", callback); 229 | } 230 | 231 | @Override 232 | public OAuthClient getHttpClient() { 233 | return super.getHttpClient(); 234 | } 235 | 236 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/SimpleGeoStorageClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.net.URLEncoder; 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.Locale; 8 | 9 | import org.json.JSONException; 10 | 11 | import com.simplegeo.client.callbacks.SimpleGeoCallback; 12 | import com.simplegeo.client.http.OAuthClient; 13 | import com.simplegeo.client.types.Layer; 14 | import com.simplegeo.client.types.Record; 15 | 16 | /* 17 | * Class for interacting with the SimpleGeo Storage API. 18 | * 19 | * @author Pranil Kanderi 20 | */ 21 | public class SimpleGeoStorageClient extends AbstractSimpleGeoClient { 22 | 23 | /** 24 | * {@link com.simplegeo.client.SimpleGeoStorageClient} constructor 25 | */ 26 | public SimpleGeoStorageClient() { 27 | super(); 28 | 29 | endpoints.put("singleRecord", "0.1/records/%s/%s.json"); 30 | endpoints.put("multipleRecords", "0.1/records/%s.json"); 31 | endpoints.put("history", "0.1/records/%s/%s/history.json"); 32 | endpoints.put("searchByLatLon", "0.1/records/%s/nearby/%f,%f.json"); 33 | endpoints.put("searchByAddress", "0.1/records/%s/nearby/address.json"); 34 | endpoints.put("searchByIP", "0.1/records/%s/nearby/%s.json"); 35 | endpoints.put("searchByMyIP", "0.1/records/%s/nearby/ip.json"); 36 | endpoints.put("layer", "0.1/layers/%s.json"); 37 | endpoints.put("allLayers", "0.1/layers.json"); 38 | } 39 | 40 | /** 41 | * Synchronously add a new record to the storage database 42 | * 43 | * @param record {@link com.simplegeo.client.types.Record} representing a new Record to be added to storage. 44 | * @throws IOException 45 | * @throws JSONException 46 | */ 47 | public void addOrUpdateRecord(Record record) throws IOException, JSONException { 48 | this.execute(String.format(Locale.US, this.getEndpoint("singleRecord"), URLEncoder.encode(record.getLayer(), "UTF-8"), URLEncoder.encode(record.getRecordId(), "UTF-8")), HttpRequestMethod.PUT, null, record.toJSONString()); 49 | } 50 | 51 | /** 52 | * Asynchronously add a new record to the storage database 53 | * 54 | * @param record {@link com.simplegeo.client.types.Record} representing a new Record to be added to storage. 55 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 56 | * @throws IOException 57 | * @throws JSONException 58 | */ 59 | public void addOrUpdateRecord(Record record, SimpleGeoCallback callback) throws IOException, JSONException { 60 | this.execute(String.format(Locale.US, this.getEndpoint("singleRecord"), URLEncoder.encode(record.getLayer(), "UTF-8"), URLEncoder.encode(record.getRecordId(), "UTF-8")), HttpRequestMethod.PUT, null, record.toJSONString(), callback); 61 | } 62 | 63 | 64 | /** 65 | * Synchronously adds multiple records to the storage database 66 | * 67 | * @param records ArrayList of {@link com.simplegeo.client.types.Record}s to be added to storage. 68 | * @throws IOException 69 | * @throws JSONException 70 | */ 71 | public void addOrUpdateRecords(ArrayList records, String layer) throws IOException, JSONException { 72 | this.execute(String.format(Locale.US, this.getEndpoint("multipleRecords"), URLEncoder.encode(layer, "UTF-8")), HttpRequestMethod.POST, null, Record.toJSONString(records)); 73 | } 74 | 75 | /** 76 | * Asynchronously adds multiple records to the storage database 77 | * 78 | * @param records ArrayList of {@link com.simplegeo.client.types.Record}s to be added to storage. 79 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 80 | * @throws IOException 81 | * @throws JSONException 82 | */ 83 | public void addOrUpdateRecords(ArrayList records, String layer, SimpleGeoCallback callback) throws IOException, JSONException { 84 | this.execute(String.format(Locale.US, this.getEndpoint("multipleRecords"), URLEncoder.encode(layer, "UTF-8")), HttpRequestMethod.POST, null, Record.toJSONString(records), callback); 85 | } 86 | 87 | /** 88 | * Synchronously get the record that corresponds to the recordId 89 | * 90 | * @param layer String name of the layer 91 | * @param recordId String id of this record 92 | * @return String Json string that can be converted to a {@link com.simplegeo.client.types.Record} with the specified recordId and layer 93 | * @throws IOException 94 | */ 95 | public String getRecord(String layer, String recordId) throws IOException { 96 | return this.execute(String.format(Locale.US, this.getEndpoint("singleRecord"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(recordId, "UTF-8")), HttpRequestMethod.GET, null, ""); 97 | } 98 | 99 | /** 100 | * Asynchronously get the record that corresponds to the recordId 101 | * 102 | * @param layer String name of the layer 103 | * @param recordId String id of this record 104 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 105 | * @throws IOException 106 | */ 107 | public void getRecord(String layer, String recordId, SimpleGeoCallback callback) throws IOException { 108 | this.execute(String.format(Locale.US, this.getEndpoint("singleRecord"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(recordId, "UTF-8")), HttpRequestMethod.GET, null, "", callback); 109 | } 110 | 111 | /** 112 | * Synchronously delete the record that corresponds to the recordId 113 | * 114 | * @param layer String name of the layer 115 | * @param recordId String id of this record 116 | * @throws IOException 117 | */ 118 | public String deleteRecord(String layer, String recordId) throws IOException { 119 | return this.execute(String.format(Locale.US, this.getEndpoint("singleRecord"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(recordId, "UTF-8")), HttpRequestMethod.DELETE, null, ""); 120 | } 121 | 122 | /** 123 | * Asynchronously delete the record that corresponds to the recordId 124 | * 125 | * @param layer String name of the layer 126 | * @param recordId String id of this record 127 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 128 | * @throws IOException 129 | */ 130 | public void deleteRecord(String layer, String recordId, SimpleGeoCallback callback) throws IOException { 131 | this.execute(String.format(Locale.US, this.getEndpoint("singleRecord"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(recordId, "UTF-8")), HttpRequestMethod.DELETE, null, "", callback); 132 | } 133 | 134 | /** 135 | * Synchronously get the history of the record that corresponds to the recordId 136 | * 137 | * @param layer String name of the layer 138 | * @param recordId String id of this record 139 | * @param queryParams HashMap Extra parameters to put in the query string such as limit and cursor. 140 | * @return String representing the history of record with the specified recordId and layer. 141 | * @throws IOException 142 | */ 143 | public String getHistory(String layer, String recordId, HashMap queryParams) throws IOException { 144 | return this.execute(String.format(Locale.US, this.getEndpoint("history"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(recordId, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 145 | } 146 | 147 | /** 148 | * Asynchronously get the history of the record that corresponds to the recordId 149 | * 150 | * @param layer String name of the layer 151 | * @param recordId String id of this record 152 | * @param queryParams HashMap Extra parameters to put in the query string such as limit and cursor. 153 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 154 | * @throws IOException 155 | */ 156 | public void getHistory(String layer, String recordId, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 157 | this.execute(String.format(Locale.US, this.getEndpoint("history"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(recordId, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 158 | } 159 | 160 | 161 | /** 162 | * Synchronously search for nearby records in the specified layer. 163 | * 164 | * @param lat double latitude 165 | * @param lon double longitude 166 | * @param layer String name of the layer 167 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 168 | * @return String A JSON String containing search results. 169 | * @throws IOException 170 | */ 171 | public String search(double lat, double lon, String layer, HashMap queryParams) throws IOException { 172 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByLatLon"), URLEncoder.encode(layer, "UTF-8"), lat, lon), HttpRequestMethod.GET, queryParams, ""); 173 | } 174 | 175 | /** 176 | * Asynchronously search for nearby records in the specified layer. 177 | * 178 | * @param lat Double latitude 179 | * @param lon double longitude 180 | * @param layer String name of the layer 181 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 182 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 183 | * @throws IOException 184 | */ 185 | public void search(double lat, double lon, String layer, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 186 | this.execute(String.format(Locale.US, this.getEndpoint("searchByLatLon"), URLEncoder.encode(layer, "UTF-8"), lat, lon), HttpRequestMethod.GET, queryParams, "", callback); 187 | } 188 | 189 | /** 190 | * Synchronously search for records near a given address in the specified layer. 191 | * 192 | * @param address String address (41 Decatur St, San Francisco, CA) 193 | * @param layer String name of the layer 194 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 195 | * @return String A JSON String containing search results. 196 | * @throws IOException 197 | */ 198 | public String searchByAddress(String address, String layer, HashMap queryParams) throws IOException { 199 | if (queryParams == null) queryParams = new HashMap(); 200 | queryParams.put("address", new String[] { address }); 201 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByAddress"), URLEncoder.encode(layer, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 202 | } 203 | 204 | /** 205 | * Asynchronously search for records near a given address in the specified layer. 206 | * 207 | * @param address String address (41 Decatur St, San Francisco, CA) 208 | * @param layer String name of the layer 209 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 210 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 211 | * @throws IOException 212 | */ 213 | public void searchByAddress(String address, String layer, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 214 | if (queryParams == null) queryParams = new HashMap(); 215 | queryParams.put("address", new String[] { address }); 216 | this.execute(String.format(Locale.US, this.getEndpoint("searchByAddress"), URLEncoder.encode(layer, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 217 | } 218 | 219 | /** 220 | * Synchronously search for records near a given IP address for the specified layer. 221 | * 222 | * @param ip String IP address If blank, your IP address will be used 223 | * @param layer String name of the layer 224 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 225 | * @return String 226 | * @throws IOException 227 | */ 228 | public String searchByIP(String ip, String layer, HashMap queryParams) throws IOException { 229 | if (ip == null || "".equals(ip)) { return this.searchByMyIP(layer, queryParams); } 230 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByIP"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 231 | } 232 | 233 | /** 234 | * Asynchronously search for records near a given IP address for the specified layer. 235 | * 236 | * @param ip String IP address If blank, your IP address will be used 237 | * @param layer String name of the layer 238 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 239 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 240 | * @throws IOException 241 | */ 242 | public void searchByIP(String ip, String layer, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 243 | if (ip == null || "".equals(ip)) { 244 | this.searchByMyIP(layer, queryParams, callback); 245 | } else { 246 | this.execute(String.format(Locale.US, this.getEndpoint("searchByIP"), URLEncoder.encode(layer, "UTF-8"), URLEncoder.encode(ip, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 247 | } 248 | } 249 | 250 | /** 251 | * Synchronously search for records near a given IP address for the specified layer. 252 | * 253 | * @param layer String name of the layer 254 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 255 | * @return String 256 | * @throws IOException 257 | */ 258 | public String searchByMyIP(String layer, HashMap queryParams) throws IOException { 259 | return this.execute(String.format(Locale.US, this.getEndpoint("searchByMyIP"), URLEncoder.encode(layer, "UTF-8")), HttpRequestMethod.GET, queryParams, ""); 260 | } 261 | 262 | /** 263 | * Asynchronously search for records near a given IP address for the specified layer. 264 | * 265 | * @param layer String name of the layer 266 | * @param queryParams HashMap Extra parameters to put in the query string such as radius, limit and cursor. 267 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 268 | * @throws IOException 269 | */ 270 | public void searchByMyIP(String layer, HashMap queryParams, SimpleGeoCallback callback) throws IOException { 271 | this.execute(String.format(Locale.US, this.getEndpoint("searchByMyIP"), URLEncoder.encode(layer, "UTF-8")), HttpRequestMethod.GET, queryParams, "", callback); 272 | } 273 | 274 | /** 275 | * Synchronously create a new layer. 276 | * 277 | * @param layer {@link com.simplegeo.client.types.Layer} to be created 278 | * @return String containing the "status" 279 | * @throws IOException 280 | * @throws JSONException 281 | */ 282 | public String createLayer(Layer layer) throws IOException, JSONException { 283 | return this.execute(String.format(Locale.US, this.getEndpoint("layer"), URLEncoder.encode(layer.getName(), "UTF-8")), HttpRequestMethod.PUT, null, Layer.toJSONString(layer)); 284 | } 285 | 286 | /** 287 | * Asynchronously create a new layer. 288 | * 289 | * @param layer {@link com.simplegeo.client.types.Layer} to be created 290 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 291 | * @throws IOException 292 | * @throws JSONException 293 | */ 294 | public void createLayer(Layer layer, SimpleGeoCallback callback) throws IOException, JSONException { 295 | this.execute(String.format(Locale.US, this.getEndpoint("layer"), URLEncoder.encode(layer.getName(), "UTF-8")), HttpRequestMethod.PUT, null, Layer.toJSONString(layer), callback); 296 | } 297 | 298 | /** 299 | * Synchronously update a layer. 300 | * 301 | * @param layer {@link com.simplegeo.client.types.Layer} to be updated 302 | * @return String containing the "status" 303 | * @throws IOException 304 | * @throws JSONException 305 | */ 306 | public String updateLayer(Layer layer) throws IOException, JSONException { 307 | return createLayer(layer); 308 | } 309 | 310 | /** 311 | * Asynchronously update a layer. 312 | * 313 | * @param layer {@link com.simplegeo.client.types.Layer} to be updated 314 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 315 | * @throws IOException 316 | * @throws JSONException 317 | */ 318 | public void updateLayer(Layer layer, SimpleGeoCallback callback) throws IOException, JSONException { 319 | createLayer(layer, callback); 320 | } 321 | 322 | /** 323 | * Synchronously delete a layer. 324 | * 325 | * @param layerName String name of the layer to be deleted 326 | * @return String containing the "status" 327 | * @throws IOException 328 | */ 329 | public String deleteLayer(String layerName) throws IOException { 330 | return this.execute(String.format(Locale.US, this.getEndpoint("layer"), URLEncoder.encode(layerName, "UTF-8")), HttpRequestMethod.DELETE, null, ""); 331 | } 332 | 333 | /** 334 | * Asynchronously delete a layer. 335 | * 336 | * @param layerName String name of the layer to be deleted 337 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 338 | * @throws IOException 339 | */ 340 | public void deleteLayer(String layerName, SimpleGeoCallback callback) throws IOException { 341 | this.execute(String.format(Locale.US, this.getEndpoint("layer"), URLEncoder.encode(layerName, "UTF-8")), HttpRequestMethod.DELETE, null, "", callback); 342 | } 343 | 344 | /** 345 | * Synchronously retrieve a layer. 346 | * 347 | * @param layerName String name of the layer to be retrieved 348 | * @return {@link com.simplegeo.client.types.Layer} 349 | * @throws IOException 350 | */ 351 | public String getLayer(String layerName) throws IOException { 352 | return this.execute(String.format(Locale.US, this.getEndpoint("layer"), URLEncoder.encode(layerName, "UTF-8")), HttpRequestMethod.GET, null, ""); 353 | } 354 | 355 | /** 356 | * Asynchronously retrieve a layer. 357 | * 358 | * @param layerName String name of the layer to be retrieved 359 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 360 | * @throws IOException 361 | */ 362 | public void getLayer(String layerName, SimpleGeoCallback callback) throws IOException { 363 | this.execute(String.format(Locale.US, this.getEndpoint("layer"), URLEncoder.encode(layerName, "UTF-8")), HttpRequestMethod.GET, null, "", callback); 364 | } 365 | 366 | /** 367 | * Synchronously retrieve all layers. 368 | * 369 | * @param queryParams HashMap A HashMap of extra query parameters like limit and cursor. 370 | * @return {@link com.simplegeo.client.types.LayerCollection} 371 | * @throws IOException 372 | */ 373 | public String getLayers(HashMap queryParams) throws IOException { 374 | return this.execute(this.getEndpoint("allLayers"), HttpRequestMethod.GET, queryParams, ""); 375 | } 376 | 377 | /** 378 | * Asynchronously retrieve a layer. 379 | * 380 | * @param queryParams HashMap A HashMap of extra query parameters like limit and cursor. 381 | * @param callback {@link com.simplegeo.client.callbacks.SimpleGeoCallback} Any object implementing the {@link com.simplegeo.client.callbacks.SimpleGeoCallback} interface 382 | * @throws IOException 383 | */ 384 | public void getLayers(HashMap queryParams, SimpleGeoCallback callback) throws IOException { 385 | this.execute(this.getEndpoint("allLayers"), HttpRequestMethod.GET, queryParams, "", callback); 386 | } 387 | 388 | @Override 389 | public OAuthClient getHttpClient() { 390 | return super.getHttpClient(); 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/callbacks/SimpleGeoCallback.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.callbacks; 2 | 3 | public interface SimpleGeoCallback { 4 | 5 | public void onSuccess(String jsonString); 6 | 7 | public void onError(String errorMessage); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/concurrent/NamedThreadFactory.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.concurrent; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | /** 7 | * A simple subclass of {@link java.util.concurrent.ThreadFactory} that 8 | * is used by {@link com.simplegeo.client.concurrent.RequestThreadPoolExecutor}. 9 | * 10 | * @author Derek Smith 11 | */ 12 | public class NamedThreadFactory implements ThreadFactory 13 | { 14 | protected final String id; 15 | protected final AtomicInteger n = new AtomicInteger(1); 16 | 17 | /** 18 | * Creates a new ThreadFactory with a value that can be used 19 | * to retrieve itself later. 20 | * 21 | * @param id The name of the the thread factory; 22 | */ 23 | public NamedThreadFactory(String id) 24 | { 25 | super(); 26 | this.id = id; 27 | } 28 | 29 | /* (non-Javadoc) 30 | * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable) 31 | */ 32 | public Thread newThread(Runnable runnable) 33 | { 34 | String name = id + ":" + n.getAndIncrement(); 35 | return new Thread(runnable, name); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/concurrent/RequestThreadPoolExecutor.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.concurrent; 2 | 3 | import java.util.concurrent.BlockingQueue; 4 | import java.util.concurrent.LinkedBlockingQueue; 5 | import java.util.concurrent.ThreadFactory; 6 | import java.util.concurrent.ThreadPoolExecutor; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | /** 10 | * A simple subclass of {@link java.util.concurrent.ThreadPoolExecutor} that is used 11 | * mainly by {@link com.simplegeo.client.SimpleGeoClient} to do threaded HttpRequests. 12 | * 13 | * @author Derek Smith 14 | */ 15 | public class RequestThreadPoolExecutor extends ThreadPoolExecutor { 16 | 17 | /** 18 | * A default constructor that builds the object using 19 | * {@link NamedThreadFactory} 20 | * 21 | * @param name name of the {@link com.simplegeo.client.concurrent.NamedThreadFactory} 22 | */ 23 | public RequestThreadPoolExecutor(String name) { 24 | 25 | this(1, 8, Integer.MAX_VALUE, TimeUnit.SECONDS, 26 | new LinkedBlockingQueue(), new NamedThreadFactory(name)); 27 | 28 | } 29 | 30 | /** 31 | * Constructs a new {@link java.util.concurrent.ThreadPoolExecutor}. 32 | * 33 | * @param corePoolSize the minimum size of the thread pool 34 | * @param maximumPoolSize the maximum size of the thread pool 35 | * @param keepAliveTime the amount of time to keep the thread alive 36 | * @param unit time unit to associate with keepAliveTime parameter 37 | * @param workQueue @see java.util.concurrent.BlockingQueue 38 | * @param threadFactory @see java.util.concurrent.ThreadFactory 39 | */ 40 | public RequestThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, 41 | BlockingQueue workQueue, ThreadFactory threadFactory) { 42 | 43 | super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); 44 | 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/OAuthClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http; 2 | 3 | import java.io.IOException; 4 | 5 | import oauth.signpost.exception.OAuthCommunicationException; 6 | import oauth.signpost.exception.OAuthExpectationFailedException; 7 | import oauth.signpost.exception.OAuthMessageSignerException; 8 | 9 | import org.apache.http.client.ClientProtocolException; 10 | import org.apache.http.client.ResponseHandler; 11 | 12 | import com.simplegeo.client.SimpleGeoClient.HttpRequestMethod; 13 | 14 | /** 15 | * An interface that defines the only method of the OAuth clients that is used outside of the 16 | * response handler; the method that specifies the key & secret. This is needed because the client 17 | * that is based off of the URLConnection needs to use a different OAuth client. 18 | * 19 | * @author Mark Fogle 20 | */ 21 | 22 | public interface OAuthClient { 23 | 24 | /** 25 | * Set the key/secret pair that will be used to sign Http 26 | * requests. 27 | * 28 | * @param key the consumer key 29 | * @param secret the secret key 30 | */ 31 | public void setToken(String key, String secret); 32 | 33 | /** 34 | * Execute an OAuth request. 35 | * 36 | * @param urlString 37 | * @param method 38 | * @param jsonPayload 39 | * @param responseHandler 40 | * @return Object 41 | * @throws OAuthMessageSignerException 42 | * @throws OAuthCommunicationException 43 | * @throws OAuthExpectationFailedException 44 | * @throws ClientProtocolException 45 | * @throws IOException 46 | */ 47 | public String executeOAuthRequest(String urlString, HttpRequestMethod method, String jsonPayload, ResponseHandler responseHandler) 48 | throws OAuthMessageSignerException, OAuthCommunicationException, OAuthExpectationFailedException, ClientProtocolException, IOException; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/OAuthHttpClient.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http; 2 | 3 | import java.io.IOException; 4 | import java.util.Locale; 5 | import java.util.logging.Logger; 6 | 7 | import oauth.signpost.OAuthConsumer; 8 | import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; 9 | import oauth.signpost.exception.OAuthCommunicationException; 10 | import oauth.signpost.exception.OAuthExpectationFailedException; 11 | import oauth.signpost.exception.OAuthMessageSignerException; 12 | 13 | import org.apache.http.client.ClientProtocolException; 14 | import org.apache.http.client.ResponseHandler; 15 | import org.apache.http.client.methods.HttpDelete; 16 | import org.apache.http.client.methods.HttpGet; 17 | import org.apache.http.client.methods.HttpPost; 18 | import org.apache.http.client.methods.HttpPut; 19 | import org.apache.http.client.methods.HttpUriRequest; 20 | import org.apache.http.entity.ByteArrayEntity; 21 | import org.apache.http.impl.client.DefaultHttpClient; 22 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 23 | import org.apache.http.params.HttpParams; 24 | import org.apache.http.protocol.BasicHttpContext; 25 | import org.apache.http.protocol.HttpContext; 26 | import org.apache.http.protocol.SyncBasicHttpContext; 27 | 28 | import com.simplegeo.client.SimpleGeoClient.HttpRequestMethod; 29 | 30 | /** 31 | * A subclass of {@link org.apache.http.impl.client.DefaultHttpClient} 32 | * that signs requests using a given OAuth key and secret. 33 | * 34 | * @author Derek Smith 35 | */ 36 | public class OAuthHttpClient extends DefaultHttpClient implements OAuthClient { 37 | 38 | private static Logger logger = Logger.getLogger(OAuthHttpClient.class.getName()); 39 | private OAuthConsumer token; 40 | 41 | /** 42 | * @param connManager 43 | * @param params 44 | */ 45 | public OAuthHttpClient(ThreadSafeClientConnManager connManager, HttpParams params) { 46 | super(connManager, params); 47 | } 48 | 49 | /** 50 | * Returns the consumer key that is used to sign Http requests. 51 | * 52 | * @return the consumer key 53 | */ 54 | public String getKey() { 55 | return token.getConsumerKey(); 56 | } 57 | 58 | /** 59 | * Returns the consumer secret that is used to sign Http requests. 60 | * 61 | * @return the consumer secret 62 | */ 63 | public String getSecret() { 64 | return token.getConsumerSecret(); 65 | } 66 | 67 | /** 68 | * Set the key/secret pair that will be used to sign Http 69 | * requests. 70 | * 71 | * @param key the consumer key 72 | * @param secret the secret key 73 | */ 74 | public void setToken(String key, String secret) { 75 | if(key != null && secret != null) { 76 | token = new CommonsHttpOAuthConsumer(key, secret); 77 | if(token == null) 78 | logger.info(String.format(Locale.US, "Failed to created OAuth token.")); 79 | else 80 | logger.info(String.format(Locale.US, "Successfully created OAuth token.")); 81 | } 82 | } 83 | 84 | /** 85 | * Signs the Http request with the registered token before 86 | * execution. 87 | * 88 | * @param urlString The url that the request should be sent to. 89 | * @param jsonPayload The json string that should be sent along with POSTs and PUTs. 90 | * @param responseHandler the handler that will be used on a successful 91 | * response 92 | * @return String 93 | * @throws OAuthMessageSignerException 94 | * @throws OAuthCommunicationException 95 | * @throws OAuthExpectationFailedException 96 | * @throws ClientProtocolException 97 | * @throws IOException 98 | */ 99 | public String executeOAuthRequest(String urlString, HttpRequestMethod method, String jsonPayload, ResponseHandler responseHandler) 100 | throws OAuthMessageSignerException, OAuthCommunicationException, OAuthExpectationFailedException, ClientProtocolException, IOException { 101 | HttpUriRequest request = buildRequest(urlString, method, jsonPayload); 102 | logger.info(String.format(Locale.US, "sending %s with url %s", request.toString(), urlString)); 103 | 104 | HttpContext context = new BasicHttpContext(); 105 | context.setAttribute("consumerKey", this.getKey()); 106 | context.setAttribute("consumerSecret", this.getSecret()); 107 | 108 | synchronized(this) { 109 | this.token.sign(request); 110 | } 111 | return super.execute(request, responseHandler, new SyncBasicHttpContext(context)); 112 | } 113 | 114 | /** 115 | * Factory method that builds a HttpUriRequest based on the information passed in. 116 | * 117 | * @param urlString The url that the request should be sent to. 118 | * @param type The type of request that should be sent. 119 | * @param jsonPayload The json string that should be sent along with POSTs and PUTs. 120 | * @return HttpUriRequest Either a HttpGet, HttpPost, HttpPut or HttpDelete 121 | */ 122 | public static HttpUriRequest buildRequest(String urlString, HttpRequestMethod method, String jsonPayload) { 123 | switch (method) { 124 | case GET: 125 | HttpGet requestGet = new HttpGet(urlString); 126 | return requestGet; 127 | case POST: 128 | HttpPost requestPost = new HttpPost(urlString); 129 | requestPost.setEntity(new ByteArrayEntity(jsonPayload.getBytes())); 130 | requestPost.addHeader("Content-type", "application/json"); 131 | return requestPost; 132 | case PUT: 133 | HttpPut requestPut = new HttpPut(urlString); 134 | requestPut.setEntity(new ByteArrayEntity(jsonPayload.getBytes())); 135 | requestPut.addHeader("Content-type", "application/json"); 136 | return requestPut; 137 | case DELETE: 138 | HttpDelete requestDelete = new HttpDelete(urlString); 139 | return requestDelete; 140 | default: 141 | return null; 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/SimpleGeoHandler.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http; 2 | 3 | import java.io.IOException; 4 | import java.util.logging.Logger; 5 | 6 | import org.apache.http.HttpResponse; 7 | import org.apache.http.client.ClientProtocolException; 8 | import org.apache.http.client.ResponseHandler; 9 | import org.apache.http.util.EntityUtils; 10 | 11 | import com.simplegeo.client.http.exceptions.APIException; 12 | import com.simplegeo.client.http.exceptions.NoSuchEntityException; 13 | import com.simplegeo.client.http.exceptions.NotAuthorizedException; 14 | 15 | /** 16 | * A handler used to parse requests sent to http://api.simplegeo.com. 17 | * 18 | * @author Derek Smith 19 | */ 20 | public class SimpleGeoHandler implements ResponseHandler { 21 | private static Logger logger = Logger.getLogger(SimpleGeoHandler.class.getName()); 22 | 23 | /* Status codes */ 24 | public static final int GET_SUCCESS = 200; 25 | public static final int PUT_SUCCESS = 202; 26 | public static final int POST_SUCCESS = 301; 27 | public static final int BAD_REQUEST = 400; 28 | public static final int NO_SUCH = 404; 29 | public static final int NOT_AUTHORIZED = 401; 30 | 31 | public SimpleGeoHandler() { 32 | super(); 33 | } 34 | 35 | /* (non-Javadoc) 36 | * @see org.apache.http.client.ResponseHandler#handleResponse(org.apache.http.HttpResponse) 37 | */ 38 | public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException { 39 | 40 | logger.info("received response " + response); 41 | 42 | int statusCode = response.getStatusLine().getStatusCode(); 43 | 44 | switch(statusCode) { 45 | case GET_SUCCESS: 46 | case POST_SUCCESS: 47 | case PUT_SUCCESS: 48 | break; 49 | case BAD_REQUEST: 50 | throw APIException.createException(response.getEntity(), response.getStatusLine()); 51 | case NO_SUCH: 52 | throw NoSuchEntityException.createException(response.getEntity(), response.getStatusLine()); 53 | case NOT_AUTHORIZED: 54 | throw NotAuthorizedException.createException(response.getEntity(), response.getStatusLine()); 55 | default: 56 | throw APIException.createException(response.getEntity(), response.getStatusLine()); 57 | } 58 | return EntityUtils.toString(response.getEntity()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/SimpleGeoHttpRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.http.Header; 6 | import org.apache.http.HttpException; 7 | import org.apache.http.HttpRequest; 8 | import org.apache.http.HttpRequestInterceptor; 9 | import org.apache.http.protocol.HttpContext; 10 | 11 | public class SimpleGeoHttpRequestInterceptor implements HttpRequestInterceptor { 12 | 13 | @Override 14 | public void process(HttpRequest request, HttpContext context) throws HttpException, IOException { 15 | if (context.getAttribute("AuthHeader") != null) { 16 | request.removeHeaders("Authorization"); 17 | request.addHeader((Header) context.getAttribute("AuthHeader")); 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/SimpleGeoRedirectHandler.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http; 2 | 3 | import java.net.URI; 4 | import java.net.URISyntaxException; 5 | 6 | import oauth.signpost.OAuthConsumer; 7 | import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; 8 | import oauth.signpost.exception.OAuthCommunicationException; 9 | import oauth.signpost.exception.OAuthExpectationFailedException; 10 | import oauth.signpost.exception.OAuthMessageSignerException; 11 | 12 | import org.apache.http.HttpResponse; 13 | import org.apache.http.ProtocolException; 14 | import org.apache.http.client.RedirectHandler; 15 | import org.apache.http.client.methods.HttpUriRequest; 16 | import org.apache.http.protocol.HttpContext; 17 | 18 | import com.simplegeo.client.SimpleGeoClient.HttpRequestMethod; 19 | 20 | public class SimpleGeoRedirectHandler implements RedirectHandler { 21 | 22 | @Override 23 | public URI getLocationURI(HttpResponse response, HttpContext context) throws ProtocolException { 24 | String urlString = response.getFirstHeader("Location").getValue(); 25 | URI uri; 26 | try { 27 | uri = new URI(urlString); 28 | } catch (URISyntaxException e) { 29 | throw new ProtocolException("Could not parse redirect uri."); 30 | } 31 | 32 | HttpUriRequest request = OAuthHttpClient.buildRequest(urlString, HttpRequestMethod.GET, response.getEntity().toString()); 33 | 34 | OAuthConsumer token = new CommonsHttpOAuthConsumer((String) context.getAttribute("consumerKey"), 35 | (String) context.getAttribute("consumerSecret")); 36 | 37 | synchronized(this) { 38 | try { 39 | token.sign(request); 40 | } catch (OAuthMessageSignerException e) { 41 | throw new ProtocolException("Could not sign request!"); 42 | } catch (OAuthExpectationFailedException e) { 43 | throw new ProtocolException("Could not sign request!"); 44 | } catch (OAuthCommunicationException e) { 45 | throw new ProtocolException("Could not sign request!"); 46 | } 47 | } 48 | 49 | // Apache puts original headers back on the request, so we need to pass this along to the RequestInterceptor to be re-added. 50 | context.setAttribute("AuthHeader", request.getFirstHeader("Authorization")); 51 | 52 | return uri; 53 | } 54 | 55 | @Override 56 | public boolean isRedirectRequested(HttpResponse response, HttpContext context) { 57 | int statusCode = response.getStatusLine().getStatusCode(); 58 | if (statusCode == 301 || statusCode == 302) return true; 59 | return false; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/exceptions/APIException.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http.exceptions; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.EOFException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Locale; 8 | import java.util.logging.Logger; 9 | 10 | import org.apache.http.HttpEntity; 11 | import org.apache.http.StatusLine; 12 | 13 | /** 14 | * An exception class that can be built from the components of 15 | * a {@link org.apache.http.HttpResponse}. 16 | * 17 | * @author Derek Smith 18 | */ 19 | @SuppressWarnings("serial") 20 | public class APIException extends IOException { 21 | 22 | private static Logger logger = Logger.getLogger(APIException.class.getName()); 23 | 24 | /** 25 | * The Http status code that generated the exception. 26 | */ 27 | public int statusCode; 28 | 29 | /** 30 | * A static factory method that creates proper API exceptions from 31 | * a {@link org.apache.http.HttpEntity} and {@link org.apache.http.StatusLine}. 32 | * The message is built using a combination of both the status code and the payload. 33 | * 34 | * @param entity the entity retrieved from a Http response 35 | * @param statusLine the {@link org.apache.http.StatusLine} that was retrieved 36 | * from a Http response 37 | * @return a new APIException object 38 | */ 39 | public static APIException createException(HttpEntity entity, StatusLine statusLine) { 40 | 41 | int statusCode = statusLine.getStatusCode(); 42 | String reason = null; 43 | 44 | try { 45 | 46 | InputStream inputStream = entity.getContent(); 47 | DataInputStream dis = new DataInputStream(inputStream); 48 | reason = dis.readUTF(); 49 | 50 | } catch (EOFException e) { 51 | 52 | ; 53 | 54 | } catch (IllegalStateException e) { 55 | e.printStackTrace(); 56 | } catch (IOException e) { 57 | e.printStackTrace(); 58 | } 59 | 60 | if(reason == null) 61 | reason = statusLine.getReasonPhrase(); 62 | 63 | logger.info(String.format(Locale.US, "(status %d) %s", statusCode, reason)); 64 | 65 | return new APIException(statusCode, reason); 66 | } 67 | 68 | /** 69 | * Creates an exception with the given status code and message. 70 | * 71 | * @param statusCode the Http status code that generated the exception 72 | * @param reason the reason why the this exception is being created 73 | */ 74 | public APIException(int statusCode, String reason) { 75 | 76 | super(reason); 77 | this.statusCode = statusCode; 78 | 79 | logger.info(String.format(Locale.US, "(status %d) %s", statusCode, reason)); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/exceptions/NoSuchEntityException.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http.exceptions; 2 | 3 | /** 4 | * An exception that is created when an Http response contains a status 5 | * code of 404. 6 | * 7 | * @author Derek Smith 8 | */ 9 | @SuppressWarnings("serial") 10 | public class NoSuchEntityException extends APIException { 11 | 12 | public NoSuchEntityException(int statusCode, String reason) { 13 | super(statusCode, reason); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/http/exceptions/NotAuthorizedException.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.http.exceptions; 2 | 3 | /** 4 | * An exception that is created when an Http response contains a status 5 | * code of 401. 6 | * 7 | * @author Derek Smith 8 | */ 9 | @SuppressWarnings("serial") 10 | public class NotAuthorizedException extends APIException { 11 | 12 | public NotAuthorizedException(int statusCode, String reason) { 13 | super(statusCode, reason); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Annotation.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | 6 | public class Annotation { 7 | 8 | private boolean isPrivate; 9 | private JSONObject annotations; 10 | 11 | public Annotation(boolean isPrivate, JSONObject annotations) { 12 | this.isPrivate = isPrivate; 13 | this.annotations = annotations; 14 | } 15 | 16 | public boolean isPrivate() { 17 | return isPrivate; 18 | } 19 | 20 | public void setPrivate(boolean isPrivate) { 21 | this.isPrivate = isPrivate; 22 | } 23 | 24 | public JSONObject getAnnotations() { 25 | return annotations; 26 | } 27 | 28 | public void setAnnotations(JSONObject annotations) { 29 | this.annotations = annotations; 30 | } 31 | 32 | public JSONObject toJSON() throws JSONException { 33 | JSONObject json = new JSONObject(); 34 | json.put("private", this.isPrivate()); 35 | json.put("annotations", this.getAnnotations()); 36 | return json; 37 | } 38 | 39 | public String toJSONString() throws JSONException { 40 | return this.toJSON().toString(); 41 | } 42 | 43 | public static Annotation fromJSON(JSONObject json) throws JSONException { 44 | return new Annotation(json.getBoolean("private"), json.getJSONObject("annotations")); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Category.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | /** 4 | * Class that a represents a single category 5 | * 6 | * @author Pranil Kanderi 7 | * 8 | */ 9 | public class Category { 10 | 11 | private String categoryId; 12 | private String category; 13 | private String type; 14 | private String subCategory; 15 | 16 | /** 17 | * Default constructor 18 | */ 19 | public Category() { 20 | } 21 | 22 | /** 23 | * Main constructor for creating a category 24 | * 25 | * @param categoryId - Id of the category, ex: "10100100", "10100101" etc 26 | * @param category - name of the category, ex: "Administrative", "Commercial Area" etc 27 | * @param type - type of the category, ex: "Region", "Entertainment" etc 28 | * @param subCategory - a sub category of this category, ex: "Consolidated City", "County" etc 29 | */ 30 | public Category (String categoryId, String category, String type, String subCategory) { 31 | this.categoryId = categoryId; 32 | this.category = category; 33 | this.type = type; 34 | this.subCategory = subCategory; 35 | } 36 | 37 | public String getCategoryId() { 38 | return categoryId; 39 | } 40 | 41 | public void setCategoryId(String categoryId) { 42 | this.categoryId = categoryId; 43 | } 44 | 45 | public String getCategory() { 46 | return category; 47 | } 48 | 49 | public void setCategory(String category) { 50 | this.category = category; 51 | } 52 | 53 | public String getType() { 54 | return type; 55 | } 56 | 57 | public void setType(String type) { 58 | this.type = type; 59 | } 60 | 61 | public String getSubCategory() { 62 | return subCategory; 63 | } 64 | 65 | public void setSubCategory(String subCategory) { 66 | this.subCategory = subCategory; 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/CategoryCollection.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | /** 10 | * Collection of {@link com.simplegeo.client.types.Category} objects 11 | * 12 | * @author Pranil Kanderi 13 | * 14 | */ 15 | public class CategoryCollection { 16 | 17 | private ArrayList categories; 18 | 19 | public CategoryCollection() { 20 | } 21 | 22 | public CategoryCollection(ArrayList categories) { 23 | this.categories = categories; 24 | } 25 | 26 | public ArrayList getCategories() { 27 | return categories; 28 | } 29 | 30 | public void setCategories(ArrayList categories) { 31 | this.categories = categories; 32 | } 33 | 34 | public static Object fromJSONString(String response) throws JSONException { 35 | JSONArray jsonArray = new JSONArray(response); 36 | 37 | CategoryCollection categoryCollection = new CategoryCollection(); 38 | ArrayList categories = new ArrayList(); 39 | 40 | for (int i = 0; i < jsonArray.length(); i++) { 41 | JSONObject json = jsonArray.getJSONObject(i); 42 | Category category = new Category(json.getString("category_id"), 43 | json.getString("category"), json.getString("type"), 44 | json.getString("subcategory")); 45 | 46 | categories.add(category); 47 | } 48 | categoryCollection.setCategories(categories); 49 | 50 | return categoryCollection; 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Feature.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.Set; 6 | 7 | import org.json.JSONArray; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | 11 | public class Feature { 12 | 13 | protected String simpleGeoId; 14 | protected Geometry geometry; 15 | protected String type; 16 | protected HashMap properties; 17 | 18 | public Feature() { 19 | 20 | } 21 | 22 | public Feature(Geometry geometry, String type, HashMap properties) { 23 | this.geometry = geometry; 24 | this.type = type; 25 | this.properties = properties; 26 | } 27 | 28 | public Feature(String simpleGeoId, Geometry geometry, String type, HashMap properties) { 29 | this.simpleGeoId = simpleGeoId; 30 | this.geometry = geometry; 31 | this.type = type; 32 | this.properties = properties; 33 | } 34 | 35 | public String getSimpleGeoId() { 36 | return simpleGeoId; 37 | } 38 | 39 | public void setSimpleGeoId(String simpleGeoId) { 40 | this.simpleGeoId = simpleGeoId; 41 | } 42 | 43 | public void setGeometry(Geometry geometry) { 44 | this.geometry = geometry; 45 | } 46 | 47 | public Geometry getGeometry() { 48 | return geometry; 49 | } 50 | 51 | public String getType() { 52 | return type; 53 | } 54 | 55 | public void setType(String type) { 56 | this.type = type; 57 | } 58 | 59 | public HashMap getProperties() { 60 | return properties; 61 | } 62 | 63 | public void setProperties(HashMap properties) { 64 | this.properties = properties; 65 | } 66 | 67 | @SuppressWarnings("unchecked") 68 | public static Feature fromJSON(JSONObject json) throws JSONException { 69 | Feature feature = new Feature(); 70 | feature.setSimpleGeoId(json.optString("id")); 71 | feature.setType("Feature"); 72 | JSONObject jsonGeometry = json.getJSONObject("geometry"); 73 | if ("Point".equals(jsonGeometry.getString("type"))) { 74 | JSONArray coordinates = jsonGeometry.getJSONArray("coordinates"); 75 | Point point = new Point(coordinates.getDouble(1), coordinates.getDouble(0)); 76 | feature.setGeometry(new Geometry(point)); 77 | } else if ("Polygon".equals(jsonGeometry.getString("type"))) { 78 | JSONArray polygonArray = jsonGeometry.getJSONArray("coordinates"); 79 | Polygon polygon = Polygon.fromJSONArray(polygonArray); 80 | feature.setGeometry(new Geometry(polygon)); 81 | } else { 82 | JSONArray polygonArray = jsonGeometry.getJSONArray("coordinates"); 83 | MultiPolygon multiPolygon = MultiPolygon.fromJSONArray(polygonArray); 84 | feature.setGeometry(new Geometry(multiPolygon)); 85 | } 86 | 87 | HashMap propertyMap = new HashMap(); 88 | JSONObject properties = json.getJSONObject("properties"); 89 | Iterator propertyIterator = properties.keys(); 90 | while (propertyIterator.hasNext()) { 91 | String key = (String) propertyIterator.next(); 92 | propertyMap.put(key, properties.get(key)); 93 | } 94 | feature.setProperties(propertyMap); 95 | return feature; 96 | } 97 | 98 | public static Feature fromJSONString(String jsonString) throws JSONException { 99 | return fromJSON(new JSONObject(jsonString)); 100 | } 101 | 102 | public JSONObject toJSON() throws JSONException { 103 | JSONObject json = new JSONObject(); 104 | json.put("geometry", this.getGeometryJSON()); 105 | json.put("type", "Feature"); 106 | if (this.getSimpleGeoId() != null) { json.put("id", this.getSimpleGeoId()); } 107 | json.put("properties", this.getPropertyJSON()); 108 | return json; 109 | } 110 | 111 | public String toJSONString() throws JSONException { 112 | return this.toJSON().toString(); 113 | } 114 | 115 | private JSONObject getGeometryJSON() throws JSONException { 116 | JSONObject json = new JSONObject(); 117 | Geometry geometry = this.getGeometry(); 118 | if (geometry.getPoint() != null) { 119 | json.put("type", "Point"); 120 | json.put("coordinates", geometry.getPoint().toJSONArray()); 121 | } else if (geometry.getPolygon() != null){ 122 | json.put("type", "Polygon"); 123 | json.put("coordinates", geometry.getPolygon().toJSONArray()); 124 | } else { 125 | json.put("type", "MultiPolygon"); 126 | json.put("coordinates", geometry.getMultiPolygon().toJSONArray()); 127 | } 128 | return json; 129 | } 130 | 131 | private JSONObject getPropertyJSON() throws JSONException { 132 | JSONObject json = new JSONObject(); 133 | HashMap properties = this.getProperties(); 134 | Set keys = properties.keySet(); 135 | for (String key : keys) { 136 | json.put(key, properties.get(key)); 137 | } 138 | return json; 139 | } 140 | 141 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/FeatureCollection.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | public class FeatureCollection { 10 | 11 | private ArrayList features; 12 | private String cursor; 13 | 14 | public FeatureCollection() { 15 | 16 | } 17 | 18 | public FeatureCollection(ArrayList features) { 19 | this.features = features; 20 | } 21 | 22 | public ArrayList getFeatures() { 23 | return features; 24 | } 25 | 26 | public void setFeatures(ArrayList features) { 27 | this.features = features; 28 | } 29 | 30 | /** 31 | * @param cursor the cursor to set 32 | */ 33 | public void setCursor(String cursor) { 34 | this.cursor = cursor; 35 | } 36 | 37 | /** 38 | * @return the cursor 39 | */ 40 | public String getCursor() { 41 | return cursor; 42 | } 43 | 44 | public static FeatureCollection fromJSON(JSONObject json) throws JSONException { 45 | FeatureCollection featureCollection = new FeatureCollection(); 46 | ArrayList features = new ArrayList(); 47 | JSONArray featuresArray = json.getJSONArray("features"); 48 | int numOfFeatures = featuresArray.length(); 49 | for (int i=0; i features = this.getFeatures(); 65 | for (Feature feature : features) { 66 | jsonArray.put(feature.toJSON()); 67 | } 68 | return jsonArray; 69 | } 70 | 71 | public String toJSONString() throws JSONException { 72 | return this.toJSON().toString(); 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Geometry.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | public class Geometry { 4 | 5 | private Point point; 6 | private Polygon polygon; 7 | private MultiPolygon multiPolygon; 8 | private long created; 9 | 10 | public Geometry() { 11 | 12 | } 13 | 14 | public Geometry(Point point) { 15 | this.point = point; 16 | } 17 | 18 | public Geometry(Polygon polygon) { 19 | this.polygon = polygon; 20 | } 21 | 22 | public Geometry(MultiPolygon multiPolygon) { 23 | this.multiPolygon = multiPolygon; 24 | } 25 | 26 | public Point getPoint() { 27 | return point; 28 | } 29 | 30 | public void setPoint(Point point) { 31 | this.point = point; 32 | } 33 | 34 | public Polygon getPolygon() { 35 | return polygon; 36 | } 37 | 38 | public void setPolygon(Polygon polygon) { 39 | this.polygon = polygon; 40 | } 41 | 42 | public MultiPolygon getMultiPolygon() { 43 | return multiPolygon; 44 | } 45 | 46 | public void setMultiPolygon(MultiPolygon multiPolygon) { 47 | this.multiPolygon = multiPolygon; 48 | } 49 | 50 | public void setCreated(long created) { 51 | this.created = created; 52 | } 53 | 54 | public long getCreated() { 55 | return created; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/GeometryCollection.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | /** 10 | * Collection of {@link com.simplegeo.client.types.Geometry} objects 11 | * 12 | * @author Pranil Kanderi 13 | * 14 | */ 15 | public class GeometryCollection { 16 | 17 | private ArrayList geometries; 18 | private String cursor; 19 | 20 | public GeometryCollection() { 21 | 22 | } 23 | 24 | public GeometryCollection(ArrayList geometries) { 25 | this.setGeometries(geometries); 26 | } 27 | 28 | /** 29 | * @param geometries the geometries to set 30 | */ 31 | public void setGeometries(ArrayList geometries) { 32 | this.geometries = geometries; 33 | } 34 | 35 | /** 36 | * @return the geometries 37 | */ 38 | public ArrayList getGeometries() { 39 | return geometries; 40 | } 41 | 42 | /** 43 | * @param cursor the cursor to set 44 | */ 45 | public void setCursor(String cursor) { 46 | this.cursor = cursor; 47 | } 48 | 49 | /** 50 | * @return the cursor 51 | */ 52 | public String getCursor() { 53 | return cursor; 54 | } 55 | 56 | public static GeometryCollection fromJSONString(String response) throws JSONException { 57 | JSONObject jsonObject = new JSONObject(response); 58 | 59 | JSONArray jsonArray = jsonObject.getJSONArray("geometries"); 60 | 61 | GeometryCollection geometryCollection = new GeometryCollection(); 62 | ArrayList geometries = new ArrayList(); 63 | 64 | for (int i = 0; i < jsonArray.length(); i++) { 65 | 66 | Geometry geometry = new Geometry(); 67 | JSONObject jsonGeometry = jsonArray.getJSONObject(i); 68 | 69 | if ("Point".equals(jsonGeometry.getString("type"))) { 70 | JSONArray coordinates = jsonGeometry.getJSONArray("coordinates"); 71 | Point point = new Point(coordinates.getDouble(1), coordinates.getDouble(0)); 72 | geometry = new Geometry(point); 73 | } else if ("Polygon".equals(jsonGeometry.getString("type"))) { 74 | JSONArray polygonArray = jsonGeometry.getJSONArray("coordinates"); 75 | Polygon polygon = Polygon.fromJSONArray(polygonArray); 76 | geometry = new Geometry(polygon); 77 | } else { 78 | JSONArray polygonArray = jsonGeometry.getJSONArray("coordinates"); 79 | MultiPolygon multiPolygon = MultiPolygon.fromJSONArray(polygonArray); 80 | geometry = new Geometry(multiPolygon); 81 | } 82 | 83 | geometry.setCreated(jsonGeometry.getLong("created")); 84 | geometries.add(geometry); 85 | } 86 | geometryCollection.setCursor(new JSONObject(response).optString("cursor")); 87 | geometryCollection.setGeometries(geometries); 88 | 89 | return geometryCollection; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Layer.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | /** 10 | * Class that a represents a Layer 11 | * 12 | * @author Pranil Kanderi 13 | * 14 | */ 15 | public class Layer { 16 | 17 | private String name; 18 | private String title; 19 | private String description; 20 | private boolean isPublic; 21 | private long created; 22 | private long updated; 23 | private ArrayList callbackURLs; 24 | 25 | /** 26 | * Initializes a new Layer object with the name 27 | * 28 | * @param name the name of the layer (e.g. com.mokriya.testing) 29 | */ 30 | public Layer(String name) { 31 | this(name, "", "", false, new ArrayList()); 32 | } 33 | 34 | /** 35 | * Initializes a new Layer object with the specified 36 | * 37 | * @param name the name of the layer (e.g. com.mokriya.testing) 38 | * @param title the title of this layer (eg. Test Layer for Mokriya) 39 | * @param description the description of this layer 40 | * @param isPublic boolean, true if this layer is public, false otherwise 41 | * @param callbackURLs ArrayList of callback url's 42 | */ 43 | public Layer(String name, String title, String description, boolean isPublic, ArrayList callbackURLs) { 44 | this.name = name; 45 | this.title = title; 46 | this.description = description; 47 | this.isPublic = isPublic; 48 | this.callbackURLs = callbackURLs; 49 | } 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | public void setName(String name) { 56 | this.name = name; 57 | } 58 | 59 | public String getTitle() { 60 | return title; 61 | } 62 | 63 | public void setTitle(String title) { 64 | this.title = title; 65 | } 66 | 67 | public String getDescription() { 68 | return description; 69 | } 70 | 71 | public void setDescription(String description) { 72 | this.description = description; 73 | } 74 | 75 | public boolean isPublic() { 76 | return isPublic; 77 | } 78 | 79 | public void setPublic(boolean isPublic) { 80 | this.isPublic = isPublic; 81 | } 82 | 83 | public ArrayList getCallbackURLs() { 84 | return callbackURLs; 85 | } 86 | 87 | public void setCallbackURLs(ArrayList callbackURLs) { 88 | this.callbackURLs = callbackURLs; 89 | } 90 | 91 | public long getCreated() { 92 | return created; 93 | } 94 | 95 | public long getUpdated() { 96 | return updated; 97 | } 98 | 99 | public static String toJSONString(Layer layer) throws JSONException{ 100 | JSONObject jsonObject = new JSONObject(); 101 | jsonObject.put("name", layer.getName()); 102 | jsonObject.put("title", layer.getTitle()); 103 | jsonObject.put("description", layer.getDescription()); 104 | jsonObject.put("public", layer.isPublic()); 105 | 106 | JSONArray jsonArray = new JSONArray(); 107 | for (String url : layer.callbackURLs) { 108 | jsonArray.put(url); 109 | } 110 | jsonObject.put("callback_urls", jsonArray); 111 | 112 | return jsonObject.toString(); 113 | } 114 | 115 | public static Layer fromJSONString(String jsonString) throws JSONException { 116 | return fromJSONObject(new JSONObject(jsonString)); 117 | } 118 | 119 | public static Layer fromJSONObject(JSONObject json) throws JSONException { 120 | Layer layer = new Layer(json.getString("name")); 121 | layer.setTitle(json.optString("title")); 122 | layer.setDescription(json.optString("description")); 123 | layer.setPublic(json.optBoolean("public")); 124 | layer.created = json.optLong("created"); 125 | layer.updated = json.optLong("updated"); 126 | 127 | JSONArray urls = json.optJSONArray("callback_urls"); 128 | ArrayList callbackURLs = new ArrayList(); 129 | if (urls != null) { 130 | for (int i=0; i < urls.length(); i++) { 131 | callbackURLs.add(urls.getString(i)); 132 | } 133 | } 134 | 135 | layer.setCallbackURLs(callbackURLs); 136 | 137 | return layer; 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/LayerCollection.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | /** 10 | * Collection of {@link com.simplegeo.client.types.Layer} objects 11 | * 12 | * @author Pranil Kanderi 13 | * 14 | */ 15 | public class LayerCollection { 16 | 17 | private ArrayList layers; 18 | 19 | public LayerCollection() { 20 | } 21 | 22 | public LayerCollection(ArrayList layers) { 23 | this.layers = layers; 24 | } 25 | 26 | public ArrayList getLayers() { 27 | return layers; 28 | } 29 | 30 | public void setLayers(ArrayList layers) { 31 | this.layers = layers; 32 | } 33 | 34 | public static LayerCollection fromJSONString(String response) throws JSONException { 35 | JSONObject jsonObject = new JSONObject(response); 36 | JSONArray jsonArray = jsonObject.getJSONArray("layers"); 37 | 38 | LayerCollection layerCollection = new LayerCollection(); 39 | ArrayList layers = new ArrayList(); 40 | 41 | for (int i = 0; i < jsonArray.length(); i++) { 42 | JSONObject json = jsonArray.getJSONObject(i); 43 | Layer layer = Layer.fromJSONObject(json); 44 | layers.add(layer); 45 | } 46 | layerCollection.setLayers(layers); 47 | 48 | return layerCollection; 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/MultiPolygon.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | 8 | public class MultiPolygon { 9 | 10 | private ArrayList polygons = new ArrayList(); 11 | 12 | public MultiPolygon() { 13 | 14 | } 15 | 16 | public MultiPolygon(ArrayList polygons) { 17 | this.polygons = polygons; 18 | } 19 | 20 | public ArrayList getPolygons() { 21 | return polygons; 22 | } 23 | 24 | public void setPolygons(ArrayList polygons) { 25 | this.polygons = polygons; 26 | } 27 | 28 | public static MultiPolygon fromJSONArray(JSONArray jsonArray) throws JSONException { 29 | ArrayList polygonList = new ArrayList(); 30 | int numOfPolygons = jsonArray.length(); 31 | for (int i=0; i polygons = this.getPolygons(); 40 | for (Polygon polygon : polygons) { 41 | jsonArray.put(polygon.toJSONArray()); 42 | } 43 | return jsonArray; 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Point.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | 6 | public class Point { 7 | 8 | private double lat; 9 | private double lon; 10 | 11 | public Point() { 12 | 13 | } 14 | 15 | public Point(double lat, double lon) { 16 | this.lat = lat; 17 | this.lon = lon; 18 | } 19 | 20 | public double getLat() { 21 | return lat; 22 | } 23 | 24 | public void setLat(double lat) { 25 | this.lat = lat; 26 | } 27 | 28 | public double getLon() { 29 | return lon; 30 | } 31 | 32 | public void setLon(double lon) { 33 | this.lon = lon; 34 | } 35 | 36 | public JSONArray toJSONArray() throws JSONException { 37 | JSONArray pointArray = new JSONArray(); 38 | pointArray.put(this.getLon()); 39 | pointArray.put(this.getLat()); 40 | return pointArray; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/com/simplegeo/client/types/Polygon.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | 8 | public class Polygon { 9 | 10 | private ArrayList> rings; 11 | 12 | public Polygon() { 13 | 14 | } 15 | 16 | public Polygon(ArrayList> rings) { 17 | this.rings = rings; 18 | } 19 | 20 | public ArrayList> getRings() { 21 | return rings; 22 | } 23 | 24 | public void setRings(ArrayList> rings) { 25 | this.rings = rings; 26 | } 27 | 28 | public static Polygon fromJSONArray(JSONArray polygonArray) throws JSONException { 29 | ArrayList> ringList = new ArrayList>(); 30 | int numOfRings = polygonArray.length(); 31 | for (int i=0; i pointList = new ArrayList(); 35 | for (int j=0; j> ringList = this.getRings(); 47 | for (ArrayList ring : ringList) { 48 | JSONArray r = new JSONArray(); 49 | int numOfPoints = ring.size(); 50 | for (int i=0; i()); 30 | 31 | this.layer = layer; 32 | this.created = (long) (System.currentTimeMillis() / 1000); 33 | this.expiration = 0; 34 | } 35 | 36 | /** 37 | * @return the id associated with the record 38 | */ 39 | public String getRecordId() { 40 | return this.simpleGeoId; 41 | } 42 | 43 | /** 44 | * @param recordId 45 | * the id associated with the record 46 | */ 47 | public void setRecordId(String recordId) { 48 | this.simpleGeoId = recordId; 49 | } 50 | 51 | /** 52 | * @return the layer where the record is held 53 | */ 54 | public String getLayer() { 55 | return layer; 56 | } 57 | 58 | /** 59 | * @param layer 60 | * the layer where the record is held 61 | */ 62 | public void setLayer(String layer) { 63 | this.layer = layer; 64 | } 65 | 66 | /** 67 | * @return the time at which this record was created in milliseconds 68 | */ 69 | public long getCreated() { 70 | return created; 71 | } 72 | 73 | /** 74 | * @param created 75 | * the time at which this record was created in milliseconds 76 | */ 77 | public void setCreated(long created) { 78 | this.created = created; 79 | } 80 | 81 | /** 82 | * @return the time at which this record will expire in milliseconds 83 | */ 84 | public long getExpiration() { 85 | return expiration; 86 | } 87 | 88 | /** 89 | * @param expiration 90 | * the time at which this record will expire in milliseconds 91 | */ 92 | public void setExpiration(long expiration) { 93 | this.expiration = expiration; 94 | } 95 | 96 | @Override 97 | public JSONObject toJSON() throws JSONException { 98 | JSONObject jsonObject = super.toJSON(); 99 | jsonObject.put("layer", layer); 100 | jsonObject.put("created", created); 101 | jsonObject.put("expiration", expiration); 102 | 103 | return jsonObject; 104 | } 105 | 106 | public static Record fromJSONString(String jsonString) throws JSONException { 107 | return fromJSON(new JSONObject(jsonString)); 108 | } 109 | 110 | public static Record fromJSON(JSONObject json) throws JSONException { 111 | Record record = new Record(); 112 | Feature feature = Feature.fromJSON(json); 113 | 114 | record.setSimpleGeoId(feature.getSimpleGeoId()); 115 | record.setGeometry(feature.getGeometry()); 116 | record.setType(feature.getType()); 117 | record.setProperties(feature.getProperties()); 118 | 119 | record.setLayer((String)feature.getProperties().get("layer")); 120 | record.setCreated(json.optLong("created")); 121 | 122 | return record; 123 | } 124 | 125 | public static JSONObject toJSON(ArrayList records) 126 | throws JSONException { 127 | JSONObject jsonObject = new JSONObject(); 128 | jsonObject.put("type", "FeatureCollection"); 129 | 130 | JSONArray jsonArray = new JSONArray(); 131 | for (Record record : records) { 132 | jsonArray.put(record.toJSON()); 133 | } 134 | jsonObject.put("features", jsonArray); 135 | 136 | return jsonObject; 137 | } 138 | 139 | public static String toJSONString(ArrayList records) 140 | throws JSONException { 141 | return toJSON(records).toString(); 142 | } 143 | 144 | public String toString() { 145 | 146 | return String.format(Locale.US, "", 147 | getRecordId(), getLayer(), getCreated()); 148 | } 149 | 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/SimpleGeoContextClientTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | import org.junit.Assert; 9 | import org.junit.BeforeClass; 10 | import org.junit.Test; 11 | 12 | import com.simplegeo.client.test.TestEnvironment; 13 | 14 | public class SimpleGeoContextClientTest { 15 | 16 | protected static SimpleGeoContextClient client; 17 | 18 | @BeforeClass 19 | public static void setUp() throws Exception { 20 | setupClient(); 21 | } 22 | 23 | private static void setupClient() throws Exception { 24 | client = new SimpleGeoContextClient(); 25 | client.getHttpClient().setToken(TestEnvironment.getKey(), TestEnvironment.getSecret()); 26 | } 27 | 28 | @Test 29 | public void testGetContextSync() { 30 | double lat = 37.803259; 31 | double lon = -122.440033; 32 | try { 33 | String jsonString = client.getContext(lat, lon, null); 34 | JSONObject json = new JSONObject(jsonString); 35 | 36 | Assert.assertNotNull(json.get("features")); 37 | Assert.assertNotNull(json.get("weather")); 38 | Assert.assertNotNull(json.get("demographics")); 39 | } catch (IOException e) { 40 | Assert.fail(e.getMessage()); 41 | } catch (JSONException e) { 42 | Assert.fail(e.getMessage()); 43 | } 44 | } 45 | 46 | @Test 47 | public void testGetContextByMyIPSync() { 48 | try { 49 | String jsonString = client.getContextByIP("", null); 50 | JSONObject json = new JSONObject(jsonString); 51 | 52 | Assert.assertNotNull(json.get("query")); 53 | Assert.assertNotNull(json.get("features")); 54 | Assert.assertNotNull(json.get("weather")); 55 | Assert.assertNotNull(json.get("demographics")); 56 | 57 | } catch (IOException e) { 58 | Assert.fail(e.getMessage()); 59 | } catch (JSONException e) { 60 | Assert.fail(e.getMessage()); 61 | } 62 | } 63 | 64 | @Test 65 | public void testGetContextByIPSync() { 66 | try { 67 | String jsonString = client.getContextByIP("92.156.43.27", null); 68 | JSONObject json = new JSONObject(jsonString); 69 | 70 | Assert.assertNotNull(json.get("query")); 71 | Assert.assertNotNull(json.get("features")); 72 | Assert.assertNotNull(json.get("weather")); 73 | Assert.assertNotNull(json.get("demographics")); 74 | 75 | } catch (IOException e) { 76 | Assert.fail(e.getMessage()); 77 | } catch (JSONException e) { 78 | Assert.fail(e.getMessage()); 79 | } 80 | } 81 | 82 | @Test 83 | public void testGetContextByAddressSync() { 84 | try { 85 | String jsonString = client.getContextByAddress("41 Decatur St, San Francisco, CA", null); 86 | JSONObject json = new JSONObject(jsonString); 87 | 88 | Assert.assertNotNull(json.get("query")); 89 | Assert.assertNotNull(json.get("features")); 90 | Assert.assertNotNull(json.get("weather")); 91 | Assert.assertNotNull(json.get("demographics")); 92 | 93 | } catch (IOException e) { 94 | Assert.fail(e.getMessage()); 95 | } catch (JSONException e) { 96 | Assert.fail(e.getMessage()); 97 | } 98 | } 99 | 100 | @Test 101 | public void testGetFilteredContext() { 102 | double lat = 37.803259; 103 | double lon = -122.440033; 104 | try { 105 | HashMap queryParams = new HashMap(); 106 | queryParams.put("filter", new String[] {"weather", "features"}); 107 | queryParams.put("features__category", new String[] {"Neighborhood"}); 108 | String jsonString = client.getContext(lat, lon, queryParams); 109 | JSONObject json = new JSONObject(jsonString); 110 | 111 | Assert.assertNotNull(json.get("weather")); 112 | Assert.assertNotNull(json.get("features")); 113 | 114 | Assert.assertNull(json.opt("demographics")); 115 | } catch (IOException e) { 116 | Assert.fail(e.getMessage()); 117 | } catch (JSONException e) { 118 | Assert.fail(e.getMessage()); 119 | } 120 | } 121 | 122 | @Test 123 | public void testGetDemographics() { 124 | double lat = 37.803259; 125 | double lon = -122.440033; 126 | try { 127 | HashMap queryParams = new HashMap(); 128 | queryParams.put("filter", new String[] {"demographics.acs"}); 129 | queryParams.put("demographics.acs__table", new String[] {"B08012"}); 130 | String jsonString = client.getContext(lat, lon, queryParams); 131 | JSONObject json = new JSONObject(jsonString); 132 | 133 | Assert.assertNotNull(json.get("demographics")); 134 | 135 | Assert.assertNull(json.opt("weather")); 136 | Assert.assertNull(json.opt("features")); 137 | } catch (IOException e) { 138 | Assert.fail(e.getMessage()); 139 | } catch (JSONException e) { 140 | Assert.fail(e.getMessage()); 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/SimpleGeoPlaces12ClientTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | import org.junit.Assert; 9 | import org.junit.BeforeClass; 10 | import org.junit.Test; 11 | 12 | import com.simplegeo.client.test.TestEnvironment; 13 | import com.simplegeo.client.types.FeatureCollection; 14 | 15 | public class SimpleGeoPlaces12ClientTest { 16 | 17 | protected static SimpleGeoPlaces12Client client; 18 | 19 | @BeforeClass 20 | public static void setUp() throws Exception { 21 | setupClient(); 22 | } 23 | 24 | private static void setupClient() throws Exception { 25 | client = new SimpleGeoPlaces12Client(); 26 | client.getHttpClient().setToken(TestEnvironment.getKey(), TestEnvironment.getSecret()); 27 | } 28 | 29 | @Test 30 | public void testGetFeaturePointSync() { 31 | try { 32 | String jsonString = client.getFeature("SG_12NOI6r1xICCpP4bMdyHsq_37.778644_-122.389380@1303263314"); 33 | JSONObject json = new JSONObject(jsonString); 34 | 35 | Assert.assertEquals("SG_12NOI6r1xICCpP4bMdyHsq_37.778644_-122.389380@1303263314", json.get("id")); 36 | } catch (IOException e) { 37 | Assert.fail(e.getMessage()); 38 | } catch (JSONException e) { 39 | Assert.fail(e.getMessage()); 40 | } 41 | } 42 | 43 | @Test 44 | public void testGetFactualFeaturePointSync() { 45 | try { 46 | String jsonString = client.getFeature("b69900d4-4490-4b56-9a1d-c00a86b8c322"); 47 | JSONObject json = new JSONObject(jsonString); 48 | 49 | Assert.assertEquals("b69900d4-4490-4b56-9a1d-c00a86b8c322", json.get("id")); 50 | } catch (IOException e) { 51 | Assert.fail(e.getMessage()); 52 | } catch (JSONException e) { 53 | Assert.fail(e.getMessage()); 54 | } 55 | } 56 | 57 | @Test 58 | public void testGetPlacePolygonSync() { 59 | try { 60 | String jsonString = client.getFeature("SG_0Bw22I6fWoxnZ4GDc8YlXd"); 61 | JSONObject json = new JSONObject(jsonString); 62 | 63 | Assert.assertEquals("SG_0Bw22I6fWoxnZ4GDc8YlXd", json.get("id")); 64 | } catch (IOException e) { 65 | Assert.fail(e.getMessage()); 66 | } catch (JSONException e) { 67 | Assert.fail(e.getMessage()); 68 | } 69 | } 70 | 71 | @Test 72 | public void testSearchSync() { 73 | double lat = 37.772381; 74 | double lon = -122.405827; 75 | try { 76 | HashMap params = new HashMap(); 77 | params.put("category", new String[] {"Restaurants"}); 78 | params.put("radius", new String[] {"100"}); 79 | String jsonString = client.search(lat, lon, params); 80 | JSONObject json = new JSONObject(jsonString); 81 | 82 | Assert.assertNotNull(json); 83 | 84 | FeatureCollection collection = FeatureCollection.fromJSON(json); 85 | 86 | Assert.assertNotNull(collection); 87 | } catch (IOException e) { 88 | Assert.fail(e.getMessage()); 89 | } catch (JSONException e) { 90 | Assert.fail(e.getMessage()); 91 | } 92 | } 93 | 94 | @Test 95 | public void testSearchNonGeoSync() { 96 | try { 97 | HashMap params = new HashMap(); 98 | params.put("limit", new String[] { "10" }); 99 | String jsonString = client.search("salad dressing", params); 100 | JSONObject json = new JSONObject(jsonString); 101 | 102 | Assert.assertNotNull(json); 103 | 104 | FeatureCollection collection = FeatureCollection.fromJSON(json); 105 | 106 | Assert.assertNotNull(collection); 107 | } catch (IOException e) { 108 | Assert.fail(e.getMessage()); 109 | } catch (JSONException e) { 110 | Assert.fail(e.getMessage()); 111 | } 112 | } 113 | 114 | @Test 115 | public void testSearchByAddressSync() { 116 | String address = "1535 Pearl St, Boulder, CO"; 117 | try { 118 | HashMap params = new HashMap(); 119 | params.put("radius", new String[] {"100"}); 120 | String jsonString = client.searchByAddress(address, params); 121 | JSONObject json = new JSONObject(jsonString); 122 | 123 | Assert.assertNotNull(json); 124 | 125 | FeatureCollection collection = FeatureCollection.fromJSON(json); 126 | 127 | Assert.assertNotNull(collection); 128 | } catch (IOException e) { 129 | Assert.fail(e.getMessage()); 130 | } catch (JSONException e) { 131 | Assert.fail(e.getMessage()); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/SimpleGeoPlacesClientTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | import org.junit.Assert; 10 | import org.junit.BeforeClass; 11 | import org.junit.Test; 12 | 13 | import com.simplegeo.client.test.TestEnvironment; 14 | import com.simplegeo.client.types.Feature; 15 | 16 | public class SimpleGeoPlacesClientTest { 17 | 18 | protected static SimpleGeoPlacesClient client; 19 | 20 | @BeforeClass 21 | public static void setUp() throws Exception { 22 | setupClient(); 23 | } 24 | 25 | private static void setupClient() throws Exception { 26 | client = new SimpleGeoPlacesClient(); 27 | client.getHttpClient().setToken(TestEnvironment.getKey(), TestEnvironment.getSecret()); 28 | } 29 | 30 | @Test 31 | public void testGetCategoriesSync() { 32 | try { 33 | String jsonString = client.getCategories(); 34 | JSONArray json = new JSONArray(jsonString); 35 | 36 | Assert.assertTrue(json.length() > 0); 37 | } catch (IOException e) { 38 | Assert.fail(e.getMessage()); 39 | } catch (JSONException e) { 40 | Assert.fail(e.getMessage()); 41 | } 42 | } 43 | 44 | @Test 45 | public void testGetFeaturePointSync() { 46 | try { 47 | String jsonString = client.getFeature("SG_12NOI6r1xICCpP4bMdyHsq_37.778644_-122.389380@1303263314"); 48 | JSONObject json = new JSONObject(jsonString); 49 | 50 | Assert.assertEquals("SG_12NOI6r1xICCpP4bMdyHsq_37.778644_-122.389380@1303263314", json.get("id")); 51 | } catch (IOException e) { 52 | Assert.fail(e.getMessage()); 53 | } catch (JSONException e) { 54 | Assert.fail(e.getMessage()); 55 | } 56 | } 57 | 58 | @Test 59 | public void testGetPlacePolygonSync() { 60 | try { 61 | String jsonString = client.getFeature("SG_0Bw22I6fWoxnZ4GDc8YlXd"); 62 | JSONObject json = new JSONObject(jsonString); 63 | 64 | Assert.assertEquals("SG_0Bw22I6fWoxnZ4GDc8YlXd", json.get("id")); 65 | } catch (IOException e) { 66 | Assert.fail(e.getMessage()); 67 | } catch (JSONException e) { 68 | Assert.fail(e.getMessage()); 69 | } 70 | } 71 | 72 | @Test 73 | public void testAddUpdateDeletePlaceSync() { 74 | try { 75 | JSONObject origJson = new JSONObject(TestEnvironment.getJsonPointStringNoId()); 76 | Feature feature = Feature.fromJSON(origJson); 77 | String jsonString = client.addPlace(feature); 78 | JSONObject json = new JSONObject(jsonString); 79 | 80 | Assert.assertNotNull(json.get("id")); 81 | String newPlaceHandle = json.getString("id"); 82 | 83 | feature = Feature.fromJSON(origJson); 84 | feature.setSimpleGeoId(newPlaceHandle); 85 | jsonString = client.updatePlace(feature); 86 | 87 | Assert.assertNotNull(json.get("id")); 88 | Assert.assertEquals(newPlaceHandle, json.getString("id")); 89 | 90 | jsonString = client.deletePlace(newPlaceHandle); 91 | json = new JSONObject(jsonString); 92 | 93 | Assert.assertNotNull(json.get("token")); 94 | } catch (IOException e) { 95 | Assert.fail(e.getMessage()); 96 | } catch (JSONException e) { 97 | Assert.fail(e.getMessage()); 98 | } 99 | } 100 | 101 | @Test 102 | public void testSearchSync() { 103 | double lat = 37.759737; 104 | double lon = -122.433203; 105 | try { 106 | HashMap params = new HashMap(); 107 | params.put("category", new String[] {"Restaurants"}); 108 | params.put("radius", new String[] {"25"}); 109 | String jsonString = client.search(lat, lon, params); 110 | JSONObject json = new JSONObject(jsonString); 111 | 112 | Assert.assertNotNull(json); 113 | } catch (IOException e) { 114 | Assert.fail(e.getMessage()); 115 | } catch (JSONException e) { 116 | Assert.fail(e.getMessage()); 117 | } 118 | } 119 | 120 | @Test 121 | public void testSearchByAddressSync() { 122 | String address = "1535 Pearl St, Boulder, CO"; 123 | try { 124 | HashMap params = new HashMap(); 125 | params.put("radius", new String[] {"25"}); 126 | String jsonString = client.searchByAddress(address, params); 127 | JSONObject json = new JSONObject(jsonString); 128 | 129 | Assert.assertNotNull(json); 130 | } catch (IOException e) { 131 | Assert.fail(e.getMessage()); 132 | } catch (JSONException e) { 133 | Assert.fail(e.getMessage()); 134 | } 135 | } 136 | } -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/SimpleGeoStorageClientTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client; 2 | 3 | import static org.junit.Assume.assumeTrue; 4 | 5 | import java.io.IOException; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | import org.junit.Assert; 12 | import org.junit.Before; 13 | import org.junit.BeforeClass; 14 | import org.junit.Test; 15 | 16 | import com.simplegeo.client.test.TestEnvironment; 17 | import com.simplegeo.client.types.FeatureCollection; 18 | import com.simplegeo.client.types.GeometryCollection; 19 | import com.simplegeo.client.types.Layer; 20 | import com.simplegeo.client.types.LayerCollection; 21 | import com.simplegeo.client.types.Record; 22 | 23 | public class SimpleGeoStorageClientTest { 24 | 25 | protected static SimpleGeoStorageClient client; 26 | 27 | @BeforeClass 28 | public static void setUp() throws Exception { 29 | setupClient(); 30 | } 31 | 32 | private static void setupClient() throws Exception { 33 | client = new SimpleGeoStorageClient(); 34 | client.getHttpClient().setToken(TestEnvironment.getKey(), TestEnvironment.getSecret()); 35 | } 36 | 37 | @Before 38 | public void mustHavePaidAccount() { 39 | assumeTrue(TestEnvironment.isPaidAccount()); 40 | } 41 | 42 | @Test 43 | public void testAddOrUpdateRecordSync() { 44 | double lon = -122.937467; 45 | double lat = 47.046962; 46 | String layer = "casey.testing.layer"; 47 | String testPropertyKey = "name"; 48 | String testPropertyValue = "Testing Storage"; 49 | try { 50 | Record record = new Record("simplegeo-boulder", layer, "Feature", lon, lat); 51 | HashMap properties = new HashMap(); 52 | properties.put(testPropertyKey, testPropertyValue); 53 | record.setProperties(properties); 54 | client.addOrUpdateRecord(record); 55 | 56 | Assert.assertEquals(layer, record.getLayer()); 57 | Assert.assertEquals(lat, record.getGeometry().getPoint().getLat(), 0d); 58 | Assert.assertEquals(lon, record.getGeometry().getPoint().getLon(), 0d); 59 | Assert.assertEquals(testPropertyValue, record.getProperties().get(testPropertyKey)); 60 | 61 | } catch (JSONException e) { 62 | Assert.fail(e.getMessage()); 63 | } catch (IOException e) { 64 | Assert.fail(e.getMessage()); 65 | } 66 | } 67 | 68 | @Test 69 | public void testAddOrUpdateRecordsSync() { 70 | double lon = -122.937467; 71 | double lat = 47.046962; 72 | String layer = "casey.testing.layer"; 73 | String testPropertyKey = "name"; 74 | String testPropertyValue = "Testing Storage"; 75 | try { 76 | Record record1 = new Record("testRecordId1", layer, "Feature", lon, lat); 77 | HashMap properties = new HashMap(); 78 | properties.put(testPropertyKey, testPropertyValue); 79 | record1.setProperties(properties); 80 | 81 | Record record2 = new Record("testRecordId2", layer, "Feature", lon, lat); 82 | record2.setProperties(properties); 83 | 84 | ArrayList records = new ArrayList(); 85 | records.add(record1); 86 | records.add(record2); 87 | 88 | client.addOrUpdateRecords(records, layer); 89 | 90 | Assert.assertEquals(layer, record1.getLayer()); 91 | Assert.assertEquals(lat, record1.getGeometry().getPoint().getLat(), 0d); 92 | Assert.assertEquals(lon, record1.getGeometry().getPoint().getLon(), 0d); 93 | Assert.assertEquals(testPropertyValue, record1.getProperties().get(testPropertyKey)); 94 | 95 | } catch (JSONException e) { 96 | Assert.fail(e.getMessage()); 97 | } catch (IOException e) { 98 | Assert.fail(e.getMessage()); 99 | } 100 | } 101 | 102 | @Test 103 | public void testGetRecordSync() { 104 | try { 105 | String jsonString = client.getRecord("casey.testing.layer", "simplegeo-boulder"); 106 | Record record = Record.fromJSONString(jsonString); 107 | 108 | Assert.assertEquals("simplegeo-boulder", record.getRecordId()); 109 | } catch (IOException e) { 110 | Assert.fail(e.getMessage()); 111 | } catch (JSONException e) { 112 | Assert.fail(e.getMessage()); 113 | } 114 | } 115 | 116 | @Test 117 | public void testGetHistorySync() { 118 | try { 119 | String jsonString = client.getHistory("casey.testing.layer", "simplegeo-boulder", null); 120 | GeometryCollection geoColl = GeometryCollection.fromJSONString(jsonString); 121 | 122 | Assert.assertNotNull(geoColl.getGeometries()); 123 | } catch (IOException e) { 124 | Assert.fail(e.getMessage()); 125 | } catch (JSONException e) { 126 | Assert.fail(e.getMessage()); 127 | } 128 | } 129 | 130 | @Test 131 | public void testSearchSync() { 132 | try { 133 | HashMap params = new HashMap(); 134 | params.put("limit", new String[] {"10"}); 135 | String jsonString = client.search(37.761809d, -122.422832d, "casey.testing.layer", params); 136 | FeatureCollection featureCollection = FeatureCollection.fromJSONString(jsonString); 137 | 138 | Assert.assertNotNull(featureCollection.getFeatures()); 139 | } catch (IOException e) { 140 | Assert.fail(e.getMessage()); 141 | } catch (JSONException e) { 142 | Assert.fail(e.getMessage()); 143 | } 144 | } 145 | 146 | @Test 147 | public void testSearchByAddressSync() { 148 | try { 149 | HashMap params = new HashMap(); 150 | params.put("limit", new String[] {"10"}); 151 | String jsonString = client.searchByAddress("41 decatur st, san francisco, ca", "casey.testing.layer", params); 152 | FeatureCollection featureCollection = FeatureCollection.fromJSONString(jsonString); 153 | 154 | Assert.assertNotNull(featureCollection.getFeatures()); 155 | } catch (IOException e) { 156 | Assert.fail(e.getMessage()); 157 | } catch (JSONException e) { 158 | Assert.fail(e.getMessage()); 159 | } 160 | } 161 | 162 | @Test 163 | public void testSearchByIPSync() { 164 | try { 165 | String jsonString = client.searchByIP("173.164.219.53", "casey.testing.layer", null); 166 | FeatureCollection featureCollection = FeatureCollection.fromJSONString(jsonString); 167 | 168 | Assert.assertNotNull(featureCollection.getFeatures()); 169 | } catch (IOException e) { 170 | Assert.fail(e.getMessage()); 171 | } catch (JSONException e) { 172 | Assert.fail(e.getMessage()); 173 | } 174 | } 175 | 176 | @Test 177 | public void testSearchByMyIPSync() { 178 | try { 179 | String jsonString = client.searchByMyIP("casey.testing.layer", null); 180 | FeatureCollection featureCollection = FeatureCollection.fromJSONString(jsonString); 181 | 182 | Assert.assertNotNull(featureCollection.getFeatures()); 183 | } catch (IOException e) { 184 | Assert.fail(e.getMessage()); 185 | } catch (JSONException e) { 186 | Assert.fail(e.getMessage()); 187 | } 188 | } 189 | 190 | @Test 191 | public void testCreateLayerSync() { 192 | try { 193 | ArrayList urls = new ArrayList(); 194 | urls.add("http://example.com/callback/simplegeo"); 195 | 196 | Layer layer = new Layer("java.client.testing.layer", "Testing Layer", "This layer is for testing only", false, urls); 197 | String jsonString = client.createLayer(layer); 198 | JSONObject json = new JSONObject(jsonString); 199 | 200 | Assert.assertEquals("OK", json.get("status")); 201 | 202 | } catch (JSONException e) { 203 | Assert.fail(e.getMessage()); 204 | } catch (IOException e) { 205 | Assert.fail(e.getMessage()); 206 | } 207 | } 208 | 209 | @Test 210 | public void testUpdateLayerSync() { 211 | try { 212 | ArrayList urls = new ArrayList(); 213 | urls.add("http://example.com/callback/simplegeo"); 214 | 215 | Layer layer = new Layer("java.client.testing.layer", "Testing Layer", "This layer is for testing only", false, urls); 216 | String jsonString = client.updateLayer(layer); 217 | JSONObject json = new JSONObject(jsonString); 218 | 219 | Assert.assertEquals("OK", json.get("status")); 220 | 221 | } catch (JSONException e) { 222 | Assert.fail(e.getMessage()); 223 | } catch (IOException e) { 224 | Assert.fail(e.getMessage()); 225 | } 226 | } 227 | 228 | @Test 229 | public void testGetLayerSync() { 230 | try { 231 | String jsonString = client.getLayer("casey.testing.layer"); 232 | Layer layer = Layer.fromJSONString(jsonString); 233 | 234 | Assert.assertEquals("casey.testing.layer", layer.getName()); 235 | } catch (IOException e) { 236 | Assert.fail(e.getMessage()); 237 | } catch (JSONException e) { 238 | Assert.fail(e.getMessage()); 239 | } 240 | } 241 | 242 | @Test 243 | public void testGetLayersSync() { 244 | try { 245 | HashMap queryParams = new HashMap(); 246 | String jsonString = client.getLayers(queryParams); 247 | LayerCollection layers = LayerCollection.fromJSONString(jsonString); 248 | 249 | Assert.assertNotNull(layers.getLayers()); 250 | } catch (IOException e) { 251 | Assert.fail(e.getMessage()); 252 | } catch (JSONException e) { 253 | Assert.fail(e.getMessage()); 254 | } 255 | } 256 | } -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/test/TestEnvironment.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.test; 2 | 3 | public abstract class TestEnvironment { 4 | 5 | private static String ACCESS_KEY = "consumerKey"; 6 | private static String SECRET_KEY = "consumerSecret"; 7 | private static boolean PAID_ACCOUNT = false; 8 | 9 | private static final String JSON_POINT_STRING = "{\"geometry\": { \"type\": \"Point\",\"coordinates\": [-122.937467,47.046962]},\"type\": \"Feature\",\"id\": \"SG_4CsrE4oNy1gl8hCLdwu0F0_47.046962_-122.937467@1290636830\",\"properties\": {\"city\": \"Olympia\",\"name\": \"Burger Master West Olympia\",\"country\": \"us\",\"phone\": \"3603575451\",\"owner\": \"simplegeo\",\"state\": \"WA\",\"address\": \"2820 Harrison Ave NW\",\"postcode\": \"98502\"}}"; 10 | private static final String JSON_POINT_STRING_NO_ID = "{\"geometry\": { \"type\": \"Point\",\"coordinates\": [-122.937467,47.046962]},\"type\": \"Feature\",\"properties\": {\"city\": \"Olympia\",\"name\": \"Burger Mistress West Olympia\",\"country\": \"us\",\"phone\": \"3603575451\",\"owner\": \"simplegeo\",\"state\": \"WA\",\"address\": \"2820 Harrison Ave NW\",\"postcode\": \"98502\"}}"; 11 | private static final String JSON_POINT_BAD_STRING = "{\"geometry\": { \"type\": \"Point\",\"coordinates\": [-122.937467,47.046962]},\"type\": \"Feature\",\"id\": \"SG_4CsrE4oNy1gl8hCLdwu0F0_47.046962_-122.937467@1290636830\",\"properties\": {\"city\": \"Gildford\",\"name\": \"Burger Master West Olympia\",\"tags\": [\"eating\"],\"country\": \"us\",\"phone\": \"3603575451\",\"owner\": \"simplegeo\",\"state\": \"WA\",\"address\": \"2820 Harrison Ave NW\",\"categories\": [[\"Food & Drink\",\"Restaurants\",\"\"]],\"postcode\": \"98502\"}}"; 12 | private static final String JSON_POLYGON_STRING = "{\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-122.444406,37.759271],[-122.444291,37.759487],[-122.444127,37.759709],[-122.443135,37.760357],[-122.442843,37.760444],[-122.441282,37.76053],[-122.440682,37.76043],[-122.439282,37.76133],[-122.438082,37.76163],[-122.436982,37.76183],[-122.435882,37.76193],[-122.434982,37.762429],[-122.432982,37.764229],[-122.430982,37.765729],[-122.430682,37.765929],[-122.430382,37.766029],[-122.428882,37.767429],[-122.428482,37.766129],[-122.428382,37.764629],[-122.428328,37.763683],[-122.428277,37.762825],[-122.428182,37.762029],[-122.428082,37.761229],[-122.428082,37.76053],[-122.427882,37.75963],[-122.427882,37.75893],[-122.427782,37.75803],[-122.425582,37.75823],[-122.423082,37.75833],[-122.422344,37.758422],[-122.422282,37.75843],[-122.421382,37.75853],[-122.421282,37.75773],[-122.421282,37.75693],[-122.422186,37.756874],[-122.422991,37.756814],[-122.423615,37.756757],[-122.424182,37.75673],[-122.42479,37.756688],[-122.425482,37.75663],[-122.426682,37.75653],[-122.427782,37.75653],[-122.429882,37.75643],[-122.431582,37.75633],[-122.432102,37.756266],[-122.434386,37.756119],[-122.435374,37.756034],[-122.436516,37.755973],[-122.437597,37.755899],[-122.43752,37.75546],[-122.438682,37.75533],[-122.439682,37.75523],[-122.440282,37.75513],[-122.439882,37.75633],[-122.440219,37.756934],[-122.441403,37.75808],[-122.441961,37.758277],[-122.442982,37.75883],[-122.443482,37.75903],[-122.444406,37.759271]]]},\"type\":\"Feature\",\"properties\":{\"category\":\"Neighborhood\",\"license\":\"http://creativecommons.org/publicdomain/mark/1.0/\",\"handle\":\"SG_0Bw22I6fWoxnZ4GDc8YlXd_37.759737_-122.433203\",\"subcategory\":\"\",\"name\":\"Castro District\",\"type\":\"Boundary\",\"abbr\":\"\"},\"id\":\"SG_0Bw22I6fWoxnZ4GDc8YlXd\"}"; 13 | private static final String JSON_MULTIPOLYGON_STRING = "{\"geometry\": { \"type\": \"MultiPolygon\",\"coordinates\": [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]]},\"type\": \"Feature\",\"id\": \"SG_4CsrE4oNy1gl8hCLdwu0F0_47.046962_-122.937467@1290636830\",\"properties\": {\"city\": \"Olympia\",\"name\": \"Burger Master West Olympia\",\"tags\": [\"eating\"],\"country\": \"us\",\"phone\": \"3603575451\",\"owner\": \"simplegeo\",\"state\": \"WA\",\"address\": \"2820 Harrison Ave NW\",\"categories\": [[\"Food & Drink\",\"Restaurants\",\"\"]],\"postcode\": \"98502\"}}"; 14 | 15 | public static String getKey() throws Exception { 16 | if(ACCESS_KEY.equals("consumerKey")) { 17 | if (System.getenv("OAUTH_KEY") != null && !"".equals(System.getenv("OAUTH_KEY"))) { 18 | ACCESS_KEY = System.getenv("OAUTH_KEY"); 19 | } else { 20 | throw new Exception("Please replace ACCESS_KEY with a valid String or set the OAUTH_KEY environment var."); 21 | } 22 | } 23 | return ACCESS_KEY; 24 | } 25 | 26 | public static String getSecret() throws Exception { 27 | if(SECRET_KEY.equals("consumerSecret")) { 28 | if (System.getenv("OAUTH_SECRET") != null && !"".equals(System.getenv("OAUTH_SECRET"))) { 29 | SECRET_KEY = System.getenv("OAUTH_SECRET"); 30 | } else { 31 | throw new Exception("Please replace SECRET_KEY with a valid String or set the OAUTH_SECRET environment var."); 32 | } 33 | } 34 | return SECRET_KEY; 35 | } 36 | 37 | public static boolean isPaidAccount() { 38 | if (System.getenv("PAID_ACCOUNT") != null && !"".equals(System.getenv("PAID_ACCOUNT"))) { 39 | PAID_ACCOUNT = "true".equals(System.getenv("PAID_ACCOUNT")) ? true : false; 40 | } 41 | return PAID_ACCOUNT; 42 | } 43 | 44 | public static String getJsonPointString() { 45 | return JSON_POINT_STRING; 46 | } 47 | 48 | public static String getJsonPointStringNoId() { 49 | return JSON_POINT_STRING_NO_ID; 50 | } 51 | 52 | public static String getJsonPointBadString() { 53 | return JSON_POINT_BAD_STRING; 54 | } 55 | 56 | public static String getJsonPolygonString() { 57 | return JSON_POLYGON_STRING; 58 | } 59 | 60 | public static String getJsonMultipolygonString() { 61 | return JSON_MULTIPOLYGON_STRING; 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/types/FeatureTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import com.simplegeo.client.test.TestEnvironment; 9 | 10 | public class FeatureTest { 11 | 12 | @Test 13 | public void testFeatureConversionPoint() { 14 | try { 15 | String jsonString = TestEnvironment.getJsonPointString(); 16 | Feature feature = Feature.fromJSONString(jsonString); 17 | String featureString = feature.toJSONString(); 18 | JSONObject actual = new JSONObject(featureString); 19 | Assert.assertNotNull(actual.get("id")); 20 | Assert.assertNotNull(actual.get("properties")); 21 | Assert.assertNotNull(actual.get("type")); 22 | Assert.assertNotNull(actual.get("geometry")); 23 | } catch (JSONException e) { 24 | Assert.fail(e.getMessage()); 25 | } 26 | } 27 | 28 | @Test 29 | public void testFeatureConversionPolygon() { 30 | try { 31 | String jsonString = TestEnvironment.getJsonPolygonString(); 32 | Feature feature = Feature.fromJSONString(jsonString); 33 | String featureString = feature.toJSONString(); 34 | JSONObject actual = new JSONObject(featureString); 35 | Assert.assertNotNull(actual.get("id")); 36 | Assert.assertNotNull(actual.get("properties")); 37 | Assert.assertNotNull(actual.get("type")); 38 | Assert.assertNotNull(actual.get("geometry")); 39 | } catch (JSONException e) { 40 | Assert.fail(e.getMessage()); 41 | } 42 | } 43 | 44 | @Test 45 | public void testFeatureConversionMultiPolygon() { 46 | try { 47 | String jsonString = TestEnvironment.getJsonMultipolygonString(); 48 | Feature feature = Feature.fromJSONString(jsonString); 49 | String featureString = feature.toJSONString(); 50 | JSONObject actual = new JSONObject(featureString); 51 | Assert.assertNotNull(actual.get("id")); 52 | Assert.assertNotNull(actual.get("properties")); 53 | Assert.assertNotNull(actual.get("type")); 54 | Assert.assertNotNull(actual.get("geometry")); 55 | } catch (JSONException e) { 56 | Assert.fail(e.getMessage()); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/types/MultiPolygonTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | public class MultiPolygonTest { 11 | 12 | @Test 13 | public void testToJSONArray() { 14 | try { 15 | MultiPolygon multiPolygon = new MultiPolygon(); 16 | multiPolygon.getPolygons().add(this.generatePolygon()); 17 | multiPolygon.getPolygons().add(this.generatePolygon()); 18 | JSONArray jsonArray = multiPolygon.toJSONArray(); 19 | Assert.assertEquals(2, jsonArray.length()); 20 | Assert.assertEquals(5, jsonArray.getJSONArray(0).length()); 21 | Assert.assertEquals(5, jsonArray.getJSONArray(1).length()); 22 | } catch (JSONException e) { 23 | Assert.fail(e.getMessage()); 24 | } 25 | } 26 | 27 | @Test 28 | public void testFromJSONArray() { 29 | try { 30 | JSONArray jsonArray = new JSONArray("[[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]]"); 31 | MultiPolygon multiPolygon = MultiPolygon.fromJSONArray(jsonArray); 32 | Assert.assertEquals(2, multiPolygon.getPolygons().size()); 33 | Assert.assertEquals(1, multiPolygon.getPolygons().get(0).getRings().size()); 34 | Assert.assertEquals(2, multiPolygon.getPolygons().get(1).getRings().size()); 35 | } catch (JSONException e) { 36 | Assert.fail(e.getMessage()); 37 | } 38 | } 39 | 40 | private Polygon generatePolygon() { 41 | ArrayList> rings = new ArrayList>(); 42 | for (int i=0; i<5; i++) { 43 | rings.add(this.generateRing()); 44 | } 45 | return new Polygon(rings); 46 | } 47 | 48 | private ArrayList generateRing() { 49 | ArrayList ring = new ArrayList(); 50 | for (int i=0; i<5; i++) { 51 | ring.add(new Point(37.0, -110.0)); 52 | } 53 | return ring; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/types/PointTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class PointTest { 7 | 8 | @Test 9 | public void testNewPoint() { 10 | Point point = new Point(37.0, -105.0); 11 | Assert.assertEquals(37.0, point.getLat(), 0d); 12 | Assert.assertEquals(-105.0, point.getLon(), 0d); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/simplegeo/client/types/PolygonTest.java: -------------------------------------------------------------------------------- 1 | package com.simplegeo.client.types; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | public class PolygonTest { 11 | 12 | @Test 13 | public void testToJSONArray() { 14 | try { 15 | ArrayList> rings = new ArrayList>(); 16 | rings.add(this.generateRing()); 17 | Polygon polygon = new Polygon(rings); 18 | JSONArray jsonArray = polygon.toJSONArray(); 19 | Assert.assertEquals(1, jsonArray.length()); 20 | JSONArray ringArray = jsonArray.getJSONArray(0); 21 | Assert.assertEquals(5, ringArray.length()); 22 | } catch (JSONException e) { 23 | Assert.fail(e.getMessage()); 24 | } 25 | } 26 | 27 | @Test 28 | public void testToJSONArrayMultipleRings() { 29 | try { 30 | ArrayList> rings = new ArrayList>(); 31 | rings.add(this.generateRing()); 32 | rings.add(this.generateRing()); 33 | Polygon polygon = new Polygon(rings); 34 | JSONArray jsonArray = polygon.toJSONArray(); 35 | Assert.assertEquals(2, jsonArray.length()); 36 | JSONArray ringArray = jsonArray.getJSONArray(0); 37 | Assert.assertEquals(5, ringArray.length()); 38 | ringArray = jsonArray.getJSONArray(1); 39 | Assert.assertEquals(5, ringArray.length()); 40 | } catch (JSONException e) { 41 | Assert.fail(e.getMessage()); 42 | } 43 | } 44 | 45 | @Test 46 | public void testFromJSONArray() { 47 | try { 48 | JSONArray jsonArray = new JSONArray("[[[-122.444406,37.759271],[-122.444291,37.759487],[-122.444127,37.759709],[-122.443135,37.760357],[-122.442843,37.760444],[-122.441282,37.76053],[-122.440682,37.76043],[-122.439282,37.76133],[-122.438082,37.76163],[-122.436982,37.76183],[-122.435882,37.76193],[-122.434982,37.762429],[-122.432982,37.764229],[-122.430982,37.765729],[-122.430682,37.765929],[-122.430382,37.766029],[-122.428882,37.767429],[-122.428482,37.766129],[-122.428382,37.764629],[-122.428328,37.763683],[-122.428277,37.762825],[-122.428182,37.762029],[-122.428082,37.761229],[-122.428082,37.76053],[-122.427882,37.75963],[-122.427882,37.75893],[-122.427782,37.75803],[-122.425582,37.75823],[-122.423082,37.75833],[-122.422344,37.758422],[-122.422282,37.75843],[-122.421382,37.75853],[-122.421282,37.75773],[-122.421282,37.75693],[-122.422186,37.756874],[-122.422991,37.756814],[-122.423615,37.756757],[-122.424182,37.75673],[-122.42479,37.756688],[-122.425482,37.75663],[-122.426682,37.75653],[-122.427782,37.75653],[-122.429882,37.75643],[-122.431582,37.75633],[-122.432102,37.756266],[-122.434386,37.756119],[-122.435374,37.756034],[-122.436516,37.755973],[-122.437597,37.755899],[-122.43752,37.75546],[-122.438682,37.75533],[-122.439682,37.75523],[-122.440282,37.75513],[-122.439882,37.75633],[-122.440219,37.756934],[-122.441403,37.75808],[-122.441961,37.758277],[-122.442982,37.75883],[-122.443482,37.75903],[-122.444406,37.759271]]]"); 49 | Polygon polygon = Polygon.fromJSONArray(jsonArray); 50 | Assert.assertEquals(1, polygon.getRings().size()); 51 | ArrayList points = polygon.getRings().get(0); 52 | Assert.assertEquals(60, points.size()); 53 | } catch (JSONException e) { 54 | Assert.fail(e.getMessage()); 55 | } 56 | 57 | } 58 | 59 | @Test 60 | public void testFromJSONArrayMultipleRings() { 61 | try { 62 | JSONArray jsonArray = new JSONArray("[[[-122.444406,37.759271],[-122.444291,37.759487],[-122.444127,37.759709],[-122.443135,37.760357],[-122.442843,37.760444],[-122.441282,37.76053],[-122.440682,37.76043],[-122.439282,37.76133],[-122.438082,37.76163],[-122.436982,37.76183],[-122.435882,37.76193],[-122.434982,37.762429],[-122.432982,37.764229],[-122.430982,37.765729],[-122.430682,37.765929],[-122.430382,37.766029],[-122.428882,37.767429],[-122.428482,37.766129],[-122.428382,37.764629],[-122.428328,37.763683],[-122.428277,37.762825],[-122.428182,37.762029],[-122.428082,37.761229],[-122.428082,37.76053],[-122.427882,37.75963],[-122.427882,37.75893],[-122.427782,37.75803],[-122.425582,37.75823],[-122.423082,37.75833],[-122.422344,37.758422],[-122.422282,37.75843],[-122.421382,37.75853],[-122.421282,37.75773],[-122.421282,37.75693],[-122.422186,37.756874],[-122.422991,37.756814],[-122.423615,37.756757]],[[-122.424182,37.75673],[-122.42479,37.756688],[-122.425482,37.75663],[-122.426682,37.75653],[-122.427782,37.75653],[-122.429882,37.75643],[-122.431582,37.75633],[-122.432102,37.756266],[-122.434386,37.756119],[-122.435374,37.756034],[-122.436516,37.755973],[-122.437597,37.755899],[-122.43752,37.75546],[-122.438682,37.75533],[-122.439682,37.75523],[-122.440282,37.75513],[-122.439882,37.75633],[-122.440219,37.756934],[-122.441403,37.75808],[-122.441961,37.758277],[-122.442982,37.75883],[-122.443482,37.75903],[-122.444406,37.759271]]]"); 63 | Polygon polygon = Polygon.fromJSONArray(jsonArray); 64 | Assert.assertEquals(2, polygon.getRings().size()); 65 | ArrayList points = polygon.getRings().get(0); 66 | Assert.assertEquals(37, points.size()); 67 | ArrayList points2 = polygon.getRings().get(1); 68 | Assert.assertEquals(23, points2.size()); 69 | } catch (JSONException e) { 70 | Assert.fail(e.getMessage()); 71 | } 72 | } 73 | 74 | private ArrayList generateRing() { 75 | ArrayList ring = new ArrayList(); 76 | for (int i=0; i<5; i++) { 77 | ring.add(new Point(37.0, -110.0)); 78 | } 79 | return ring; 80 | } 81 | 82 | } 83 | --------------------------------------------------------------------------------