/** * Copyright (C) 2012 cogroo <cogroo@cogroo.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.cogroo.addon.util; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.cogroo.addon.CogrooException; import org.cogroo.addon.CogrooExceptionMessages; import org.cogroo.addon.LoggerImpl; import org.cogroo.addon.i18n.I18nLabelsLoader; public class RestUtil { protected static Logger LOG = LoggerImpl.getLogger(RestUtil.class.getCanonicalName()); public String get(String urlRoot, String path) throws CogrooException { return execute("GET", urlRoot, path, null); } public Map<String, String> post(String urlRoot, String path, Map<String, String> data) throws CogrooException { return extractResponse(execute("POST", urlRoot, path, convert(data))); } private String __userAgent = null; private String getUserAgent() { synchronized(this) { if(__userAgent == null) { StringBuilder sb = new StringBuilder(); sb.append("CoGrOO/" + I18nLabelsLoader.ADDON_VERSION + " "); sb.append("(" + System.getProperty("os.name") + " " + System.getProperty("os.version") + "; " + System.getProperty("os.arch") + ") "); __userAgent = sb.toString(); } } return __userAgent; } public String execute(String method, String urlRoot, String path, String urlParameters) throws CogrooException { URL url = null; HttpURLConnection connection = null; try { // Create connection url = toUrl(urlRoot, path); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod(method); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Language", "en-US"); connection.setRequestProperty ( "User-agent", getUserAgent()); connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(true); if (urlParameters != null) { connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length)); // Send request DataOutputStream wr = new DataOutputStream( connection.getOutputStream()); wr.writeBytes(urlParameters); wr.flush(); wr.close(); } // Get Response InputStream is = connection.getInputStream(); BufferedReader rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); String line; StringBuffer response = new StringBuffer(); while ((line = rd.readLine()) != null) { response.append(line); response.append('\r'); } rd.close(); return response.toString(); } catch (ConnectException e) { LOG.log(Level.SEVERE, "Couldn't connect to host. Is it online? URL: " + url + " method: " + method, e); throw new RestConnectionException(CogrooExceptionMessages.COMMUNITY_CONNECT_EXCEPTION, null); } catch (IOException e) { LOG.log(Level.SEVERE, "Communication error. URL: " + url + " method: " + method, e); throw new CogrooException(CogrooExceptionMessages.COMMUNITY_COMMUNICATION_EXCEPTION, new String[]{url.toString(), method}); } finally { if (connection != null) { connection.disconnect(); } } } private static final Pattern imgSrc = Pattern.compile("<img\\s+id=\"gaMobileTrackingCode\"\\s+src=\"([^\"]+)\".*"); public void getGAImg(String urlRoot, String path) throws CogrooException { try { String resp = get(urlRoot, path); if (resp != null) { Matcher m = imgSrc.matcher(resp); if (m.find()) { String respImg = get(urlRoot, m.group(1)); if (respImg == null) { LOG.log(Level.WARNING, "Couldn't get GA img! Get image returned null"); } } } else { LOG.log(Level.WARNING, "Couldn't get GA img!"); } } catch (Exception e) { // just log, we don't care if it fail. LOG.log(Level.WARNING, "Couldn't get GA img!", e); } } private static URL toUrl(String urlRoot, String path) throws MalformedURLException { return new URL(urlRoot + "/" + path); } private static String convert(Map<String, String> data) { StringBuilder sb = new StringBuilder(); for (String key : data.keySet()) { sb.append(encode(key) + "=" + encode(data.get(key))); sb.append("&"); } return sb.subSequence(0, sb.length() - 1).toString(); } private static String encode(String text) { try { return URLEncoder.encode(text, "UTF-8"); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); } return null; } private static final Pattern responsePattern = Pattern.compile("\\$\\{(.*?)\\|(.*?)\\}&"); // response have the format: // ${key|value}& // one response per line public static String prepareResponse(String key, String data) { return "${" + key + "|" + data + "}&"; } public static Map<String, String> extractResponse(String response) { Map<String, String> data = new HashMap<String, String>(); Matcher theMatcher = responsePattern.matcher(response); while (theMatcher.find()) { data.put(theMatcher.group(1), theMatcher.group(2)); } return data; } }