Java tutorial
/* * Copyright 2011 Roman Stepanenko * * 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 brainleg.app.util; import brainleg.app.api.SearchResults; import brainleg.app.api.UserInfoResponse; import brainleg.app.intellij.BLSettingsService; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.net.HttpConfigurable; import brainleg.app.engine.EData; import brainleg.app.engine.Generator; import brainleg.app.exception.RequestRejectedException; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import java.io.*; import java.net.HttpURLConnection; import java.net.URLEncoder; import java.util.Arrays; import java.util.Iterator; import java.util.List; /** * Responsible for working with the BrainLeg website. * * @author Roman Stepanenko */ public class AppWeb { /** * Returns null if there was a communication error. * * @param userAuthToken * @return */ public static UserInfoResponse getUserInfo(String userAuthToken) { try { Gson gson = new Gson(); String jsonText = get( getUrl("api/getUserInfo?apiToken=" + (userAuthToken == null ? "" : userAuthToken.trim()))); UserInfoResponse response = gson.fromJson(jsonText, UserInfoResponse.class); return response; } catch (IOException e) { return null; } } /** * Returns true if success, false otherwise. * @param solution * @param snippet * @param exception * @return */ public static boolean submitSolution(String solution, String snippet, EData exception) { String exceptionString = Generator.generateStringForWebSubmission(exception, BLSettingsService.getSettings().sendExceptionMessage, BLSettingsService.getSettings().sendFullTraces); try { post(getUrl("api/submitSolution"), new NameValuePair[] { new NameValuePair("clientId", "intellij"), new NameValuePair("clientVer", AppUtil.getPluginVersion()), new NameValuePair("userAPIToken", BLSettingsService.getSettings().userAuthToken == null ? "" : BLSettingsService.getSettings().userAuthToken.trim()), new NameValuePair("exception", exceptionString), new NameValuePair("solution", solution), new NameValuePair("snippet", snippet) }); return true; } catch (RequestRejectedException e) { if ("USER_NOT_FOUND".equals(e.getResponseCode())) { Messages.showMessageDialog( "The user token does not match your website profile. Please open BrainLeg settings and update it", "Incorrect user token", Messages.getInformationIcon()); } else { Messages.showMessageDialog( "Connected to server but request was rejected: " + e.getResponseCode() + ":" + e.getResponseMessage(), "Request rejected by the server", Messages.getInformationIcon()); } return false; } catch (IOException e) { System.out.println("Can't connect to the server: " + e.getMessage()); Messages.showMessageDialog("Can't connect to the server", "Connection Problem", Messages.getInformationIcon()); return false; } } public static void sendQueryAndOpenBrowser(EData exception) { String searchString = generateExceptionStringForSearchViaApi(exception); try { //stack trace can be too big to send via GET //so we first send the exception via POST, the server responds with a temp request token //and then we open browser with a short url containing this token String requestToken = post(getUrl("api/submitSearch"), new NameValuePair[] { new NameValuePair("plugin", "intellij"), new NameValuePair("version", AppUtil.getPluginVersion()), new NameValuePair("exception", searchString) }); BrowserUtil.launchBrowser(getUrl("api/search?token=" + requestToken)); } catch (RequestRejectedException e) { Messages.showMessageDialog("Connected to server but request was rejected", "Request rejected by the server", Messages.getInformationIcon()); } catch (IOException e) { Messages.showMessageDialog("Can't connect to the server", "Connection Problem", Messages.getInformationIcon()); } } public static void openSearchResultsInBrowser(String requestToken) { BrowserUtil.launchBrowser(getUrl("api/searchInBrowser?token=" + requestToken)); } public static SearchResults sendQuery(EData exception, boolean isAutomaticSearch) { String searchString = generateExceptionStringForSearchViaApi(exception); try { //stack trace can be too big to send via GET //so we first send the exception via POST, String jsonText = post(getUrl("api/intellijSearch"), new NameValuePair[] { new NameValuePair("plugin", "intellij"), new NameValuePair("version", AppUtil.getPluginVersion()), new NameValuePair("exception", searchString), new NameValuePair("automatic", "" + isAutomaticSearch) }); Gson gson = new Gson(); SearchResults response = gson.fromJson(jsonText, SearchResults.class); return response; } catch (RequestRejectedException e) { System.out.println("Connected to server but request was rejected"); return null; } catch (IOException e) { System.out.println("Can't connect to the server: " + e.getMessage()); return null; } } private static String generateExceptionStringForSearchViaApi(EData exception) { return Generator.generateStringForWebSubmission(exception, BLSettingsService.getSettings().sendExceptionMessage, BLSettingsService.getSettings().sendFullTraces); } public static String post(String url, NameValuePair[] postParameters) throws RequestRejectedException, IOException { HttpConfigurable.getInstance().prepareURL(getUrl("api/proxyTest")); HttpURLConnection connection = doPost(url, join(Arrays.asList(postParameters))); int responseCode = connection.getResponseCode(); String responseText; InputStream is = new BufferedInputStream(connection.getInputStream()); try { responseText = readFrom(is); } finally { is.close(); } if (responseCode != HttpURLConnection.HTTP_OK) { // if this is 400 this is an application error (something is rejected by the app) if (responseCode == 400 && responseText != null) { //normally we return error messages like this: REQUIRED_PARAM_MISSING:Required parameters missing List<String> tokens = Lists .newArrayList(Splitter.on(":").omitEmptyStrings().trimResults().split(responseText)); if (tokens.isEmpty()) { throw new RequestRejectedException(); } else if (tokens.size() == 1) { throw new RequestRejectedException(tokens.get(0), null); } else { throw new RequestRejectedException(tokens.get(0), tokens.get(1)); } } else { throw new IOException("response code from server: " + responseCode); } } else { return responseText; } } public static String get(String url) throws IOException { GetMethod get = null; try { HttpConfigurable.getInstance().prepareURL(getUrl("api/proxyTest")); HttpClient httpclient = new HttpClient(); get = new GetMethod(url); httpclient.executeMethod(get); String responseBody = get.getResponseBodyAsString(); return responseBody; } finally { if (get != null) { get.releaseConnection(); } } } /** * Copied from ITNProxy * @param params * @return * @throws UnsupportedEncodingException */ private static byte[] join(List<NameValuePair> params) throws UnsupportedEncodingException { StringBuilder builder = new StringBuilder(); Iterator<NameValuePair> it = params.iterator(); while (it.hasNext()) { NameValuePair param = it.next(); if (StringUtil.isEmpty(param.getName())) throw new IllegalArgumentException(param.toString()); if (StringUtil.isNotEmpty(param.getValue())) builder.append(param.getName()).append("=").append(URLEncoder.encode(param.getValue(), ENCODING)); if (it.hasNext()) builder.append(POST_DELIMITER); } return builder.toString().getBytes(); } private static String readFrom(InputStream is) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); int c; while ((c = is.read()) != -1) { out.write(c); } String s = out.toString(); out.close(); return s; } /** * Copied from ITNProxy */ private static HttpURLConnection doPost(String url, byte[] bytes) throws IOException { HttpURLConnection connection = (HttpURLConnection) HttpConfigurable.getInstance().openConnection(url); connection.setReadTimeout(60 * 1000); connection.setConnectTimeout(10 * 1000); connection.setRequestMethod(HTTP_POST); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestProperty(HTTP_CONTENT_TYPE, String.format("%s; charset=%s", HTTP_WWW_FORM, ENCODING)); connection.setRequestProperty(HTTP_CONTENT_LENGTH, Integer.toString(bytes.length)); OutputStream out = new BufferedOutputStream(connection.getOutputStream()); try { out.write(bytes); out.flush(); } finally { out.close(); } return connection; } private static String getUrl(String uri) { // return "http://localhost:8080/app/" + uri; return "http://www.brainleg.com/" + uri; } public static final String ENCODING = "UTF8"; public static final String POST_DELIMITER = "&"; public static final String HTTP_CONTENT_LENGTH = "Content-Length"; public static final String HTTP_CONTENT_TYPE = "Content-Type"; public static final String HTTP_WWW_FORM = "application/x-www-form-urlencoded"; public static final String HTTP_POST = "POST"; }