/** * Add the HTTP header field associated with the provided key and value. * * @param key The header's key. * @param value The header's value. * @throws ParseException if anything goes wrong. */ public void addHeader(final String key, final String value) throws ParseException { try { headers.put(key, value); } catch (JSONException ex) { Logger.getInstance().error("Unable to add header. Error: " + ex); throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } }
public void init(Object context) { // Pro users - uncomment this code to get crash reports sent to you automatically /*Display.getInstance().addEdtErrorHandler(new ActionListener() { public void actionPerformed(ActionEvent evt) { evt.consume(); Log.p("Exception in AppName version " + Display.getInstance().getProperty("AppVersion", "Unknown")); Log.p("OS " + Display.getInstance().getPlatformName()); Log.p("Error " + evt.getSource()); Log.p("Current Form " + Display.getInstance().getCurrent().getName()); Log.e((Throwable)evt.getSource()); Log.sendLog(); } });*/ Logger.getInstance().setLogLevel(Log.DEBUG); }
/** * Performs this ParseCommand by issuing a synchronous network request. * * @return The response received if the request was successful. * @throws ParseException if anything goes wrong. */ public ParseResponse perform() throws ParseException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Data to be sent: " + data.toString()); } long commandStart = System.currentTimeMillis(); final ParseResponse response = new ParseResponse(); final ConnectionRequest request = createConnectionRequest(response); setUpRequest(request); if (progressCallback != null) { NetworkManager.getInstance() .addProgressListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { if (evt instanceof NetworkEvent) { final NetworkEvent networkEvent = (NetworkEvent) evt; if (request.equals(networkEvent.getConnectionRequest())) { int progressPercentage = networkEvent.getProgressPercentage(); if (progressPercentage >= 0) { progressCallback.done(progressPercentage); } } } } }); } Iterator keys = headers.keys(); while (keys.hasNext()) { final String key = (String) keys.next(); try { request.addRequestHeader(key, (String) headers.get(key)); } catch (JSONException ex) { Logger.getInstance().error("Error parsing header '" + key + "' + Error: " + ex); throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } keys = data.keys(); while (keys.hasNext()) { final String key = (String) keys.next(); if (!REQUEST_BODY_KEY.equals(key)) { try { request.addArgument(key, data.get(key).toString()); } catch (JSONException ex) { Logger.getInstance() .error("Error parsing key '" + key + "' in command data. Error: " + ex); throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } } NetworkManager.getInstance().addToQueueAndWait(request); response.extractResponseData(request); long commandReceived = System.currentTimeMillis(); if (LOGGER.isDebugEnabled()) { LOGGER.debug( "Parse " + request.getHttpMethod() + " Command took " + (commandReceived - commandStart) + " milliseconds\n"); } return response; }
/** * This class encapsulates a network request to be made to the Parse REST API using any of the * supported HTTP verbs. */ public abstract class ParseCommand { private static final Logger LOGGER = Logger.getInstance(); private static final String REQUEST_BODY_KEY = "data"; private final JSONObject data = new JSONObject(); private final JSONObject headers = new JSONObject(); private ProgressCallback progressCallback; protected boolean addJson; /** * Sets up the network connection request that will be issued when performing this operation. * Typically, that involves specifying the HTTP verb, headers, url, content type, etc. * * <p>This method is invoked by {@link #perform()}. * * @param request The request to be initialized. * @throws ParseException if anything goes wrong. */ abstract void setUpRequest(final ConnectionRequest request) throws ParseException; /** * Performs this ParseCommand by issuing a synchronous network request. * * @return The response received if the request was successful. * @throws ParseException if anything goes wrong. */ public ParseResponse perform() throws ParseException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Data to be sent: " + data.toString()); } long commandStart = System.currentTimeMillis(); final ParseResponse response = new ParseResponse(); final ConnectionRequest request = createConnectionRequest(response); setUpRequest(request); if (progressCallback != null) { NetworkManager.getInstance() .addProgressListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { if (evt instanceof NetworkEvent) { final NetworkEvent networkEvent = (NetworkEvent) evt; if (request.equals(networkEvent.getConnectionRequest())) { int progressPercentage = networkEvent.getProgressPercentage(); if (progressPercentage >= 0) { progressCallback.done(progressPercentage); } } } } }); } Iterator keys = headers.keys(); while (keys.hasNext()) { final String key = (String) keys.next(); try { request.addRequestHeader(key, (String) headers.get(key)); } catch (JSONException ex) { Logger.getInstance().error("Error parsing header '" + key + "' + Error: " + ex); throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } keys = data.keys(); while (keys.hasNext()) { final String key = (String) keys.next(); if (!REQUEST_BODY_KEY.equals(key)) { try { request.addArgument(key, data.get(key).toString()); } catch (JSONException ex) { Logger.getInstance() .error("Error parsing key '" + key + "' in command data. Error: " + ex); throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } } NetworkManager.getInstance().addToQueueAndWait(request); response.extractResponseData(request); long commandReceived = System.currentTimeMillis(); if (LOGGER.isDebugEnabled()) { LOGGER.debug( "Parse " + request.getHttpMethod() + " Command took " + (commandReceived - commandStart) + " milliseconds\n"); } return response; } /** * Add the HTTP header field associated with the provided key and value. * * @param key The header's key. * @param value The header's value. * @throws ParseException if anything goes wrong. */ public void addHeader(final String key, final String value) throws ParseException { try { headers.put(key, value); } catch (JSONException ex) { Logger.getInstance().error("Unable to add header. Error: " + ex); throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } /** * Creates and initializes a network connection request. * * @param response The response associated with the request. This response object will be updated * with the error information if the request fails. * @return The created connection request. */ protected ConnectionRequest createConnectionRequest(final ParseResponse response) { ConnectionRequest request = new ConnectionRequest() { @Override protected void handleErrorResponseCode(int code, String message) { response.setConnectionError(code, message); } @Override protected void handleException(Exception err) { response.setConnectionError( new ParseException( ParseException.CONNECTION_FAILED, ParseException.ERR_NETWORK, err)); } @Override protected void buildRequestBody(OutputStream os) throws IOException { if (data.has(REQUEST_BODY_KEY)) { try { os.write(data.get(REQUEST_BODY_KEY).toString().getBytes("UTF-8")); } catch (JSONException ex) { throw new IllegalArgumentException( "Unable to read request body from json object. Error:" + ex.getMessage()); } } else { super.buildRequestBody(os); } } }; request.setReadResponseForErrors(true); return request; } /** * Adds the default headers (e.g., {@link ParseConstants#HEADER_APPLICATION_ID} and {@link * ParseConstants#HEADER_CLIENT_KEY}) associated with Parse REST API calls. * * @param addJson If true, the corresponding content-type header field is also set. * @throws ParseException if anything goes wrong. */ protected void setupDefaultHeaders(boolean addJson) throws ParseException { try { headers.put(ParseConstants.HEADER_APPLICATION_ID, Parse.getApplicationId()); headers.put(ParseConstants.HEADER_CLIENT_KEY, Parse.getClientKey()); if (addJson) { headers.put(ParseConstants.HEADER_CONTENT_TYPE, ParseConstants.CONTENT_TYPE_JSON); } if (!data.has(ParseConstants.FIELD_SESSION_TOKEN) && ParseUser.getCurrent() != null) { data.put(ParseConstants.FIELD_SESSION_TOKEN, ParseUser.getCurrent().getSessionToken()); } if (data.has(ParseConstants.FIELD_SESSION_TOKEN)) { headers.put( ParseConstants.HEADER_SESSION_TOKEN, data.getString(ParseConstants.FIELD_SESSION_TOKEN)); } } catch (JSONException ex) { throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } /** * Create a Parse API URL using the provided data. * * @param endPoint The end point * @param objectId The optional objectId * @return The Parse API URL of the format {@code https://api.parse.com/<endpoint>[/<objectId>]}. */ protected static String getUrl(final String endPoint, final String objectId) { String url = Parse.getParseAPIUrl(endPoint) + (objectId != null ? "/" + objectId : ""); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Request URL: " + url); } return url; } /** * Sets the message body data for the HTTP request. * * @param data The message body to be set. * @throws ParseException if anything goes wrong. */ public void setMessageBody(JSONObject data) throws ParseException { try { this.data.put(REQUEST_BODY_KEY, data); } catch (JSONException ex) { throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } /** * Adds the specified key-value pair as an argument to the HTTP request. * * @param key The key of the argument. * @param value The value for {@code key}. * @throws ParseException if anything goes wrong. */ public void addArgument(final String key, final String value) throws ParseException { try { this.data.put(key, value); } catch (JSONException ex) { throw new ParseException( ParseException.INVALID_JSON, ParseException.ERR_PREPARING_REQUEST, ex); } } /** * Sets a callback to be notified of the progress of this command when it is performed. * * @param progressCallback The callback to be set. It will replace any previously set callback. */ public void setProgressCallback(final ProgressCallback progressCallback) { this.progressCallback = progressCallback; } }
private void checkForPushMessages() { final String pushReceivedInBackgroundError = Preferences.get(StateMachine.KEY_APP_IN_BACKGROUND_PUSH_ERROR, null); if (pushReceivedInBackgroundError != null) { Logger.getInstance() .error( "Apparently an error occurred while processing a push message " + "received while the app was in background:\n\n" + pushReceivedInBackgroundError); Display.getInstance() .callSerially( new Runnable() { public void run() { Dialog.show( "Error", "Apparently an error occurred while processing a push message " + "received while the app was in background:\n\n" + pushReceivedInBackgroundError, Dialog.TYPE_ERROR, null, "OK", null); Preferences.set(StateMachine.KEY_APP_IN_BACKGROUND_PUSH_ERROR, null); } }); } else { final String pushReceivedInBackground = Preferences.get(StateMachine.KEY_APP_IN_BACKGROUND_PUSH_PAYLOAD, null); if (pushReceivedInBackground != null) { Logger.getInstance() .info( "The following push messages were " + "received while the app was in background:\n\n" + pushReceivedInBackground); Display.getInstance() .callSerially( new Runnable() { public void run() { Dialog.show( "Push received (background)", "The following push messages were received while the app was in background:\n\n" + pushReceivedInBackground, "OK", null); Preferences.set(StateMachine.KEY_APP_IN_BACKGROUND_PUSH_PAYLOAD, null); } }); } } if (ParsePush.isAppOpenedViaPushNotification()) { Logger.getInstance().info("App opened via push notification"); try { final JSONObject pushPayload = ParsePush.getPushDataUsedToOpenApp(); Display.getInstance() .callSerially( new Runnable() { public void run() { Dialog.show( "App opened via push", "The app was opened via clicking a push notification with payload:\n\n" + pushPayload.toString(), "OK", null); ParsePush.resetPushDataUsedToOpenApp(); } }); } catch (final ParseException ex) { Display.getInstance() .callSerially( new Runnable() { public void run() { Dialog.show( "Error", "An error occured while trying to retrieve " + "push payload used to open app.\n\n" + "Error: " + ex.getMessage(), Dialog.TYPE_ERROR, null, "OK", null); } }); } } else { Logger.getInstance().info("App opened normally"); } if (ParsePush.isUnprocessedPushDataAvailable()) { Logger.getInstance().info("Unprocessed push data available"); try { final JSONArray pushPayload = ParsePush.getUnprocessedPushData(); Display.getInstance() .callSerially( new Runnable() { public void run() { Dialog.show( "Unprocessed push data", "The following unprocessed push message(s) were " + "possibly received while the app was not running:\n\n" + pushPayload.toString(), "OK", null); ParsePush.resetUnprocessedPushData(); } }); } catch (final ParseException ex) { Display.getInstance() .callSerially( new Runnable() { public void run() { Dialog.show( "Error", "An error occured while trying to retrieve " + "unprocessed push payload.\n\n" + "Error: " + ex.getMessage(), Dialog.TYPE_ERROR, null, "OK", null); } }); } } else { Logger.getInstance().info("No unprocessed push data found"); } }