001/*
002 *  $URL: svn://svn.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/tools/RestRequester.java $
003 *  $Author: tgutwin $
004 *  $Revision: 1211 $
005 *  $Date: 2018-03-02 22:01:06 -0800 (Fri, 02 Mar 2018) $
006 */
007/*
008 *
009 *  Written by Tom Gutwin - WebARTS Design.
010 *  Copyright (C) 2014 WebARTS Design, North Vancouver Canada
011 *  http://www.webarts.ca
012 *
013 *  This program is free software; you can redistribute it and/or modify
014 *  it under the terms of the GNU General Public License as published by
015 *  the Free Software Foundation; version 3 of the License, or
016 *  (at your option) any later version.
017 *
018 *  This program is distributed in the hope that it will be useful,
019 *  but WITHOUT ANY WARRANTY; without_ even the implied warranty of
020 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
021 *  GNU General Public License for more details.
022 *
023 *  You should have received a copy of the GNU General Public License
024 *  along with this program; if not, write to the Free Software
025 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
026 */
027
028package ca.bc.webarts.tools;
029
030import java.io.BufferedReader;
031import java.io.IOException;
032import java.io.InputStreamReader;
033import java.io.File;
034import java.lang.StringBuilder;
035import java.net.HttpURLConnection;
036import java.net.MalformedURLException;
037import java.net.URL;
038import java.net.URLEncoder;
039
040//import android.util.Base64;
041import org.apache.commons.codec.binary.Base64;
042
043import ca.bc.webarts.widgets.Util;
044
045
046/** A class to encapsulate the calls to Restful Web Services. It is kept very basic with low overhead to live in android apps.
047 **/
048public class RestRequester
049{
050  protected static String CLASSNAME = "ca.bc.webarts.tools.RestRequester"; //ca.bc.webarts.widgets.Util.getCurrentClassName();
051  public static final String LOG_TAG = CLASSNAME;
052  protected static boolean debugOut_ = false;
053
054  /**  A holder for this clients System File Separator.  */
055  public final static String SYSTEM_FILE_SEPERATOR = File.separator;
056
057  /**  A holder for this clients System line termination separator.  */
058  public final static String SYSTEM_LINE_SEPERATOR =
059                                           System.getProperty("line.separator");
060
061  protected static String baseUrl_ = ""; // http://isy994
062  public static boolean authenticating_ = true;
063  protected static String username_ = "";
064  protected static String password_ = "";
065  protected static boolean acceptJSON_ = false;
066
067  public static final String USER_AGENT = "WebARTS RestRequester / "+ "$Revision: 1211 $";
068
069  public void setUsername(String uName){username_=uName;}
070  public void setPassword(String uPasswd){password_=uPasswd;}
071  public void setBaseUrl(String url){baseUrl_=url;}
072  public void setAcceptJSON(boolean acceptJson){acceptJSON_=acceptJson;}
073  public String getUsername(){return username_;}
074  public String getPassword(){return password_;}
075  public String getBaseUrl(){return baseUrl_;}
076  public boolean getAcceptJSON(){return acceptJSON_;}
077
078
079  public RestRequester()
080  {
081  }
082
083
084  public RestRequester(String baseUrl)
085  {
086    setBaseUrl( baseUrl);
087    authenticating_=false;
088  }
089
090
091  public RestRequester(String baseUrl,String uName,String uPasswd)
092  {
093    setBaseUrl( baseUrl);
094    authenticating_=true;
095    setUsername( uName);
096    setPassword( uPasswd);
097  }
098
099
100  public boolean isInit()
101  {
102    boolean retVal = true;
103    if( baseUrl_.equals("") ||
104        (authenticating_ &&
105            (username_.equals("") || password_.equals(""))
106        )
107      )
108      retVal=false;
109    return retVal;
110  }
111
112
113  /** Stitches together the URL that will get sent as the fuul service request. **/
114  public String getServiceUrl(String serviceStr){return baseUrl_+serviceStr;}
115
116
117  /** Sends the rest service GET request off and returns the results.
118    * @param serviceName is the service (string) to append to the baseURL - example /rest/sys
119    * @return the serviceResult as a stringBuilder, null if error
120    **/
121  public StringBuilder serviceGet(String  serviceName)
122  { return callService(serviceName, true);}
123
124
125  /** Sends the rest service POST request off and retruns the results.
126    * @param serviceName is the service (string) to append to the baseURL - example /rest/sys
127    * @return the serviceResult as a stringBuilder, null if error
128    **/
129  public StringBuilder servicePost(String  serviceName)
130  { return callService(serviceName, false);}
131
132
133  /** Sends the rest service request off and returns the results.
134    * @param serviceName is the service (string) to append to the baseURL - example /rest/sys
135    * @param getNotPost is a flag to tell this method to do a get or post based on this flag - true does a GET, false does a POST
136    * @return the serviceResult as a stringBuilder, null if error
137   **/
138  public StringBuilder callService(String  serviceName, boolean getNotPost){ return callService(baseUrl_, serviceName, getNotPost);}
139  public StringBuilder callService(String  baseUrl, String  serviceName, boolean getNotPost)
140  {
141    StringBuilder retVal = null;
142    if(isInit())
143      try
144      {
145        String usrlStr = (baseUrl+serviceName).replace(" " ,"%20");
146        URL url = new URL(usrlStr);
147        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
148        if(getNotPost)
149          conn.setRequestMethod("GET");
150        else
151          conn.setRequestMethod("POST");
152        if(acceptJSON_)
153          conn.setRequestProperty("Accept", "application/json");
154        else
155          conn.setRequestProperty("Accept", "application/xml");
156
157        conn.setRequestProperty("User-Agent", USER_AGENT+" ( tgutwin@webarts.ca )");
158
159        //BASE64Encoder enc = new sun.misc.BASE64Encoder();
160        String userpassword = username_ + ":" + password_;
161        //String encodedAuthorization = android.util.Base64.encodeToString( userpassword.getBytes(), android.util.Base64.DEFAULT );
162        String encodedAuthorization = new String(Base64.encodeBase64( (userpassword.getBytes()) ));
163        conn.setRequestProperty("Authorization", "Basic "+ encodedAuthorization);
164
165        if (debugOut_) System.out.println("callService to: "+usrlStr);
166        if (debugOut_) System.out.println("         with : "+userpassword);
167        if (conn.getResponseCode() == 200)
168        {
169          BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
170          if (br!=null)
171          {
172            retVal = new StringBuilder();
173            String output;
174            if (debugOut_) System.out.println("Output from Server .... \n");
175            while ((output = br.readLine()) != null)
176            {
177              if (debugOut_) System.out.println(output);
178              retVal.append(output);
179              retVal.append("\n");
180            }
181          }
182        } // valid http response code
183        else
184        {
185          if (debugOut_) System.out.println("\n*!*! Rest Connection error: "+conn.getResponseCode());
186        }
187        conn.disconnect();
188      }
189      catch (MalformedURLException e)
190      {
191        e.printStackTrace();
192      }
193      catch (IOException e)
194      {
195        e.printStackTrace();
196      }
197    return retVal;
198  }
199
200
201  private String cleanJSON(StringBuilder sb)
202  {
203    String retVal = sb.toString();
204    retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+"   ,", ",");
205    retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+"  ,", ",");
206    retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+" ,", ",");
207    retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+",", ",");
208    return retVal;
209  }
210
211
212  /** Indents/spaces out an XML result. **/
213  public StringBuilder responseIndenter(StringBuilder sb)
214  {
215    StringBuilder retVal = new StringBuilder("");
216    if (sb!=null)
217    {
218      int indent = -1;
219      boolean opening = false;
220      boolean closing = false;
221      boolean lf = false;
222      char [] sbChar = sb.toString().toCharArray();
223
224      for (int i=0; i< sbChar.length;i++)
225      {
226        opening = false;
227        closing = false;
228        lf = false;
229        if ((sbChar[i]=='<'&&sbChar[i+1]=='/') )
230        {
231          retVal.append("\n");
232          for (int j=0;j<indent;j++) retVal.append("  ");
233          retVal.append(sbChar[i]);
234          indent--; //indent--;
235        }
236        else if(sbChar[i]=='<')
237        {
238          indent++;
239          retVal.append("\n");
240          for (int j=0;j<indent;j++) retVal.append("  ");
241          retVal.append(sbChar[i]);
242        }
243        else if ((sbChar[i]=='/'&&sbChar[i+1]=='>') )
244        {
245          indent--; //indent--;
246          retVal.append(sbChar[i]);
247        }
248        else if (sbChar[i]=='>')
249        {
250          retVal.append(sbChar[i]);
251          //for (int j=0;j<indent;j++) retVal.append("  ");
252        }
253        else if (sbChar[i]!='\n')
254        {
255          retVal.append(sbChar[i]);
256        }
257      }
258    }
259    return retVal;
260  }
261
262}