001/*
002 * Copyright (c) 2018 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2018-10-22 21:39:44 +0000 (Mon, 22 Oct 2018) $' 
007 * '$Revision: 34713 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029package org.kepler.gis.arcgis;
030
031import org.kepler.webview.server.WebViewServer;
032
033import io.vertx.core.AsyncResult;
034import io.vertx.core.Future;
035import io.vertx.core.Handler;
036import io.vertx.core.MultiMap;
037import io.vertx.core.json.JsonObject;
038import io.vertx.ext.web.client.WebClient;
039
040/** Utilities for working with ArcGIS FeatureService.
041 * 
042 *  @author Daniel Crawl
043 *  @version $Id: FeatureServiceUtilities.java 34713 2018-10-22 21:39:44Z crawl $ 
044 */
045public class FeatureServiceUtilities {
046
047    /** This class cannot be instantiated. */
048    private FeatureServiceUtilities() {}
049    
050    /** Add features to a feature service.
051     *  @param jsonStr The features to add in esri json format.
052     *  @param featureServiceUrlStr The url of the layer in the feature service.
053     *  @param userNameStr 
054     *  @param passwordStr
055     *  @param handler Asynchronous handler for the result. 
056     */
057    public static void addFeatures(String jsonStr,
058        String featureServiceUrlStr, String userNameStr, String passwordStr,
059        Handler<AsyncResult<String>> handler) {
060                
061        FeatureServiceUtilities.getAccessToken(userNameStr, passwordStr,
062            tokenResult -> {
063                if(tokenResult.failed()) {
064                    handler.handle(Future.failedFuture(tokenResult.cause()));
065                } else {
066                    _addFeatures(tokenResult.result(), jsonStr, featureServiceUrlStr, handler);                   
067                }
068            });                                
069    }
070    
071    /** Get an access token for ArcGIS. */
072    public static void getAccessToken(String userNameStr, String passwordStr,
073        Handler<AsyncResult<String>> handler) {
074               
075        /*
076        MultiMap form = MultiMap.caseInsensitiveMultiMap()
077            .add("client_id", clientIdStr)
078            .add("client_secret", clientSecretStr)
079            .add("grant_type", "client_credentials");
080         */
081        
082        MultiMap form = MultiMap.caseInsensitiveMultiMap()
083            .add("username", userNameStr)
084            .add("password", passwordStr)
085            .add("referer", _refererUrlStr);
086
087        WebClient client = WebClient.create(WebViewServer.vertx());
088        client.postAbs(_generateTokenUrlStr)
089            .sendForm(form, result -> {
090                //System.out.println(result.result().bodyAsString());
091                if(result.failed()) {
092                    handler.handle(Future.failedFuture(result.cause()));                   
093                } else {
094                    JsonObject json = result.result().bodyAsJsonObject();
095                    if(!json.containsKey("token")) {
096                        handler.handle(Future.failedFuture("Missing access_token in response."));
097                    } else {
098                        handler.handle(Future.succeededFuture(json.getString("token")));
099                    }
100                }
101            });        
102    }
103
104    /** Add features to a service. */
105    private static void _addFeatures(String tokenStr, String jsonStr,
106            String featureServiceUrlStr, Handler<AsyncResult<String>> handler) {
107        
108        MultiMap form = MultiMap.caseInsensitiveMultiMap()
109            // get response in json
110            .add("f", "json")
111            .add("adds", jsonStr)
112            .add("token", tokenStr);
113        
114        //System.out.println(featureServiceUrlStr);
115        //System.out.println(jsonStr);
116        
117        WebClient client = WebClient.create(WebViewServer.vertx());
118        client.postAbs(featureServiceUrlStr + "/applyEdits")
119            .sendForm(form, response -> {
120                System.out.println(response.result().bodyAsString());
121                JsonObject responseJson = response.result().bodyAsJsonObject();
122                if(response.failed() || responseJson.containsKey("error")) {
123                    handler.handle(Future.failedFuture(response.cause()));                   
124                } else {
125                    handler.handle(Future.succeededFuture());
126                }
127            });        
128    }
129    
130
131    /** REST URL for generating tokens. */
132    private final static String _generateTokenUrlStr = "https://www.arcgis.com/sharing/rest/generateToken?f=json";
133    
134    /** Referer URL when getting token. */
135    private final static String _refererUrlStr = "https://www.arcgis.com/";
136}