├── .gitignore ├── .travis.yml ├── README.md ├── pom.xml └── src ├── main └── java │ └── org │ └── parse4j │ ├── Parse.java │ ├── ParseAnalytics.java │ ├── ParseBatch.java │ ├── ParseClassName.java │ ├── ParseCloud.java │ ├── ParseConstants.java │ ├── ParseDecoder.java │ ├── ParseException.java │ ├── ParseExecutor.java │ ├── ParseFile.java │ ├── ParseGeoPoint.java │ ├── ParseObject.java │ ├── ParsePush.java │ ├── ParseQuery.java │ ├── ParseRelation.java │ ├── ParseRole.java │ ├── ParseUser.java │ ├── bolts │ ├── AggregateException.java │ ├── Capture.java │ ├── Continuation.java │ └── Task.java │ ├── callback │ ├── CountCallback.java │ ├── DeleteCallback.java │ ├── FindCallback.java │ ├── FunctionCallback.java │ ├── GetCallback.java │ ├── GetDataCallback.java │ ├── LocationCallback.java │ ├── LoginCallback.java │ ├── ParseCallback.java │ ├── ProgressCallback.java │ ├── RequestPasswordResetCallback.java │ ├── SaveCallback.java │ ├── SendCallback.java │ └── SignUpCallback.java │ ├── command │ ├── ParseBatchCommand.java │ ├── ParseCommand.java │ ├── ParseDeleteCommand.java │ ├── ParseGetCommand.java │ ├── ParsePostCommand.java │ ├── ParsePutCommand.java │ ├── ParseResponse.java │ └── ParseUploadCommand.java │ ├── encode │ ├── ParseObjectEncodingStrategy.java │ ├── PointerEncodingStrategy.java │ └── PointerOrLocalIdEncodingStrategy.java │ ├── http │ └── CountingHttpEntity.java │ ├── operation │ ├── AddOperation.java │ ├── AddUniqueOperation.java │ ├── DeleteFieldOperation.java │ ├── IncrementFieldOperation.java │ ├── OperationUtil.java │ ├── ParseFieldOperation.java │ ├── ParseFieldOperations.java │ ├── RelationOperation.java │ ├── RemoveFieldOperation.java │ └── SetFieldOperation.java │ └── util │ ├── MimeType.java │ ├── ParseEncoder.java │ ├── ParseRegistry.java │ └── Preconditions.java └── test ├── java └── org │ └── parse4j │ ├── Parse4JTestCase.java │ ├── ParseAnalyticsTestCase.java │ ├── ParseBatchTestCase.java │ ├── ParseCloudTestCase.java │ ├── ParseDecoderTestCase.java │ ├── ParseFileTestCase.java │ ├── ParseObjectCRUDTestCase.java │ ├── ParseObjectCustomTest.java │ ├── ParseObjectOperationsTestCase.java │ ├── ParseQueryTestCase.java │ ├── ParseRelationTestCase.java │ ├── ParseUserTestCase.java │ ├── bolts │ ├── TestBolts.java │ └── TestTask.java │ └── custom │ ├── Person.java │ └── Person2.java └── resources ├── parse.docx ├── parse.exr ├── parse.jpg ├── parse.pdf └── parse.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .classpath 3 | .project 4 | .settings/ 5 | bin/ 6 | .externalToolBuilders/ 7 | .springBeans 8 | 9 | # Intellij 10 | .idea/ 11 | *.iml 12 | *.iws 13 | 14 | # Mac 15 | .DS_Store 16 | 17 | # Maven 18 | log/ 19 | target/ 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | - openjdk6 5 | script: 6 | - mvn test -Dmaven.test.skip=false 7 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.github.thiagolocatelli 5 | parse4j 6 | 1.5-SNAPSHOT 7 | jar 8 | parse4j 9 | https://github.com/thiagolocatelli/parse4j 10 | 11 | 12 | org.sonatype.oss 13 | oss-parent 14 | 7 15 | 16 | 17 | 18 | 19 | The Apache Software License, Version 2.0 20 | http://www.apache.org/licenses/LICENSE-2.0.txt 21 | repo 22 | 23 | 24 | 25 | 26 | 27 | parse4j 28 | Thiago Locatelli 29 | thiago.locatelli@gmail.com 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 39 | scm:git:git@github.com:thiagolocatelli/parse4j.git 40 | scm:git:git@github.com:thiagolocatelli/parse4j.git 41 | git@github.com:thiagolocatelli/parse4j.git 42 | 43 | 44 | 45 | true 46 | false 47 | false 48 | 1.6 49 | UTF-8 50 | UTF-8 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.slf4j 58 | slf4j-api 59 | 1.6.1 60 | jar 61 | compile 62 | 63 | 64 | 65 | org.apache.httpcomponents 66 | httpclient 67 | 4.3.2 68 | 69 | 70 | 71 | org.apache.httpcomponents 72 | httpcore 73 | 4.3.1 74 | 75 | 76 | 77 | org.json 78 | json 79 | 20131018 80 | 81 | 82 | 83 | commons-codec 84 | commons-codec 85 | 1.9 86 | 87 | 88 | 89 | 90 | 91 | junit 92 | junit 93 | 4.11 94 | test 95 | 96 | 97 | 98 | ch.qos.logback 99 | logback-classic 100 | 0.9.28 101 | jar 102 | test 103 | 104 | 105 | 106 | ch.qos.logback 107 | logback-core 108 | 0.9.28 109 | jar 110 | test 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | org.apache.maven.plugins 120 | maven-compiler-plugin 121 | 3.1 122 | 123 | UTF-8 124 | 1.6 125 | 1.6 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | release-sign-artifacts 136 | 137 | 138 | performRelease 139 | true 140 | 141 | 142 | 143 | 144 | 145 | 146 | org.apache.maven.plugins 147 | maven-compiler-plugin 148 | 3.1 149 | 150 | UTF-8 151 | 1.6 152 | 1.6 153 | 154 | 155 | 156 | org.apache.maven.plugins 157 | maven-gpg-plugin 158 | 159 | 160 | sign-artifacts 161 | verify 162 | 163 | sign 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/Parse.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONObject; 5 | import org.parse4j.operation.ParseFieldOperations; 6 | import org.parse4j.util.ParseRegistry; 7 | 8 | import java.text.DateFormat; 9 | import java.text.ParseException; 10 | import java.text.SimpleDateFormat; 11 | import java.util.*; 12 | 13 | public class Parse { 14 | 15 | private static String mApplicationId; 16 | private static String mRestAPIKey; 17 | private static String mMasterKey; 18 | private static final DateFormat dateFormat; 19 | private static boolean isRootMode; 20 | private static String sServerPath; 21 | private static boolean bCustomServer; 22 | 23 | static { 24 | DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 25 | format.setTimeZone(new SimpleTimeZone(0, "GMT")); 26 | dateFormat = format; 27 | ParseRegistry.registerDefaultSubClasses(); 28 | ParseFieldOperations.registerDefaultDecoders(); 29 | } 30 | 31 | static public void initialize(String applicationId, String restAPIKey) { 32 | mApplicationId = applicationId; 33 | mRestAPIKey = restAPIKey; 34 | isRootMode = false; 35 | bCustomServer = false; 36 | } 37 | 38 | static public void initialize(String applicationId, String restAPIKey, String serverPath) { 39 | mApplicationId = applicationId; 40 | mRestAPIKey = restAPIKey; 41 | isRootMode = false; 42 | sServerPath = serverPath; 43 | bCustomServer = true; 44 | } 45 | 46 | /** 47 | * Don't use it in client app! Use it only if know what you are doing. 48 | * If someone get your master key he can bypass all of your app's security! 49 | * 50 | * @param applicationId your app id 51 | * @param masterKey your master key 52 | */ 53 | static public void initializeAsRoot (String applicationId, String masterKey) { 54 | mApplicationId = applicationId; 55 | mMasterKey = masterKey; 56 | isRootMode = true; 57 | } 58 | 59 | static public String getApplicationId() { 60 | return mApplicationId; 61 | } 62 | 63 | static public String getRestAPIKey() { 64 | return mRestAPIKey; 65 | } 66 | 67 | public static boolean isIsRootMode() { 68 | return isRootMode; 69 | } 70 | 71 | static public String getParseAPIUrl(String context) { 72 | if(bCustomServer){ 73 | return sServerPath + "/" + context; 74 | }else{ 75 | return ParseConstants.API_ENDPOINT + "/" + ParseConstants.API_VERSION 76 | + "/" + context; 77 | } 78 | } 79 | 80 | public static synchronized String encodeDate(Date date) { 81 | return dateFormat.format(date); 82 | } 83 | 84 | public static synchronized Date parseDate(String dateString) { 85 | try { 86 | return dateFormat.parse(dateString); 87 | } catch (ParseException e) { 88 | return null; 89 | } 90 | } 91 | 92 | public static String getMasterKey() { 93 | return mMasterKey; 94 | } 95 | 96 | public static boolean isInvalidKey(String key) { 97 | return "objectId".equals(key) || "createdAt".equals(key) 98 | || "updatedAt".equals(key); 99 | } 100 | 101 | public static boolean isValidType(Object value) { 102 | return ((value instanceof JSONObject)) 103 | || ((value instanceof JSONArray)) 104 | || ((value instanceof String)) 105 | || ((value instanceof Number)) 106 | || ((value instanceof Boolean)) 107 | || (value == JSONObject.NULL) 108 | || ((value instanceof ParseObject)) 109 | // || ((value instanceof ParseACL)) 110 | || ((value instanceof ParseFile)) 111 | || ((value instanceof ParseRelation)) 112 | || ((value instanceof ParseGeoPoint)) 113 | || ((value instanceof Date)) 114 | || ((value instanceof byte[])) 115 | || ((value instanceof List)) 116 | || ((value instanceof Map)); 117 | } 118 | 119 | @SuppressWarnings("rawtypes") 120 | public static String join(Collection items, String delimiter) { 121 | StringBuffer buffer = new StringBuffer(); 122 | Iterator iter = items.iterator(); 123 | if (iter.hasNext()) { 124 | buffer.append((String) iter.next()); 125 | while (iter.hasNext()) { 126 | buffer.append(delimiter); 127 | buffer.append((String) iter.next()); 128 | } 129 | } 130 | return buffer.toString(); 131 | } 132 | 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseAnalytics.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.Date; 4 | import java.util.Map; 5 | 6 | import org.json.JSONObject; 7 | import org.parse4j.command.ParsePostCommand; 8 | import org.parse4j.command.ParseResponse; 9 | import org.parse4j.util.ParseEncoder; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | public class ParseAnalytics { 14 | 15 | private static Logger LOGGER = LoggerFactory.getLogger(ParseAnalytics.class); 16 | 17 | public static void trackAppOpened() { 18 | trackEvent("AppOpened"); 19 | } 20 | 21 | public static void trackEvent(String name) { 22 | trackEvent(name, null); 23 | } 24 | 25 | public static void trackEvent(String name, Map dimensions) { 26 | 27 | if ((name == null) || (name.trim().length() == 0)) { 28 | LOGGER.error("A name for the custom event must be provided."); 29 | throw new RuntimeException( 30 | "A name for the custom event must be provided."); 31 | } 32 | 33 | class TrackEventInBackgroundThread extends Thread { 34 | 35 | private String event; 36 | private Map dimensions; 37 | 38 | public TrackEventInBackgroundThread(String event, 39 | Map dimensions) { 40 | this.event = event; 41 | this.dimensions = dimensions; 42 | } 43 | 44 | public void run() { 45 | ParsePostCommand command = new ParsePostCommand("events", event); 46 | JSONObject data = new JSONObject(); 47 | data.put("at", ParseEncoder.encode(new Date(), null)); 48 | if(dimensions != null && dimensions.size() > 0) { 49 | data.put("dimentions", ParseEncoder.encode(dimensions, null)); 50 | } 51 | command.setData(data); 52 | try { 53 | ParseResponse response = command.perform(); 54 | if (response.isFailed()) { 55 | throw response.getException(); 56 | } 57 | else { 58 | System.out.println("done"); 59 | } 60 | } catch (ParseException pe) { 61 | System.out.println(pe); 62 | } 63 | } 64 | } 65 | 66 | TrackEventInBackgroundThread event = new TrackEventInBackgroundThread( 67 | name, dimensions); 68 | ParseExecutor.runInBackground(event); 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseBatch.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONObject; 5 | import org.json.JSONTokener; 6 | import org.parse4j.command.ParseBatchCommand; 7 | import org.parse4j.command.ParseCommand; 8 | import org.parse4j.command.ParseResponse; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | /** 12 | * Main class used for sending batch requests 13 | * @author Nikolay Rusev 14 | * 15 | */ 16 | public class ParseBatch { 17 | private static final String path = "/" + ParseConstants.API_VERSION + "/"+ "classes" + "/"; 18 | private JSONArray data = new JSONArray(); 19 | 20 | private static Logger LOGGER = LoggerFactory.getLogger(ParseBatch.class); 21 | 22 | public void deleteObject(ParseObject obj) { 23 | if (obj.getObjectId() == null) 24 | throw new IllegalArgumentException("for delete operation your object should provide objectId"); 25 | JSONObject inner = new JSONObject(); 26 | inner.put("path", path + obj.getClassName() + "/" + obj.getObjectId()); 27 | inner.put("method", "DELETE"); 28 | inner.put("body", obj.getParseData()); 29 | data.put(inner); 30 | } 31 | 32 | public void createObject(ParseObject obj) { 33 | JSONObject inner = new JSONObject(); 34 | inner.put("path", path + obj.getClassName()); 35 | inner.put("method", "POST"); 36 | inner.put("body", obj.getParseData()); 37 | data.put(inner); 38 | } 39 | 40 | public void updateObject(ParseObject obj) { 41 | if (obj.getObjectId() == null) 42 | throw new IllegalArgumentException("for update operation your object should provide objectId"); 43 | JSONObject inner = new JSONObject(); 44 | inner.put("path", path + obj.getClassName() + "/" + obj.getObjectId()); 45 | inner.put("method", "PUT"); 46 | inner.put("body", obj.getParseData()); 47 | data.put(inner); 48 | } 49 | /** 50 | * from Parse.com-> 51 | * The response from batch will be a list with the same number of elements as the input list. 52 | * Each item in the list with be a dictionary with either the success or error field set. 53 | * @return array of json objects corresponding to every passed object if it is successfully created 54 | * @throws ParseException 55 | */ 56 | public JSONArray batch() throws ParseException { 57 | ParseCommand command = new ParseBatchCommand(); 58 | command.put("requests", data); 59 | ParseResponse response = command.perform(); 60 | if (!response.isFailed()) { 61 | Object json = new JSONTokener(response.getRawResponseBody()).nextValue(); 62 | if (json instanceof JSONArray) { 63 | JSONArray jsonResponse = (JSONArray) json; 64 | LOGGER.info("response is " + jsonResponse); 65 | return jsonResponse; 66 | } 67 | //if the response is not array there is an error 68 | LOGGER.error("Error response"); 69 | throw response.getException(); 70 | } else { 71 | LOGGER.error("Error while sending batch request"); 72 | throw response.getException(); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseClassName.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.lang.annotation.Inherited; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target({java.lang.annotation.ElementType.TYPE}) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Inherited 11 | public @interface ParseClassName { 12 | public abstract String value(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseCloud.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.Map; 4 | 5 | import org.json.JSONObject; 6 | import org.parse4j.callback.FunctionCallback; 7 | import org.parse4j.command.ParsePostCommand; 8 | import org.parse4j.command.ParseResponse; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class ParseCloud { 13 | 14 | private static Logger LOGGER = LoggerFactory.getLogger(ParseCloud.class); 15 | 16 | @SuppressWarnings("unchecked") 17 | public static T callFunction(String name, Map params) 18 | throws ParseException { 19 | 20 | T result = null; 21 | ParsePostCommand command = new ParsePostCommand("functions", name); 22 | command.setData(new JSONObject(params)); 23 | ParseResponse response = command.perform(); 24 | 25 | if(!response.isFailed()) { 26 | JSONObject jsonResponse = response.getJsonObject(); 27 | result = (T) jsonResponse.get("result"); 28 | return result; 29 | } 30 | else { 31 | LOGGER.debug("Request failed."); 32 | throw response.getException(); 33 | } 34 | 35 | } 36 | 37 | public static void callFunctionInBackground(String name, 38 | Map params, FunctionCallback callback) { 39 | 40 | CallFunctionInBackgroundThread task = new CallFunctionInBackgroundThread(name, params, callback); 41 | ParseExecutor.runInBackground(task); 42 | } 43 | 44 | private static class CallFunctionInBackgroundThread extends Thread { 45 | Map params; 46 | FunctionCallback functionCallback; 47 | String name; 48 | 49 | public CallFunctionInBackgroundThread(String name, Map params, FunctionCallback functionCallback) { 50 | this.functionCallback = functionCallback; 51 | this.params = params; 52 | this.name = name; 53 | } 54 | 55 | public void run() { 56 | ParseException exception = null; 57 | T result = null; 58 | try { 59 | result = callFunction(name, params); 60 | } catch (ParseException e) { 61 | LOGGER.debug("Request failed {}", e.getMessage()); 62 | exception = e; 63 | } 64 | if (functionCallback != null) { 65 | functionCallback.done(result, exception); 66 | } 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseConstants.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | public class ParseConstants { 4 | 5 | public static final String API_ENDPOINT = "https://api.parse.com"; 6 | public static final String API_VERSION = "1"; 7 | 8 | public static final String HEADER_CONTENT_TYPE = "Content-Type"; 9 | public static final String HEADER_APPLICATION_ID = "X-Parse-Application-Id"; 10 | public static final String HEADER_REST_API_KEY = "X-Parse-REST-API-Key"; 11 | public static final String HEADER_MASTER_KEY = "X-Parse-Master-Key"; 12 | public static final String HEADER_SESSION_TOKEN = "X-Parse-Session-Token"; 13 | 14 | public static final String CONTENT_TYPE_JSON = "application/json"; 15 | 16 | public static final String FIELD_OBJECT_ID = "objectId"; 17 | public static final String FIELD_CREATED_AT = "createdAt"; 18 | public static final String FIELD_UPDATED_AT = "updatedAt"; 19 | public static final String FIELD_SESSION_TOKEN = "sessionToken"; 20 | 21 | 22 | public static int MAX_PARSE_FILE_SIZE = 10485760; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseDecoder.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import org.apache.commons.codec.binary.Base64; 10 | import org.json.JSONArray; 11 | import org.json.JSONException; 12 | import org.json.JSONObject; 13 | import org.parse4j.operation.ParseFieldOperations; 14 | 15 | public class ParseDecoder { 16 | 17 | @SuppressWarnings("rawtypes") 18 | public static Object decode(Object object) { 19 | 20 | if ((object instanceof JSONArray)) { 21 | return convertJSONArrayToList((JSONArray) object); 22 | } 23 | 24 | if (!(object instanceof JSONObject)) { 25 | return object; 26 | } 27 | 28 | JSONObject jsonObject = (JSONObject) object; 29 | 30 | String typeString = jsonObject.optString("__type", null); 31 | if (typeString == null) { 32 | return convertJSONObjectToMap(jsonObject); 33 | } 34 | 35 | if (typeString.equals("Date")) { 36 | String iso = jsonObject.optString("iso"); 37 | return Parse.parseDate(iso); 38 | } 39 | 40 | if (typeString.equals("Bytes")) { 41 | String base64 = jsonObject.optString("base64"); 42 | return Base64.decodeBase64(base64); 43 | } 44 | 45 | if (typeString.equals("Pointer")) { 46 | return decodePointer(jsonObject.optString("className"), 47 | jsonObject.optString("objectId")); 48 | } 49 | 50 | if (typeString.equals("File")) { 51 | return new ParseFile(jsonObject.optString("name"), 52 | jsonObject.optString("url")); 53 | } 54 | 55 | if (typeString.equals("GeoPoint")) { 56 | double latitude, longitude; 57 | try { 58 | latitude = jsonObject.getDouble("latitude"); 59 | longitude = jsonObject.getDouble("longitude"); 60 | } catch (JSONException e) { 61 | throw new RuntimeException(e); 62 | } 63 | return new ParseGeoPoint(latitude, longitude); 64 | } 65 | 66 | if (typeString.equals("Relation")) { 67 | return new ParseRelation(jsonObject); 68 | } 69 | 70 | if (typeString.equals("Object")) { 71 | return convertJSONObjectToParseObject(jsonObject); 72 | } 73 | 74 | String opString = jsonObject.optString("__op", null); 75 | if (opString != null) { 76 | try { 77 | return ParseFieldOperations.decode(jsonObject); 78 | } catch (JSONException e) { 79 | throw new RuntimeException(e); 80 | } 81 | } 82 | 83 | return null; 84 | 85 | } 86 | 87 | private static ParseObject convertJSONObjectToParseObject(JSONObject jsonObject) { 88 | if (jsonObject == null) return null; 89 | ParseObject parseObject = ParseObject.createWithoutData(jsonObject.optString("className"), 90 | jsonObject.optString("objectId")); 91 | parseObject.setData(jsonObject, true); 92 | return parseObject; 93 | } 94 | 95 | private static ParseObject decodePointer(String className, String objectId) { 96 | return ParseObject.createWithoutData(className, objectId); 97 | } 98 | 99 | private static List convertJSONArrayToList(JSONArray array) { 100 | List list = new ArrayList(); 101 | for (int i = 0; i < array.length(); i++) { 102 | list.add(decode(array.opt(i))); 103 | } 104 | return list; 105 | } 106 | 107 | private static Map convertJSONObjectToMap(JSONObject object) { 108 | Map outputMap = new HashMap(); 109 | Iterator it = object.keys(); 110 | while (it.hasNext()) { 111 | String key = (String) it.next(); 112 | Object value = object.opt(key); 113 | outputMap.put(key, decode(value)); 114 | } 115 | return outputMap; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseException.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | public class ParseException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public static final int OTHER_CAUSE = -1; 8 | public static final int INTERNAL_SERVER_ERROR = 1; 9 | public static final int CONNECTION_FAILED = 100; 10 | public static final int OBJECT_NOT_FOUND = 101; 11 | public static final int INVALID_QUERY = 102; 12 | public static final int INVALID_CLASS_NAME = 103; 13 | public static final int MISSING_OBJECT_ID = 104; 14 | public static final int INVALID_KEY_NAME = 105; 15 | public static final int INVALID_POINTER = 106; 16 | public static final int INVALID_JSON = 107; 17 | public static final int COMMAND_UNAVAILABLE = 108; 18 | public static final int NOT_INITIALIZED = 109; 19 | public static final int INCORRECT_TYPE = 111; 20 | public static final int INVALID_CHANNEL_NAME = 112; 21 | public static final int PUSH_MISCONFIGURED = 115; 22 | public static final int OBJECT_TOO_LARGE = 116; 23 | public static final int OPERATION_FORBIDDEN = 119; 24 | public static final int CACHE_MISS = 120; 25 | public static final int INVALID_NESTED_KEY = 121; 26 | public static final int INVALID_FILE_NAME = 122; 27 | public static final int INVALID_ACL = 123; 28 | public static final int TIMEOUT = 124; 29 | public static final int INVALID_EMAIL_ADDRESS = 125; 30 | public static final int DUPLICATE_VALUE = 137; 31 | public static final int INVALID_ROLE_NAME = 139; 32 | public static final int EXCEEDED_QUOTA = 140; 33 | public static final int CLOUD_ERROR = 141; 34 | public static final int USERNAME_MISSING = 200; 35 | public static final int PASSWORD_MISSING = 201; 36 | public static final int USERNAME_TAKEN = 202; 37 | public static final int EMAIL_TAKEN = 203; 38 | public static final int EMAIL_MISSING = 204; 39 | public static final int EMAIL_NOT_FOUND = 205; 40 | public static final int SESSION_MISSING = 206; 41 | public static final int MUST_CREATE_USER_THROUGH_SIGNUP = 207; 42 | public static final int ACCOUNT_ALREADY_LINKED = 208; 43 | public static final int LINKED_ID_MISSING = 250; 44 | public static final int INVALID_LINKED_SESSION = 251; 45 | public static final int UNSUPPORTED_SERVICE = 252; 46 | public static final int TOO_MANY_COMMANDS_IN_BATCH_REQUEST = 154; 47 | 48 | private int code; 49 | 50 | public ParseException(int theCode, String theMessage, 51 | Throwable causeThrowable) { 52 | this(theCode, theMessage + " Cause: " + causeThrowable.getMessage()); 53 | } 54 | 55 | public ParseException(int theCode, String theMessage) { 56 | super(theMessage); 57 | this.code = theCode; 58 | } 59 | 60 | public ParseException(String message, Throwable cause) { 61 | super(message, cause); 62 | this.code = -1; 63 | } 64 | 65 | public ParseException(Throwable cause) { 66 | super(cause); 67 | this.code = -1; 68 | } 69 | 70 | public int getCode() { 71 | return this.code; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "ParseException [code=" + code + ", error=" 77 | + getMessage() + "]"; 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseExecutor.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | public class ParseExecutor { 7 | 8 | private static ExecutorService executor; 9 | 10 | static { 11 | executor = Executors.newFixedThreadPool(10); 12 | } 13 | 14 | public static void runInBackground(Runnable runnable) { 15 | executor.execute(runnable); 16 | } 17 | 18 | public static ExecutorService getExecutor() { 19 | return executor; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseFile.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | 7 | import org.apache.http.Header; 8 | import org.apache.http.HttpResponse; 9 | import org.apache.http.client.ClientProtocolException; 10 | import org.apache.http.client.HttpClient; 11 | import org.apache.http.client.methods.HttpGet; 12 | import org.apache.http.impl.client.DefaultHttpClient; 13 | import org.json.JSONObject; 14 | import org.parse4j.callback.GetDataCallback; 15 | import org.parse4j.callback.ProgressCallback; 16 | import org.parse4j.callback.SaveCallback; 17 | import org.parse4j.command.ParseResponse; 18 | import org.parse4j.command.ParseUploadCommand; 19 | import org.parse4j.util.MimeType; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | 23 | @SuppressWarnings("deprecation") 24 | public class ParseFile { 25 | 26 | private static Logger LOGGER = LoggerFactory.getLogger(ParseFile.class); 27 | 28 | private String endPoint; 29 | private boolean uplodated = false; 30 | private boolean dirty = false; 31 | private String name = null; 32 | private String url = null; 33 | private String contentType = null; 34 | byte[] data; 35 | 36 | public ParseFile(String name, byte[] data, String contentType) { 37 | if (data.length > ParseConstants.MAX_PARSE_FILE_SIZE) { 38 | LOGGER.error(String.format( 39 | "ParseFile must be less than %i bytes, current %i", 40 | new Object[] { 41 | Integer.valueOf(ParseConstants.MAX_PARSE_FILE_SIZE), 42 | data.length })); 43 | throw new IllegalArgumentException( 44 | String.format( 45 | "ParseFile must be less than %i bytes, current %i", 46 | new Object[] { 47 | Integer.valueOf(ParseConstants.MAX_PARSE_FILE_SIZE), 48 | data.length })); 49 | } 50 | 51 | this.endPoint = "files/" + name; 52 | this.name = name; 53 | this.data = data; 54 | this.contentType = contentType; 55 | this.dirty = true; 56 | } 57 | 58 | public ParseFile(byte[] data) { 59 | this(null, data, null); 60 | } 61 | 62 | public ParseFile(String name, byte[] data) { 63 | this(name, data, null); 64 | } 65 | 66 | public ParseFile(byte[] data, String contentType) { 67 | this(null, data, contentType); 68 | } 69 | 70 | public ParseFile(String name, String url) { 71 | this.name = name; 72 | this.url = url; 73 | } 74 | 75 | public boolean isDirty() { 76 | return dirty; 77 | } 78 | 79 | public void setDirty(boolean dirty) { 80 | this.dirty = dirty; 81 | } 82 | 83 | public String getName() { 84 | return name; 85 | } 86 | 87 | public void setName(String name) { 88 | this.name = name; 89 | } 90 | 91 | public String getUrl() { 92 | return url; 93 | } 94 | 95 | public void setUrl(String url) { 96 | this.url = url; 97 | } 98 | 99 | public String getContentType() { 100 | return contentType; 101 | } 102 | 103 | public void setContentType(String contentType) { 104 | this.contentType = contentType; 105 | } 106 | 107 | public void setData(byte[] data) { 108 | this.data = data; 109 | } 110 | 111 | protected String getEndPoint() { 112 | return this.endPoint; 113 | } 114 | 115 | public boolean isUploaded() { 116 | return uplodated; 117 | } 118 | 119 | public void save() throws ParseException { 120 | save(null, null); 121 | } 122 | 123 | public void save(SaveCallback saveCallback) throws ParseException { 124 | save(saveCallback, null); 125 | } 126 | 127 | public void save(ProgressCallback progressCallback) throws ParseException { 128 | save(null, progressCallback); 129 | } 130 | 131 | public void save(SaveCallback saveCallback, 132 | ProgressCallback progressCallback) throws ParseException { 133 | 134 | if(!isDirty() || data == null) return; 135 | 136 | ParseUploadCommand command = new ParseUploadCommand(getEndPoint()); 137 | command.setProgressCallback(progressCallback); 138 | command.setData(data); 139 | if(getContentType() == null) { 140 | String fileExtension = MimeType.getFileExtension(getName()); 141 | contentType = MimeType.getMimeType(fileExtension); 142 | command.setContentType(contentType); 143 | } 144 | else { 145 | command.setContentType(getContentType()); 146 | } 147 | ParseResponse response = command.perform(); 148 | if(!response.isFailed()) { 149 | JSONObject jsonResponse = response.getJsonObject(); 150 | if (jsonResponse == null) { 151 | LOGGER.error("Empty response."); 152 | throw response.getException(); 153 | } 154 | LOGGER.info(jsonResponse.toString()); 155 | 156 | this.name = jsonResponse.getString("name"); 157 | this.url = jsonResponse.getString("url"); 158 | this.dirty = false; 159 | this.uplodated = true; 160 | 161 | } 162 | else { 163 | LOGGER.error("Request failed."); 164 | throw response.getException(); 165 | } 166 | 167 | } 168 | 169 | public void saveInBackground() { 170 | saveInBackground(null, null); 171 | } 172 | 173 | public void saveInBackground(SaveCallback saveCallback) { 174 | saveInBackground(saveCallback, null); 175 | } 176 | 177 | public void saveInBackground(ProgressCallback progressCallback) { 178 | saveInBackground(null, progressCallback); 179 | } 180 | 181 | public void saveInBackground(SaveCallback saveCallback, 182 | ProgressCallback progressCallback) { 183 | 184 | SaveInBackgroundThread task = new SaveInBackgroundThread(saveCallback, 185 | progressCallback); 186 | ParseExecutor.runInBackground(task); 187 | 188 | } 189 | 190 | public byte[] getData() throws ParseException { 191 | 192 | HttpGet get = new HttpGet(url); 193 | HttpClient client = new DefaultHttpClient(); 194 | 195 | HttpResponse response; 196 | try { 197 | response = client.execute(get); 198 | int totalSize = -1; 199 | Header[] contentLengthHeader = response 200 | .getHeaders("Content-Length"); 201 | if (contentLengthHeader.length > 0) { 202 | totalSize = Integer.parseInt(contentLengthHeader[0].getValue()); 203 | LOGGER.debug("File size: {}", totalSize); 204 | } 205 | int downloadedSize = 0; 206 | InputStream responseStream = response.getEntity().getContent(); 207 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 208 | byte[] data = new byte[32768]; 209 | int nRead; 210 | while ((nRead = responseStream.read(data, 0, data.length)) != -1) { 211 | buffer.write(data, 0, nRead); 212 | downloadedSize += nRead; 213 | LOGGER.debug("Downloaded: {}", downloadedSize); 214 | } 215 | 216 | responseStream.close(); 217 | buffer.close(); 218 | return buffer.toByteArray(); 219 | } 220 | catch(ClientProtocolException cpe) { 221 | throw new ParseException(100, "bad protocol: " + cpe.getClass().getName() + ": " + cpe.getMessage()); 222 | } catch (IOException e) { 223 | throw new ParseException(100, "i/o failure: " + e.getClass().getName() + ": " + e.getMessage()); 224 | } 225 | finally { 226 | //client.close(); 227 | } 228 | 229 | } 230 | 231 | public void getData(GetDataCallback dataCallback) throws ParseException { 232 | 233 | try { 234 | byte[] result = getData(); 235 | dataCallback.done(result, null); 236 | } 237 | catch(ParseException pe) { 238 | dataCallback.done(null, pe); 239 | } 240 | 241 | } 242 | 243 | public void getDataInBackground() { 244 | getDataInBackground(null); 245 | } 246 | 247 | public void getDataInBackground(GetDataCallback dataCallback) { 248 | GetDataInBackgroundThread task = new GetDataInBackgroundThread(this.data, dataCallback); 249 | ParseExecutor.runInBackground(task); 250 | } 251 | 252 | class SaveInBackgroundThread extends Thread { 253 | SaveCallback saveCallback; 254 | ProgressCallback progressCallback; 255 | 256 | public SaveInBackgroundThread(SaveCallback saveCallback, 257 | ProgressCallback progressCallback) { 258 | this.saveCallback = saveCallback; 259 | this.progressCallback = progressCallback; 260 | } 261 | 262 | public void run() { 263 | ParseException exception = null; 264 | try { 265 | save(saveCallback, progressCallback); 266 | } catch (ParseException e) { 267 | LOGGER.debug("Request failed {}", e.getMessage()); 268 | exception = e; 269 | } 270 | if (saveCallback != null) { 271 | saveCallback.done(exception); 272 | } 273 | } 274 | } 275 | 276 | class GetDataInBackgroundThread extends Thread { 277 | GetDataCallback getDataCallback; 278 | byte[] data; 279 | 280 | public GetDataInBackgroundThread(byte[] data, GetDataCallback getDataCallback) { 281 | this.getDataCallback = getDataCallback; 282 | this.data = data; 283 | } 284 | 285 | public void run() { 286 | ParseException exception = null; 287 | try { 288 | getData(getDataCallback); 289 | } catch (ParseException e) { 290 | LOGGER.debug("Request failed {}", e.getMessage()); 291 | exception = e; 292 | } 293 | if (getDataCallback != null) { 294 | getDataCallback.done(data, exception); 295 | } 296 | } 297 | } 298 | 299 | } 300 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseGeoPoint.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | public class ParseGeoPoint { 4 | static double EARTH_MEAN_RADIUS_KM = 6371.0D; 5 | static double EARTH_MEAN_RADIUS_MILE = 3958.8000000000002D; 6 | 7 | private double latitude = 0.0D; 8 | private double longitude = 0.0D; 9 | 10 | public ParseGeoPoint(double latitude, double longitude) { 11 | setLatitude(latitude); 12 | setLongitude(longitude); 13 | } 14 | 15 | public void setLatitude(double latitude) { 16 | if ((latitude > 90.0D) || (latitude < -90.0D)) { 17 | throw new IllegalArgumentException( 18 | "Latitude must be within the range (-90.0, 90.0)."); 19 | } 20 | this.latitude = latitude; 21 | } 22 | 23 | public void setLongitude(double longitude) { 24 | if ((longitude > 180.0D) || (longitude < -180.0D)) { 25 | throw new IllegalArgumentException( 26 | "Longitude must be within the range (-180.0, 180.0)."); 27 | } 28 | this.longitude = longitude; 29 | } 30 | 31 | public double getLatitude() { 32 | return this.latitude; 33 | } 34 | 35 | public double getLongitude() { 36 | return this.longitude; 37 | } 38 | 39 | public double distanceInRadiansTo(ParseGeoPoint point) { 40 | double d2r = 0.0174532925199433D; 41 | double lat1rad = this.latitude * d2r; 42 | double long1rad = this.longitude * d2r; 43 | double lat2rad = point.getLatitude() * d2r; 44 | double long2rad = point.getLongitude() * d2r; 45 | double deltaLat = lat1rad - lat2rad; 46 | double deltaLong = long1rad - long2rad; 47 | double sinDeltaLatDiv2 = Math.sin(deltaLat / 2.0D); 48 | double sinDeltaLongDiv2 = Math.sin(deltaLong / 2.0D); 49 | 50 | double a = sinDeltaLatDiv2 * sinDeltaLatDiv2 + Math.cos(lat1rad) 51 | * Math.cos(lat2rad) * sinDeltaLongDiv2 * sinDeltaLongDiv2; 52 | 53 | a = Math.min(1.0D, a); 54 | return 2.0D * Math.asin(Math.sqrt(a)); 55 | } 56 | 57 | public double distanceInKilometersTo(ParseGeoPoint point) { 58 | return distanceInRadiansTo(point) * EARTH_MEAN_RADIUS_KM; 59 | } 60 | 61 | public double distanceInMilesTo(ParseGeoPoint point) { 62 | return distanceInRadiansTo(point) * EARTH_MEAN_RADIUS_MILE; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParsePush.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.Date; 6 | import java.util.List; 7 | 8 | import org.json.JSONArray; 9 | import org.json.JSONObject; 10 | import org.parse4j.command.ParsePostCommand; 11 | import org.parse4j.command.ParseResponse; 12 | 13 | public class ParsePush { 14 | 15 | private List channelSet = null; 16 | // private ParseQuery query = null; 17 | private Date expirationTime = null; 18 | private Date pushTime = null; 19 | private Long expirationTimeInterval = null; 20 | private Boolean pushToIOS = null; 21 | private Boolean pushToAndroid = null; 22 | private JSONObject pushData = new JSONObject(); 23 | 24 | public void setChannel(String channel) { 25 | this.channelSet = new ArrayList(); 26 | this.channelSet.add(channel); 27 | } 28 | 29 | public void setChannels(Collection channels) { 30 | this.channelSet = new ArrayList(); 31 | this.channelSet.addAll(channels); 32 | } 33 | 34 | public void setPushTime(Date time) { 35 | this.pushTime = time; 36 | } 37 | 38 | public void setExpirationTime(Date time) { 39 | this.expirationTime = time; 40 | this.expirationTimeInterval = null; 41 | } 42 | 43 | public void setExpirationTimeInterval(long timeInterval) { 44 | this.expirationTime = null; 45 | this.expirationTimeInterval = Long.valueOf(timeInterval); 46 | } 47 | 48 | public void clearExpiration() { 49 | this.expirationTime = null; 50 | this.expirationTimeInterval = null; 51 | } 52 | 53 | public void setMessage(String message) { 54 | this.pushData.put("alert", message); 55 | } 56 | 57 | public void setBadge(String badge) { 58 | if(badge == null || badge.length() == 0) { 59 | badge = "Increment"; 60 | } 61 | this.pushData.put("badge", badge); 62 | } 63 | 64 | public void setSound(String sound) { 65 | this.pushData.put("sound", sound); 66 | } 67 | 68 | public void setTitle(String title) { 69 | this.pushData.put("title", title); 70 | } 71 | 72 | public void setData(String key, String value) { 73 | this.pushData.put(key, value); 74 | } 75 | 76 | public void send() throws ParseException { 77 | ParsePostCommand command = new ParsePostCommand("push"); 78 | JSONObject requestData = getJSONData(); 79 | command.setData(requestData); 80 | ParseResponse response = command.perform(); 81 | if(response.isFailed()) { 82 | throw response.getException(); 83 | } 84 | } 85 | 86 | public void sendInBackground(String message, List channels) { 87 | SendPushInBackgroundThread event = new SendPushInBackgroundThread(); 88 | ParseExecutor.runInBackground(event); 89 | } 90 | 91 | class SendPushInBackgroundThread extends Thread { 92 | 93 | public void run() { 94 | try { 95 | send(); 96 | } catch (ParseException e) { 97 | //TODO 98 | } 99 | } 100 | } 101 | 102 | private JSONObject getJSONData() { 103 | JSONObject data = new JSONObject(); 104 | data.put("data", this.pushData); 105 | 106 | if (this.channelSet == null) { 107 | data.put("channel", ""); 108 | } else { 109 | data.put("channels", new JSONArray(this.channelSet)); 110 | } 111 | 112 | if(pushTime != null) { 113 | data.put("push_time", Parse.encodeDate(pushTime)); 114 | } 115 | 116 | if(expirationTimeInterval != null) { 117 | data.put("expiration_interval", expirationTimeInterval); 118 | } 119 | 120 | if(expirationTime != null) { 121 | data.put("expiration_time", expirationTime); 122 | } 123 | 124 | return data; 125 | 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseRelation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.Collections; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.json.JSONArray; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | import org.parse4j.encode.ParseObjectEncodingStrategy; 11 | import org.parse4j.operation.RelationOperation; 12 | 13 | public class ParseRelation { 14 | 15 | private ParseObject parent; 16 | private String key; 17 | private String targetClass; 18 | private Set knownObjects = new HashSet(); 19 | 20 | @SuppressWarnings("unchecked") 21 | public ParseRelation(JSONObject jsonObject) { 22 | this.parent = null; 23 | this.key = null; 24 | this.targetClass = jsonObject.optString("className", null); 25 | JSONArray objectsArray = jsonObject.optJSONArray("objects"); 26 | if (objectsArray != null) { 27 | for (int i = 0; i < objectsArray.length(); i++) { 28 | this.knownObjects.add((T) ParseDecoder.decode(objectsArray 29 | .optJSONObject(i))); 30 | } 31 | } 32 | } 33 | 34 | public ParseRelation(String targetClass) { 35 | this.parent = null; 36 | this.key = null; 37 | this.targetClass = targetClass; 38 | } 39 | 40 | public ParseRelation(ParseObject parent, String key) { 41 | this.parent = parent; 42 | this.key = key; 43 | this.targetClass = null; 44 | } 45 | 46 | public String getTargetClass() { 47 | return this.targetClass; 48 | } 49 | 50 | public void setTargetClass(String className) { 51 | this.targetClass = className; 52 | } 53 | 54 | void ensureParentAndKey(ParseObject someParent, String someKey) { 55 | 56 | if (this.parent == null) { 57 | this.parent = someParent; 58 | } 59 | 60 | if (this.key == null) { 61 | this.key = someKey; 62 | } 63 | 64 | if (this.parent != someParent) { 65 | throw new IllegalStateException( 66 | "Internal error. One ParseRelation retrieved from two different ParseObjects."); 67 | } 68 | 69 | if (!this.key.equals(someKey)) { 70 | throw new IllegalStateException( 71 | "Internal error. One ParseRelation retrieved from two different keys."); 72 | } 73 | 74 | } 75 | 76 | public void add(T object) { 77 | 78 | this.knownObjects.add(object); 79 | 80 | /* 81 | RelationOperation operation = new RelationOperation( 82 | Collections.singleton(object), null); 83 | */ 84 | 85 | RelationOperation operation = new RelationOperation( 86 | Collections.unmodifiableSet(this.knownObjects), null); 87 | 88 | this.targetClass = operation.getTargetClass(); 89 | this.parent.performOperation(this.key, operation); 90 | 91 | } 92 | 93 | public void remove(T object) { 94 | 95 | this.knownObjects.remove(object); 96 | 97 | RelationOperation operation = new RelationOperation(null, 98 | Collections.singleton(object)); 99 | 100 | this.targetClass = operation.getTargetClass(); 101 | this.parent.performOperation(this.key, operation); 102 | } 103 | 104 | 105 | public ParseQuery getQuery() { 106 | 107 | ParseQuery query; 108 | if (this.targetClass == null) { 109 | query = ParseQuery.getQuery(this.parent.getClassName()); 110 | query.redirectClassNameForKey(this.key); 111 | } else { 112 | query = ParseQuery.getQuery(this.targetClass); 113 | } 114 | query.whereRelatedTo(this.parent, this.key); 115 | return query; 116 | 117 | } 118 | 119 | 120 | public JSONObject encodeToJSON(ParseObjectEncodingStrategy objectEncoder) throws JSONException { 121 | JSONObject relation = new JSONObject(); 122 | relation.put("__type", "Relation"); 123 | relation.put("className", this.targetClass); 124 | JSONArray knownObjectsArray = new JSONArray(); 125 | for (ParseObject knownObject : this.knownObjects) { 126 | try { 127 | knownObjectsArray.put(objectEncoder.encodeRelatedObject(knownObject)); 128 | } catch (Exception e) { } 129 | } 130 | relation.put("objects", knownObjectsArray); 131 | return relation; 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseRole.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | @ParseClassName("roles") 7 | public class ParseRole extends ParseObject { 8 | 9 | private static Logger LOGGER = LoggerFactory.getLogger(ParseRole.class); 10 | 11 | public ParseRole() { 12 | } 13 | 14 | public ParseRole(String name) { 15 | this(); 16 | setName(name); 17 | } 18 | 19 | public void setName(String name) { 20 | put("name", name); 21 | } 22 | 23 | public String getName() { 24 | return getString("name"); 25 | } 26 | 27 | @Override 28 | void validateSave() { 29 | if ((getObjectId() == null) && (getName() == null)) { 30 | LOGGER.error("New roles must specify a name."); 31 | throw new IllegalStateException("New roles must specify a name."); 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/ParseUser.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | import org.parse4j.callback.LoginCallback; 6 | import org.parse4j.callback.RequestPasswordResetCallback; 7 | import org.parse4j.callback.SignUpCallback; 8 | import org.parse4j.command.*; 9 | import org.parse4j.util.ParseRegistry; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | @ParseClassName("users") 14 | public class ParseUser extends ParseObject { 15 | 16 | public static ParseUser currentUser; 17 | 18 | private static Logger LOGGER = LoggerFactory.getLogger(ParseUser.class); 19 | 20 | private String password; 21 | private String sessionToken; 22 | 23 | public ParseUser() { 24 | super(ParseRegistry.getClassName(ParseUser.class)); 25 | setEndPoint("users"); 26 | } 27 | 28 | public void remove(String key) { 29 | if ("username".equals(key)) { 30 | LOGGER.error("Can't remove the username key."); 31 | throw new IllegalArgumentException("Can't remove the username key."); 32 | } 33 | 34 | remove(key); 35 | } 36 | 37 | public void setSessionToken(String sessionToken) { 38 | this.sessionToken = sessionToken; 39 | } 40 | 41 | public void setUsername(String username) { 42 | put("username", username); 43 | } 44 | 45 | public String getUsername() { 46 | return getString("username"); 47 | } 48 | 49 | public void setPassword(String password) { 50 | this.password = password; 51 | isDirty = true; 52 | } 53 | 54 | public void setEmail(String email) { 55 | put("email", email); 56 | } 57 | 58 | public String getEmail() { 59 | return getString("email"); 60 | } 61 | 62 | public String getSessionToken() { 63 | return sessionToken; 64 | 65 | } 66 | 67 | public static ParseUser logIn(String username, String password) throws ParseException { 68 | ParseUser pu = new ParseUser(); 69 | pu.setUsername(username); 70 | pu.setPassword(password); 71 | return pu; 72 | } 73 | 74 | public boolean isAuthenticated() { 75 | return (this.sessionToken != null && getObjectId() != null); 76 | } 77 | 78 | void validateSave() { 79 | 80 | if (getObjectId() == null) { 81 | LOGGER.error("Cannot save a ParseUser until it has been signed up. Call signUp first."); 82 | throw new IllegalArgumentException( 83 | "Cannot save a ParseUser until it has been signed up. Call signUp first."); 84 | } 85 | 86 | if ((!isAuthenticated()) && isDirty && getObjectId() != null) { 87 | LOGGER.error("Cannot save a ParseUser that is not authenticated."); 88 | throw new IllegalArgumentException( 89 | "Cannot save a ParseUser that is not authenticated."); 90 | } 91 | 92 | } 93 | 94 | 95 | 96 | public void signUp() throws ParseException { 97 | 98 | if ((getUsername() == null) || (getUsername().length() == 0)) { 99 | LOGGER.error("Username cannot be missing or blank"); 100 | throw new IllegalArgumentException( 101 | "Username cannot be missing or blank"); 102 | } 103 | 104 | if (password == null) { 105 | LOGGER.error("Password cannot be missing or blank"); 106 | throw new IllegalArgumentException( 107 | "Password cannot be missing or blank"); 108 | } 109 | 110 | if (getObjectId() != null) { 111 | LOGGER.error("Cannot sign up a user that has already signed up."); 112 | throw new IllegalArgumentException( 113 | "Cannot sign up a user that has already signed up."); 114 | } 115 | 116 | ParsePostCommand command = new ParsePostCommand(getClassName()); 117 | JSONObject parseData = getParseData(); 118 | parseData.put("password", password); 119 | command.setData(parseData); 120 | ParseResponse response = command.perform(); 121 | if(!response.isFailed()) { 122 | JSONObject jsonResponse = response.getJsonObject(); 123 | if (jsonResponse == null) { 124 | LOGGER.error("Empty response"); 125 | throw response.getException(); 126 | } 127 | try { 128 | setObjectId(jsonResponse.getString(ParseConstants.FIELD_OBJECT_ID)); 129 | sessionToken = jsonResponse.getString(ParseConstants.FIELD_SESSION_TOKEN); 130 | String createdAt = jsonResponse.getString(ParseConstants.FIELD_CREATED_AT); 131 | setCreatedAt(Parse.parseDate(createdAt)); 132 | setUpdatedAt(Parse.parseDate(createdAt)); 133 | }catch (JSONException e) { 134 | LOGGER.error("Although Parse reports object successfully saved, the response was invalid."); 135 | throw new ParseException( 136 | ParseException.INVALID_JSON, 137 | "Although Parse reports object successfully saved, the response was invalid.", 138 | e); 139 | } 140 | } 141 | else { 142 | LOGGER.error("Request failed."); 143 | throw response.getException(); 144 | } 145 | 146 | } 147 | 148 | public static ParseUser login(String username, String password) throws ParseException { 149 | 150 | currentUser = null; 151 | ParseGetCommand command = new ParseGetCommand("login"); 152 | command.addJson(false); 153 | command.put("username", username); 154 | command.put("password", password); 155 | ParseResponse response = command.perform(); 156 | if(!response.isFailed()) { 157 | JSONObject jsonResponse = response.getJsonObject(); 158 | if (jsonResponse == null) { 159 | LOGGER.error("Empty response."); 160 | throw response.getException(); 161 | } 162 | try { 163 | ParseUser parseUser = new ParseUser(); 164 | parseUser.setObjectId(jsonResponse.getString(ParseConstants.FIELD_OBJECT_ID)); 165 | parseUser.setSessionToken(jsonResponse.getString(ParseConstants.FIELD_SESSION_TOKEN)); 166 | currentUser = parseUser; 167 | String createdAt = jsonResponse.getString(ParseConstants.FIELD_CREATED_AT); 168 | String updatedAt = jsonResponse.getString(ParseConstants.FIELD_UPDATED_AT); 169 | parseUser.setCreatedAt(Parse.parseDate(createdAt)); 170 | parseUser.setUpdatedAt(Parse.parseDate(updatedAt)); 171 | jsonResponse.remove(ParseConstants.FIELD_OBJECT_ID); 172 | jsonResponse.remove(ParseConstants.FIELD_CREATED_AT); 173 | jsonResponse.remove(ParseConstants.FIELD_UPDATED_AT); 174 | jsonResponse.remove(ParseConstants.FIELD_SESSION_TOKEN); 175 | parseUser.setData(jsonResponse, false); 176 | return parseUser; 177 | 178 | }catch (JSONException e) { 179 | LOGGER.error("Although Parse reports object successfully saved, the response was invalid."); 180 | throw new ParseException( 181 | ParseException.INVALID_JSON, 182 | "Although Parse reports object successfully saved, the response was invalid.", 183 | e); 184 | } 185 | } 186 | else { 187 | LOGGER.error("Request failed."); 188 | throw response.getException(); 189 | } 190 | 191 | } 192 | 193 | public static void requestPasswordReset(String email) throws ParseException { 194 | 195 | ParsePostCommand command = new ParsePostCommand("requestPasswordReset"); 196 | JSONObject data = new JSONObject(); 197 | data.put("email", email); 198 | command.setData(data); 199 | ParseResponse response = command.perform(); 200 | if (!response.isFailed()) { 201 | JSONObject jsonResponse = response.getJsonObject(); 202 | if (jsonResponse == null) { 203 | LOGGER.error("Empty response."); 204 | throw response.getException(); 205 | } 206 | } else { 207 | LOGGER.error("Request failed."); 208 | throw response.getException(); 209 | } 210 | 211 | } 212 | 213 | @Override 214 | public void delete() throws ParseException { 215 | if(getObjectId() == null) return; 216 | 217 | ParseCommand command = new ParseDeleteCommand(getEndPoint(), getObjectId()); 218 | command.put(ParseConstants.FIELD_SESSION_TOKEN, getSessionToken()); 219 | 220 | ParseResponse response = command.perform(); 221 | if(response.isFailed()) { 222 | throw response.getException(); 223 | } 224 | 225 | setUpdatedAt(null); 226 | setCreatedAt(null); 227 | setObjectId(null); 228 | this.isDirty = false; 229 | } 230 | 231 | public void logout() throws ParseException { 232 | 233 | if(!isAuthenticated()) { 234 | return; 235 | } 236 | 237 | } 238 | 239 | public static void requestPasswordResetInBackground(String email, 240 | RequestPasswordResetCallback callback) { 241 | 242 | } 243 | 244 | public void signUpInBackground(SignUpCallback callback) { 245 | 246 | } 247 | 248 | public static void loginInBackground(String username, String password, 249 | LoginCallback callback) { 250 | 251 | } 252 | 253 | } 254 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/bolts/AggregateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | package org.parse4j.bolts; 12 | 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Aggregates Exceptions that may be thrown in the process of a task's 18 | * execution. 19 | */ 20 | public class AggregateException extends Exception { 21 | private static final long serialVersionUID = 1L; 22 | 23 | private List errors; 24 | 25 | public AggregateException(List errors) { 26 | super("There were multiple errors."); 27 | 28 | this.errors = errors; 29 | } 30 | 31 | /** 32 | * Returns the list of errors that this exception encapsulates. 33 | */ 34 | public List getErrors() { 35 | return errors; 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/org/parse4j/bolts/Capture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | package org.parse4j.bolts; 12 | 13 | /** 14 | * Provides a class that can be used for capturing variables in an anonymous class implementation. 15 | * 16 | * @param 17 | */ 18 | public class Capture { 19 | private T value; 20 | 21 | public Capture() { 22 | } 23 | 24 | public Capture(T value) { 25 | this.value = value; 26 | } 27 | 28 | public T get() { 29 | return value; 30 | } 31 | 32 | public void set(T value) { 33 | this.value = value; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/org/parse4j/bolts/Continuation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | */ 10 | 11 | package org.parse4j.bolts; 12 | 13 | /** 14 | * A function to be called after a task completes. 15 | * @see Task 16 | */ 17 | public interface Continuation { 18 | 19 | TContinuationResult then(Task task) throws Exception; 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/CountCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class CountCallback extends ParseCallback { 6 | 7 | public abstract void done(Integer count, ParseException parseException); 8 | 9 | @Override 10 | void internalDone(Integer count, ParseException parseException) { 11 | if (parseException == null) 12 | done(count, null); 13 | else 14 | done(-1, parseException); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/DeleteCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class DeleteCallback extends ParseCallback { 6 | 7 | public abstract void done(ParseException parseException); 8 | 9 | @Override 10 | void internalDone(Void paramT, ParseException parseException) { 11 | done(parseException); 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/FindCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import java.util.List; 4 | 5 | import org.parse4j.ParseException; 6 | import org.parse4j.ParseObject; 7 | 8 | public abstract class FindCallback extends ParseCallback> { 9 | 10 | public abstract void done(List list, ParseException parseException); 11 | 12 | @Override 13 | void internalDone(List list, ParseException parseException) { 14 | done(list, parseException); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/FunctionCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class FunctionCallback extends ParseCallback { 6 | 7 | public abstract void done(T result, ParseException parseException); 8 | 9 | @Override 10 | void internalDone(T result, ParseException parseException) { 11 | done(result, parseException); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/GetCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | import org.parse4j.ParseObject; 5 | 6 | public abstract class GetCallback extends ParseCallback { 7 | 8 | public abstract void done(T t, ParseException parseException); 9 | 10 | @Override 11 | void internalDone(T t, ParseException parseException) { 12 | done(t, parseException); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/GetDataCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class GetDataCallback extends ParseCallback { 6 | 7 | public abstract void done(byte[] data, ParseException e); 8 | 9 | final void internalDone(byte[] returnValue, ParseException e) { 10 | done(returnValue, e); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/LocationCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | import org.parse4j.ParseGeoPoint; 5 | 6 | public abstract class LocationCallback extends ParseCallback { 7 | 8 | abstract void done(ParseGeoPoint parseGeoPoint, ParseException parseException); 9 | 10 | @Override 11 | void internalDone(ParseGeoPoint parseGeoPoint, ParseException parseException) { 12 | done(parseGeoPoint, parseException); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/LoginCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | import org.parse4j.ParseUser; 5 | 6 | public abstract class LoginCallback extends ParseCallback { 7 | 8 | abstract void done(ParseUser parseUser, ParseException parseException); 9 | 10 | @Override 11 | void internalDone(ParseUser parseUser, ParseException parseException) { 12 | done(parseUser, parseException); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/ParseCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class ParseCallback { 6 | 7 | abstract void internalDone(T paramT, ParseException parseException); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/ProgressCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class ProgressCallback extends ParseCallback { 6 | 7 | public abstract void done(Integer percentDone); 8 | 9 | @Override 10 | void internalDone(Integer paramT, ParseException parseException) { 11 | done(paramT); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/RequestPasswordResetCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class RequestPasswordResetCallback extends ParseCallback { 6 | 7 | public abstract void done(ParseException parseException); 8 | 9 | final void internalDone(Void paramVoid, ParseException parseException) { 10 | done(parseException); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/SaveCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class SaveCallback extends ParseCallback { 6 | 7 | public abstract void done(ParseException parseException); 8 | 9 | @Override 10 | void internalDone(Void paramT, ParseException parseException) { 11 | done(parseException); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/SendCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class SendCallback extends ParseCallback { 6 | 7 | abstract void done(ParseException parseException); 8 | 9 | @Override 10 | void internalDone(Void paramT, ParseException parseException) { 11 | done(parseException); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/callback/SignUpCallback.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.callback; 2 | 3 | import org.parse4j.ParseException; 4 | 5 | public abstract class SignUpCallback extends ParseCallback { 6 | 7 | public abstract void done(ParseException parseException); 8 | 9 | @Override 10 | void internalDone(Void paramVoid, ParseException parseException) { 11 | done(parseException); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParseBatchCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.http.client.methods.HttpPost; 6 | import org.apache.http.client.methods.HttpRequestBase; 7 | import org.apache.http.entity.StringEntity; 8 | import org.parse4j.ParseConstants; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | /** 12 | * Generate parse batch requesy body and construct the url 13 | * @author Nikolay Rusev 14 | * 15 | */ 16 | public class ParseBatchCommand extends ParseCommand{ 17 | 18 | private static Logger LOGGER = LoggerFactory.getLogger(ParseBatchCommand.class); 19 | 20 | public String getUrl(){ 21 | String base = ParseConstants.API_ENDPOINT; 22 | String version = ParseConstants.API_VERSION; 23 | return base + "/" +version + "/" + "batch"; 24 | } 25 | @Override 26 | public HttpRequestBase getRequest() throws IOException { 27 | 28 | HttpPost httppost = new HttpPost(getUrl()); 29 | setupHeaders(httppost, addJson); 30 | 31 | if (data.has("requests")) { 32 | if(LOGGER.isDebugEnabled()) { 33 | LOGGER.debug("Sending data: {}", data.getJSONArray("requests")); 34 | } 35 | httppost.setEntity(new StringEntity(data.toString(), "UTF8")); 36 | } 37 | return httppost; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParseCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import org.apache.http.HttpResponse; 4 | import org.apache.http.client.ClientProtocolException; 5 | import org.apache.http.client.HttpClient; 6 | import org.apache.http.client.config.RequestConfig; 7 | import org.apache.http.client.methods.HttpRequestBase; 8 | import org.apache.http.impl.client.HttpClientBuilder; 9 | import org.apache.http.impl.client.HttpClients; 10 | import org.json.JSONArray; 11 | import org.json.JSONObject; 12 | import org.parse4j.Parse; 13 | import org.parse4j.ParseException; 14 | import org.parse4j.ParseUser; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.io.IOException; 19 | 20 | import static org.parse4j.ParseConstants.*; 21 | 22 | public abstract class ParseCommand { 23 | 24 | private static Logger LOGGER = LoggerFactory.getLogger(ParseCommand.class); 25 | 26 | private static RequestConfig config; 27 | protected JSONObject data = new JSONObject(); 28 | protected boolean addJson = true; 29 | 30 | static { 31 | config = RequestConfig.custom().build(); 32 | } 33 | 34 | abstract HttpRequestBase getRequest() throws IOException; 35 | 36 | public ParseResponse perform() throws ParseException { 37 | 38 | if (LOGGER.isDebugEnabled()) { 39 | LOGGER.debug("Data to be sent: {}", data); 40 | } 41 | 42 | try { 43 | long commandStart = System.currentTimeMillis(); 44 | HttpClient httpclient = createSingleClient(); 45 | // ResponseHandler responseHandler=new 46 | // BasicResponseHandler(); 47 | HttpResponse httpResponse = httpclient.execute(getRequest()); 48 | // String resp = httpclient.execute(getRequest(), responseHandler); 49 | ParseResponse response = new ParseResponse(httpResponse); 50 | 51 | long commandReceived = System.currentTimeMillis(); 52 | if (LOGGER.isDebugEnabled()) { 53 | LOGGER.debug("ParseCommand took " 54 | + (commandReceived - commandStart) + " milliseconds\n"); 55 | } 56 | return response; 57 | } catch (ClientProtocolException e) { 58 | throw ParseResponse.getConnectionFailedException(e.getMessage()); 59 | } catch (IOException e) { 60 | throw ParseResponse.getConnectionFailedException(e.getMessage()); 61 | } 62 | } 63 | 64 | protected HttpClient createSingleClient() { 65 | HttpClientBuilder client = HttpClients.custom() 66 | .setDefaultRequestConfig(config); 67 | 68 | return client.build(); 69 | } 70 | 71 | protected void setupHeaders(HttpRequestBase requestBase, boolean addJson) { 72 | requestBase.addHeader(HEADER_APPLICATION_ID, Parse.getApplicationId()); 73 | 74 | if (Parse.isIsRootMode()) { 75 | requestBase.addHeader(HEADER_MASTER_KEY, Parse.getMasterKey()); 76 | } else { 77 | requestBase.addHeader(HEADER_REST_API_KEY, Parse.getRestAPIKey()); 78 | } 79 | 80 | if (addJson) { 81 | requestBase.addHeader(HEADER_CONTENT_TYPE, CONTENT_TYPE_JSON); 82 | } 83 | 84 | if (data.has(FIELD_SESSION_TOKEN)) { 85 | requestBase.addHeader(HEADER_SESSION_TOKEN, 86 | data.getString(FIELD_SESSION_TOKEN)); 87 | } else if (ParseUser.currentUser != null) { 88 | // if we are logged in, pass the session token 89 | requestBase.addHeader(HEADER_SESSION_TOKEN, 90 | ParseUser.currentUser.getSessionToken()); 91 | } 92 | } 93 | 94 | public void setData(JSONObject data) { 95 | this.data.put("data", data); 96 | } 97 | 98 | public void put(String key, String value) { 99 | this.data.put(key, value); 100 | } 101 | 102 | public void put(String key, int value) { 103 | this.data.put(key, value); 104 | } 105 | 106 | public void put(String key, long value) { 107 | this.data.put(key, value); 108 | } 109 | 110 | public void put(String key, JSONObject value) { 111 | this.data.put(key, value); 112 | } 113 | 114 | public void put(String key, JSONArray value) { 115 | this.data.put(key, value); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParseDeleteCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import org.apache.http.client.methods.HttpDelete; 4 | import org.apache.http.client.methods.HttpRequestBase; 5 | import org.parse4j.Parse; 6 | 7 | public class ParseDeleteCommand extends ParseCommand { 8 | 9 | private String endPoint; 10 | private String objectId; 11 | 12 | public ParseDeleteCommand(String endPoint, String objectId) { 13 | this.endPoint = endPoint; 14 | this.objectId = objectId; 15 | } 16 | 17 | public ParseDeleteCommand(String endPoint) { 18 | this.endPoint = endPoint; 19 | } 20 | 21 | @Override 22 | public HttpRequestBase getRequest() { 23 | String url = Parse.getParseAPIUrl(endPoint) 24 | + (objectId != null ? "/" + objectId : ""); 25 | HttpDelete httpdelete = new HttpDelete(url); 26 | setupHeaders(httpdelete, false); 27 | return httpdelete; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParseGetCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | import java.util.Iterator; 6 | 7 | import org.apache.http.client.methods.HttpGet; 8 | import org.apache.http.client.methods.HttpRequestBase; 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | import org.parse4j.Parse; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | public class ParseGetCommand extends ParseCommand { 16 | 17 | private static Logger LOGGER = LoggerFactory.getLogger(ParseGetCommand.class); 18 | 19 | private String endPoint; 20 | private String objectId; 21 | 22 | public ParseGetCommand(String className, String objectId) { 23 | this.endPoint = className; 24 | this.objectId = objectId; 25 | } 26 | 27 | public ParseGetCommand(String endPoint) { 28 | this.endPoint = endPoint; 29 | } 30 | 31 | @SuppressWarnings("rawtypes") 32 | @Override 33 | public HttpRequestBase getRequest() { 34 | 35 | String url = getUrl(); 36 | 37 | if("login".endsWith(endPoint)) { 38 | try { 39 | String userPart = "username=" + URLEncoder.encode(data.getString("username"), "UTF-8"); 40 | String passPart = "password=" + URLEncoder.encode(data.getString("password"), "UTF-8"); 41 | url += "?" + userPart + "&" + passPart; 42 | LOGGER.info(url); 43 | } 44 | catch(UnsupportedEncodingException e) { 45 | LOGGER.error("Error while building request url", e); 46 | } 47 | } 48 | 49 | try { 50 | if(data.opt("data") != null) { 51 | JSONObject query = (JSONObject) data.get("data"); 52 | try { 53 | 54 | Iterator it = query.keySet().iterator(); 55 | if(it.hasNext()) { 56 | url += "?"; 57 | } 58 | while(it.hasNext()) { 59 | String key = (String) it.next(); 60 | Object obj = query.get(key); 61 | url += key + "=" + URLEncoder.encode(obj.toString(), "UTF-8") + "&"; 62 | } 63 | 64 | if(LOGGER.isDebugEnabled()) { 65 | LOGGER.debug("Final Request URL: {}", url); 66 | } 67 | } 68 | catch(UnsupportedEncodingException e) { 69 | LOGGER.error("Encoding error while building request url", e); 70 | } 71 | } 72 | 73 | 74 | } 75 | catch(JSONException e) { 76 | LOGGER.error("Data not found, empty request?", e); 77 | } 78 | 79 | HttpGet httpget = new HttpGet(url); 80 | setupHeaders(httpget, addJson); 81 | return httpget; 82 | } 83 | 84 | public void addJson(boolean addJson) { 85 | this.addJson = false; 86 | } 87 | 88 | protected String getUrl() { 89 | String url = Parse.getParseAPIUrl(endPoint) + (objectId != null ? "/" + objectId : ""); 90 | 91 | if(LOGGER.isDebugEnabled()) { 92 | LOGGER.debug("Request URL: {}", url); 93 | } 94 | 95 | return url; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParsePostCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.http.client.methods.HttpPost; 6 | import org.apache.http.client.methods.HttpRequestBase; 7 | import org.apache.http.entity.StringEntity; 8 | import org.parse4j.Parse; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class ParsePostCommand extends ParseCommand { 13 | 14 | private static Logger LOGGER = LoggerFactory.getLogger(ParsePostCommand.class); 15 | 16 | private String endPoint; 17 | private String objectId; 18 | 19 | public ParsePostCommand(String endPoint, String objectId) { 20 | this.endPoint = endPoint; 21 | this.objectId = objectId; 22 | } 23 | 24 | public ParsePostCommand(String endPoint) { 25 | this.endPoint = endPoint; 26 | } 27 | 28 | @Override 29 | public HttpRequestBase getRequest() throws IOException { 30 | 31 | HttpPost httppost = new HttpPost(getUrl()); 32 | setupHeaders(httppost, addJson); 33 | 34 | if (data.has("data")) { 35 | if(LOGGER.isDebugEnabled()) { 36 | LOGGER.debug("Sending data: {}", data.getJSONObject("data")); 37 | } 38 | httppost.setEntity(new StringEntity(data.getJSONObject("data").toString(), "UTF8")); 39 | } 40 | return httppost; 41 | } 42 | 43 | protected String getUrl() { 44 | String url = Parse.getParseAPIUrl(endPoint) + (objectId != null ? "/" + objectId : ""); 45 | 46 | if(LOGGER.isDebugEnabled()) { 47 | LOGGER.debug("Request URL: {}", url); 48 | } 49 | 50 | return url; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParsePutCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.http.client.methods.HttpPut; 6 | import org.apache.http.client.methods.HttpRequestBase; 7 | import org.apache.http.entity.StringEntity; 8 | import org.parse4j.Parse; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | public class ParsePutCommand extends ParseCommand { 13 | 14 | private static Logger LOGGER = LoggerFactory.getLogger(ParsePutCommand.class); 15 | 16 | private String endPoint; 17 | private String objectId; 18 | 19 | public ParsePutCommand(String endPoint, String objectId) { 20 | this.endPoint = endPoint; 21 | this.objectId = objectId; 22 | } 23 | 24 | public ParsePutCommand(String endPoint) { 25 | this.endPoint = endPoint; 26 | } 27 | 28 | @Override 29 | public HttpRequestBase getRequest() throws IOException { 30 | 31 | HttpPut httpput = new HttpPut(getUrl()); 32 | setupHeaders(httpput, true); 33 | 34 | if (data != null) { 35 | if(LOGGER.isDebugEnabled()) { 36 | LOGGER.debug("Sending data: {}", data.getJSONObject("data")); 37 | } 38 | httpput.setEntity(new StringEntity(data.getJSONObject("data").toString(), "UTF8")); 39 | } 40 | return httpput; 41 | } 42 | 43 | protected String getUrl() { 44 | String url = Parse.getParseAPIUrl(endPoint) + (objectId != null ? "/" + objectId : ""); 45 | 46 | if(LOGGER.isDebugEnabled()) { 47 | LOGGER.debug("Request URL: {}", url); 48 | } 49 | 50 | return url; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParseResponse.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | import org.apache.http.HttpResponse; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | import org.parse4j.ParseException; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | public class ParseResponse { 15 | 16 | private static Logger LOGGER = LoggerFactory.getLogger(ParseResponse.class); 17 | 18 | private HttpResponse httpResponse; 19 | static final String RESPONSE_CODE_JSON_KEY = "code"; 20 | static final String RESPONSE_ERROR_JSON_KEY = "error"; 21 | private String responseBody; 22 | private String headers; 23 | private int contentLength; 24 | 25 | public ParseResponse(HttpResponse httpResponse) { 26 | this.httpResponse = httpResponse; 27 | this.responseBody = getResponseAsString(httpResponse); 28 | this.contentLength = responseBody.length(); 29 | this.headers = httpResponse.toString(); 30 | if(LOGGER.isDebugEnabled()) { 31 | LOGGER.debug("Response Headers: " + headers); 32 | LOGGER.debug("Response Content Length: " + contentLength); 33 | LOGGER.debug("Response Content: " + responseBody); 34 | } 35 | } 36 | 37 | public boolean isFailed() { 38 | return hasConnectionFailed() || hasErrorCode(); 39 | } 40 | 41 | public boolean hasConnectionFailed() { 42 | return responseBody == null; 43 | } 44 | 45 | public boolean hasErrorCode() { 46 | int statusCode = httpResponse.getStatusLine().getStatusCode(); 47 | return (statusCode < 200 || statusCode >= 300); 48 | } 49 | 50 | static ParseException getConnectionFailedException(String message) { 51 | return new ParseException(ParseException.CONNECTION_FAILED, 52 | "Connection failed with Parse servers. Log: " + message); 53 | } 54 | 55 | static ParseException getConnectionFailedException(Throwable e) { 56 | return getConnectionFailedException(e.getMessage()); 57 | } 58 | 59 | public ParseException getException() { 60 | 61 | if (hasConnectionFailed()) { 62 | return new ParseException(ParseException.CONNECTION_FAILED, 63 | "Connection to Parse servers failed."); 64 | } 65 | 66 | if (!hasErrorCode()) { 67 | return new ParseException(ParseException.OPERATION_FORBIDDEN, 68 | "getException called with successful response"); 69 | } 70 | 71 | JSONObject response = getJsonObject(); 72 | 73 | if (response == null) { 74 | return new ParseException(ParseException.INVALID_JSON, 75 | "Invalid response from Parse servers."); 76 | } 77 | 78 | return getParseError(response); 79 | } 80 | 81 | public JSONObject getJsonObject() { 82 | 83 | return new JSONObject(responseBody); 84 | /* 85 | try { 86 | 87 | JSONObject json = new JSONObject(EntityUtils.toString(httpResponse.getEntity())); 88 | 89 | 90 | return json; 91 | } catch (org.apache.http.ParseException e) { 92 | return null; 93 | } catch (JSONException e) { 94 | return null; 95 | } catch (IOException e) { 96 | return null; 97 | } 98 | */ 99 | } 100 | public String getRawResponseBody(){ 101 | return responseBody; 102 | } 103 | private ParseException getParseError(JSONObject response) { 104 | 105 | int code; 106 | String error; 107 | 108 | try { 109 | code = response.getInt(RESPONSE_CODE_JSON_KEY); 110 | } 111 | catch(JSONException e) { 112 | code = ParseException.NOT_INITIALIZED; 113 | } 114 | 115 | try { 116 | error = response.getString(RESPONSE_ERROR_JSON_KEY); 117 | } 118 | catch(JSONException e) { 119 | error = "Error undefinted by Parse server."; 120 | } 121 | 122 | return new ParseException(code, error); 123 | } 124 | 125 | private String getResponseAsString(HttpResponse httpResponse) { 126 | try { 127 | BufferedReader r = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); 128 | StringBuilder total = new StringBuilder(); 129 | String line = null; 130 | while ((line = r.readLine()) != null) { 131 | total.append(line); 132 | } 133 | //r.close(); 134 | return total.toString(); 135 | } 136 | catch(IOException e) { 137 | LOGGER.error("Error while reading response entity", e); 138 | throw new IllegalArgumentException("Failed getting Parse Response", e); 139 | } 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/command/ParseUploadCommand.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.command; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.http.client.methods.HttpPost; 6 | import org.apache.http.client.methods.HttpRequestBase; 7 | import org.apache.http.entity.ByteArrayEntity; 8 | import org.parse4j.Parse; 9 | import org.parse4j.ParseConstants; 10 | import org.parse4j.ParseUser; 11 | import org.parse4j.callback.ProgressCallback; 12 | import org.parse4j.http.CountingHttpEntity; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | public class ParseUploadCommand extends ParseCommand { 17 | 18 | private String endPoint; 19 | private String contentType; 20 | private byte[] data; 21 | private ProgressCallback progressCallback; 22 | 23 | private static Logger LOGGER = LoggerFactory.getLogger(ParseUser.class); 24 | 25 | public ParseUploadCommand(String endPoint) { 26 | this.endPoint = endPoint; 27 | } 28 | 29 | @Override 30 | public HttpRequestBase getRequest() throws IOException { 31 | String url = Parse.getParseAPIUrl(endPoint); 32 | LOGGER.info(url); 33 | HttpPost httppost = new HttpPost(url); 34 | setupHeaders(httppost, false); 35 | 36 | if(contentType != null) { 37 | httppost.addHeader(ParseConstants.HEADER_CONTENT_TYPE, contentType); 38 | } 39 | 40 | LOGGER.info("data size: " + data.length); 41 | if (data != null) { 42 | if(progressCallback != null) { 43 | httppost.setEntity(new CountingHttpEntity(new ByteArrayEntity(data), progressCallback)); 44 | } 45 | else { 46 | httppost.setEntity(new ByteArrayEntity(data)); 47 | } 48 | } 49 | return httppost; 50 | } 51 | 52 | public void setContentType(String contentType) { 53 | this.contentType = contentType; 54 | } 55 | 56 | public void setData(byte[] data) { 57 | this.data = data; 58 | } 59 | 60 | public void setProgressCallback(ProgressCallback progressCallback) { 61 | this.progressCallback = progressCallback; 62 | } 63 | 64 | /* 65 | @Override 66 | public ParseResponse perform() throws ParseException { 67 | 68 | try { 69 | HttpClient httpclient = createSingleClient(); 70 | HttpResponse httpResponse = httpclient.execute(getRequest()); 71 | ParseResponse response = new ParseResponse(httpResponse); 72 | 73 | return response; 74 | } 75 | catch (ClientProtocolException e) { 76 | throw ParseResponse.getConnectionFailedException(e.getMessage()); 77 | } 78 | catch (IOException e) { 79 | throw ParseResponse.getConnectionFailedException(e.getMessage()); 80 | } 81 | } 82 | */ 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/encode/ParseObjectEncodingStrategy.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.encode; 2 | 3 | import org.json.JSONObject; 4 | import org.parse4j.ParseObject; 5 | 6 | public interface ParseObjectEncodingStrategy { 7 | 8 | public abstract JSONObject encodeRelatedObject(ParseObject parseObject); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/encode/PointerEncodingStrategy.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.encode; 2 | 3 | import org.json.JSONObject; 4 | import org.parse4j.ParseObject; 5 | 6 | public class PointerEncodingStrategy extends PointerOrLocalIdEncodingStrategy { 7 | 8 | private static final PointerEncodingStrategy instance = new PointerEncodingStrategy(); 9 | 10 | public static PointerEncodingStrategy get() { 11 | return instance; 12 | } 13 | 14 | public JSONObject encodeRelatedObject(ParseObject object) { 15 | if (object.getObjectId() == null) { 16 | throw new IllegalStateException( 17 | "unable to encode an association with an unsaved ParseObject"); 18 | } 19 | return super.encodeRelatedObject(object); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/encode/PointerOrLocalIdEncodingStrategy.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.encode; 2 | 3 | import java.util.Random; 4 | 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | import org.parse4j.ParseObject; 8 | 9 | public class PointerOrLocalIdEncodingStrategy implements 10 | ParseObjectEncodingStrategy { 11 | 12 | @Override 13 | public JSONObject encodeRelatedObject(ParseObject parseObject) { 14 | JSONObject json = new JSONObject(); 15 | try { 16 | if (parseObject.getObjectId() != null) { 17 | json.put("__type", "Pointer"); 18 | json.put("className", parseObject.getClassName()); 19 | json.put("objectId", parseObject.getObjectId()); 20 | } else { 21 | json.put("__type", "Pointer"); 22 | json.put("className", parseObject.getClassName()); 23 | json.put("localId", createTempId()); 24 | } 25 | } 26 | catch (JSONException e) { 27 | throw new RuntimeException(e); 28 | } 29 | return json; 30 | } 31 | 32 | private String createTempId() { 33 | Random random = new Random(); 34 | long localIdNumber = random.nextLong(); 35 | String localId = "local_" + Long.toHexString(localIdNumber); 36 | 37 | if (!isLocalId(localId)) { 38 | throw new IllegalStateException( 39 | "Generated an invalid local id: \"" 40 | + localId 41 | + "\". " 42 | + "This should never happen. Contact us at https://parse.com/help"); 43 | } 44 | 45 | return localId; 46 | } 47 | 48 | private boolean isLocalId(String localId) { 49 | if (!localId.startsWith("local_")) { 50 | return false; 51 | } 52 | for (int i = 6; i < localId.length(); i++) { 53 | char c = localId.charAt(i); 54 | if (((c < '0') || (c > '9')) && ((c < 'a') || (c > 'f'))) { 55 | return false; 56 | } 57 | } 58 | return true; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/http/CountingHttpEntity.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.http; 2 | 3 | import java.io.FilterOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | import org.apache.http.HttpEntity; 8 | import org.apache.http.entity.HttpEntityWrapper; 9 | import org.parse4j.callback.ProgressCallback; 10 | 11 | public class CountingHttpEntity extends HttpEntityWrapper { 12 | 13 | private final ProgressCallback progressCallback; 14 | 15 | public CountingHttpEntity(final HttpEntity entity, ProgressCallback progressCallback) { 16 | super(entity); 17 | this.progressCallback = progressCallback; 18 | } 19 | 20 | @Override 21 | public void writeTo(final OutputStream out) throws IOException { 22 | this.wrappedEntity.writeTo(new CountingOutputStream(out, this.progressCallback, getContentLength())); 23 | } 24 | 25 | static class CountingOutputStream extends FilterOutputStream { 26 | 27 | private final ProgressCallback progressCallback; 28 | private long transferred; 29 | private long totalSize; 30 | 31 | CountingOutputStream(final OutputStream out, final ProgressCallback progressCallback, long totalSize) { 32 | super(out); 33 | this.progressCallback = progressCallback; 34 | this.transferred = 0; 35 | this.totalSize = totalSize; 36 | } 37 | 38 | @Override 39 | public void write(final byte[] b, final int off, final int len) throws IOException { 40 | //// NO, double-counting, as super.write(byte[], int, int) delegates to write(int). 41 | //super.write(b, off, len); 42 | out.write(b, off, len); 43 | this.transferred += len; 44 | notifyCallback(); 45 | } 46 | 47 | @Override 48 | public void write(final int b) throws IOException { 49 | out.write(b); 50 | this.transferred++; 51 | notifyCallback(); 52 | } 53 | 54 | private void notifyCallback() { 55 | int progressToReport = Math.round((float)this.transferred / (float)this.totalSize * 100.0F); 56 | this.progressCallback.done(progressToReport); 57 | } 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/AddOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | import org.parse4j.ParseObject; 9 | import org.parse4j.encode.ParseObjectEncodingStrategy; 10 | import org.parse4j.util.ParseEncoder; 11 | 12 | public class AddOperation implements ParseFieldOperation { 13 | 14 | protected final ArrayList objects = new ArrayList(); 15 | 16 | public AddOperation(Collection coll) { 17 | this.objects.addAll(coll); 18 | } 19 | 20 | public AddOperation(Object o) { 21 | this.objects.add(o); 22 | } 23 | 24 | @Override 25 | public Object apply(Object oldValue, ParseObject parseObject, String key) { 26 | throw new IllegalArgumentException("not implemented!"); 27 | } 28 | 29 | @Override 30 | public Object encode(ParseObjectEncodingStrategy objectEncoder) 31 | throws JSONException { 32 | JSONObject output = new JSONObject(); 33 | output.put("__op", "Add"); 34 | output.put("objects", ParseEncoder.encode(this.objects, objectEncoder)); 35 | return output; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/AddUniqueOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.LinkedHashSet; 6 | 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | import org.parse4j.ParseObject; 10 | import org.parse4j.encode.ParseObjectEncodingStrategy; 11 | import org.parse4j.util.ParseEncoder; 12 | 13 | public class AddUniqueOperation implements ParseFieldOperation { 14 | 15 | protected LinkedHashSet objects = new LinkedHashSet(); 16 | 17 | public AddUniqueOperation(Collection coll) { 18 | this.objects.addAll(coll); 19 | } 20 | 21 | public AddUniqueOperation(Object o) { 22 | this.objects.add(o); 23 | } 24 | 25 | @Override 26 | public Object apply(Object oldValue, ParseObject parseObject, String key) { 27 | throw new IllegalArgumentException("not implemented!"); 28 | } 29 | 30 | @Override 31 | public Object encode(ParseObjectEncodingStrategy objectEncoder) 32 | throws JSONException { 33 | JSONObject output = new JSONObject(); 34 | output.put("__op", "AddUnique"); 35 | output.put("objects", ParseEncoder.encode(new ArrayList(this.objects), objectEncoder)); 36 | return output; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/DeleteFieldOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | import org.parse4j.ParseObject; 6 | import org.parse4j.encode.ParseObjectEncodingStrategy; 7 | 8 | public class DeleteFieldOperation implements ParseFieldOperation { 9 | 10 | @Override 11 | public Object apply(Object oldValue, ParseObject paramParseObject, String key) { 12 | return null; 13 | } 14 | 15 | @Override 16 | public Object encode(ParseObjectEncodingStrategy objectEncoder) 17 | throws JSONException { 18 | JSONObject output = new JSONObject(); 19 | output.put("__op", "Delete"); 20 | return output; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/IncrementFieldOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import org.json.JSONException; 4 | import org.json.JSONObject; 5 | import org.parse4j.ParseObject; 6 | import org.parse4j.encode.ParseObjectEncodingStrategy; 7 | 8 | public class IncrementFieldOperation implements ParseFieldOperation { 9 | 10 | private Number amount; 11 | private boolean needIncrement = true; 12 | 13 | public IncrementFieldOperation(Number amount) { 14 | this.amount = amount; 15 | } 16 | 17 | @Override 18 | public Object apply(Object oldValue, ParseObject parseObject, String key) { 19 | 20 | if (oldValue == null) { 21 | needIncrement = false; 22 | return amount; 23 | } 24 | 25 | if ((oldValue instanceof Number)) { 26 | return OperationUtil.addNumbers((Number) oldValue, this.amount); 27 | } 28 | 29 | throw new IllegalArgumentException("You cannot increment a non-number. Key type ["+oldValue.getClass().getCanonicalName()+"]"); 30 | } 31 | 32 | @Override 33 | public Object encode(ParseObjectEncodingStrategy objectEncoder) 34 | throws JSONException { 35 | if(needIncrement) { 36 | JSONObject output = new JSONObject(); 37 | output.put("__op", "Increment"); 38 | output.put("amount", this.amount); 39 | return output; 40 | } 41 | else { 42 | return amount; 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/OperationUtil.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | public class OperationUtil { 4 | 5 | static Number addNumbers(Number first, Number second) { 6 | if (((first instanceof Double)) || ((second instanceof Double))) 7 | return Double.valueOf(first.doubleValue() + second.doubleValue()); 8 | if (((first instanceof Float)) || ((second instanceof Float))) 9 | return Float.valueOf(first.floatValue() + second.floatValue()); 10 | if (((first instanceof Long)) || ((second instanceof Long))) 11 | return Long.valueOf(first.longValue() + second.longValue()); 12 | if (((first instanceof Integer)) || ((second instanceof Integer))) 13 | return Integer.valueOf(first.intValue() + second.intValue()); 14 | if (((first instanceof Short)) || ((second instanceof Short))) 15 | return Integer.valueOf(first.shortValue() + second.shortValue()); 16 | if (((first instanceof Byte)) || ((second instanceof Byte))) { 17 | return Integer.valueOf(first.byteValue() + second.byteValue()); 18 | } 19 | throw new RuntimeException("Unknown number type."); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/ParseFieldOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import org.json.JSONException; 4 | import org.parse4j.ParseObject; 5 | import org.parse4j.encode.ParseObjectEncodingStrategy; 6 | 7 | public interface ParseFieldOperation { 8 | 9 | abstract Object apply(Object oldValue, ParseObject parseObject, String key); 10 | 11 | abstract Object encode(ParseObjectEncodingStrategy objectEncoder) throws JSONException; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/ParseFieldOperations.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.json.JSONArray; 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | import org.parse4j.ParseDecoder; 12 | import org.parse4j.ParseObject; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | 17 | public class ParseFieldOperations { 18 | 19 | private static Logger LOGGER = LoggerFactory.getLogger(ParseFieldOperations.class); 20 | 21 | 22 | static Map opDecoderMap = 23 | new HashMap(); 24 | 25 | private static void registerDecoder(String opName, ParseFieldOperationFactory factory) { 26 | if(LOGGER.isDebugEnabled()) { 27 | LOGGER.debug("Registering {} decoder", opName); 28 | } 29 | opDecoderMap.put(opName, factory); 30 | } 31 | 32 | private static abstract interface ParseFieldOperationFactory { 33 | public abstract ParseFieldOperation decode(JSONObject paramJSONObject) throws JSONException; 34 | } 35 | 36 | public static void registerDefaultDecoders() { 37 | /* 38 | registerDecoder("Batch", new ParseFieldOperationFactory() { 39 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 40 | ParseFieldOperation op = null; 41 | JSONArray ops = object.getJSONArray("ops"); 42 | for (int i = 0; i < ops.length(); i++) { 43 | ParseFieldOperation nextOp = ParseFieldOperations.decode( 44 | ops.getJSONObject(i)); 45 | op = nextOp.mergeWithPrevious(op); 46 | } 47 | return op; 48 | } 49 | }); 50 | */ 51 | 52 | registerDecoder("Delete", new ParseFieldOperationFactory() { 53 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 54 | return new DeleteFieldOperation(); 55 | } 56 | }); 57 | registerDecoder("Increment", new ParseFieldOperationFactory() { 58 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 59 | return new IncrementFieldOperation((Number) object 60 | .opt("amount")); 61 | } 62 | }); 63 | registerDecoder("Add", new ParseFieldOperationFactory() { 64 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 65 | return new AddOperation(object.opt("objects")); 66 | } 67 | }); 68 | registerDecoder("AddUnique", new ParseFieldOperationFactory() { 69 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 70 | return new AddUniqueOperation(object.opt("objects")); 71 | } 72 | }); 73 | registerDecoder("Remove", new ParseFieldOperationFactory() { 74 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 75 | return new RemoveFieldOperation(object.opt("objects")); 76 | } 77 | }); 78 | registerDecoder("AddRelation", new ParseFieldOperationFactory() { 79 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 80 | JSONArray objectsArray = object.optJSONArray("objects"); 81 | List objectsList = (List) ParseDecoder.decode(objectsArray); 82 | return new RelationOperation(new HashSet(objectsList), 83 | null); 84 | } 85 | }); 86 | registerDecoder("RemoveRelation", new ParseFieldOperationFactory() { 87 | public ParseFieldOperation decode(JSONObject object) throws JSONException { 88 | JSONArray objectsArray = object.optJSONArray("objects"); 89 | List objectsList = (List) ParseDecoder.decode(objectsArray); 90 | return new RelationOperation(null, 91 | new HashSet(objectsList)); 92 | } 93 | }); 94 | } 95 | 96 | public static ParseFieldOperation decode(JSONObject encoded) throws JSONException { 97 | String op = encoded.optString("__op"); 98 | ParseFieldOperationFactory factory = (ParseFieldOperationFactory) opDecoderMap.get(op); 99 | if (factory == null) { 100 | throw new RuntimeException("Unable to decode operation of type " + op); 101 | } 102 | return factory.decode(encoded); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/RelationOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | import org.parse4j.ParseObject; 10 | import org.parse4j.ParseRelation; 11 | import org.parse4j.encode.ParseObjectEncodingStrategy; 12 | import org.parse4j.util.ParseEncoder; 13 | 14 | public class RelationOperation implements ParseFieldOperation { 15 | 16 | private String targetClass; 17 | private Set relationsToAdd; 18 | private Set relationsToRemove; 19 | 20 | public RelationOperation(Set newRelationsToAdd, Set newRelationsToRemove) { 21 | this.targetClass = null; 22 | this.relationsToAdd = new HashSet(); 23 | this.relationsToRemove = new HashSet(); 24 | 25 | if (newRelationsToAdd != null) { 26 | for (ParseObject object : newRelationsToAdd) { 27 | addParseObjectToSet(object, this.relationsToAdd); 28 | 29 | if (this.targetClass == null) { 30 | this.targetClass = object.getClassName(); 31 | } else if (!this.targetClass.equals(object.getClassName())) { 32 | throw new IllegalArgumentException( 33 | "All objects in a relation must be of the same class."); 34 | } 35 | 36 | } 37 | 38 | } 39 | 40 | if (newRelationsToRemove != null) { 41 | for (ParseObject object : newRelationsToRemove) { 42 | addParseObjectToSet(object, this.relationsToRemove); 43 | 44 | if (this.targetClass == null) { 45 | this.targetClass = object.getClassName(); 46 | } else if (!this.targetClass.equals(object.getClassName())) { 47 | throw new IllegalArgumentException( 48 | "All objects in a relation must be of the same class."); 49 | } 50 | 51 | } 52 | 53 | } 54 | 55 | if (this.targetClass == null) 56 | throw new IllegalArgumentException( 57 | "Cannot create a ParseRelationOperation with no objects."); 58 | } 59 | 60 | private void addParseObjectToSet(ParseObject obj, Set set) { 61 | 62 | if (obj.getObjectId() == null) { 63 | set.add(obj); 64 | return; 65 | } 66 | 67 | for (ParseObject existingObject : set) { 68 | if (obj.getObjectId().equals(existingObject.getObjectId())) { 69 | set.remove(existingObject); 70 | } 71 | } 72 | set.add(obj); 73 | } 74 | 75 | public String getTargetClass() { 76 | return this.targetClass; 77 | } 78 | 79 | public JSONArray convertSetToArray(Set set, ParseObjectEncodingStrategy objectEncoder) throws JSONException { 80 | JSONArray array = new JSONArray(); 81 | for (ParseObject obj : set) { 82 | array.put(ParseEncoder.encode(obj, objectEncoder)); 83 | } 84 | return array; 85 | } 86 | 87 | @SuppressWarnings("unchecked") 88 | @Override 89 | public Object apply(Object oldValue, ParseObject parseObject, String key) { 90 | ParseRelationrelation = null; 91 | 92 | if (oldValue == null) { 93 | relation = new ParseRelation(parseObject, key); 94 | relation.setTargetClass(this.targetClass); 95 | } else if ((oldValue instanceof ParseRelation)) { 96 | relation = (ParseRelation) oldValue; 97 | if ((this.targetClass != null) && (relation.getTargetClass() != null)) { 98 | if (!relation.getTargetClass().equals(this.targetClass)) { 99 | throw new IllegalArgumentException( 100 | "Related object object must be of class " 101 | + relation.getTargetClass() + ", but " 102 | + this.targetClass + " was passed in."); 103 | } 104 | 105 | relation.setTargetClass(this.targetClass); 106 | } 107 | 108 | } else { 109 | throw new IllegalArgumentException( 110 | "Operation is invalid after previous operation."); 111 | } 112 | return relation; 113 | } 114 | 115 | @Override 116 | public JSONObject encode(ParseObjectEncodingStrategy objectEncoder) throws JSONException { 117 | 118 | JSONObject adds = null; 119 | JSONObject removes = null; 120 | 121 | if (this.relationsToAdd.size() > 0) { 122 | adds = new JSONObject(); 123 | adds.put("__op", "AddRelation"); 124 | adds.put("objects", convertSetToArray(this.relationsToAdd, objectEncoder)); 125 | } 126 | 127 | if (this.relationsToRemove.size() > 0) { 128 | removes = new JSONObject(); 129 | removes.put("__op", "RemoveRelation"); 130 | removes.put("objects", convertSetToArray(this.relationsToRemove, objectEncoder)); 131 | } 132 | 133 | if ((adds != null) && (removes != null)) { 134 | JSONObject result = new JSONObject(); 135 | result.put("__op", "Batch"); 136 | JSONArray ops = new JSONArray(); 137 | ops.put(adds); 138 | ops.put(removes); 139 | result.put("ops", ops); 140 | return result; 141 | } 142 | 143 | if (adds != null) { 144 | return adds; 145 | } 146 | 147 | if (removes != null) { 148 | return removes; 149 | } 150 | 151 | throw new IllegalArgumentException( 152 | "A ParseRelationOperation was created without any data."); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/RemoveFieldOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.HashSet; 6 | 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | import org.parse4j.ParseObject; 10 | import org.parse4j.encode.ParseObjectEncodingStrategy; 11 | import org.parse4j.util.ParseEncoder; 12 | 13 | public class RemoveFieldOperation implements ParseFieldOperation { 14 | 15 | protected HashSet objects = new HashSet(); 16 | 17 | public RemoveFieldOperation(Collection coll) { 18 | this.objects.addAll(coll); 19 | } 20 | 21 | public RemoveFieldOperation(Object o) { 22 | this.objects.add(o); 23 | } 24 | 25 | @Override 26 | public Object apply(Object oldValue, ParseObject parseObject, String key) { 27 | throw new IllegalArgumentException("not implemented!"); 28 | } 29 | 30 | @Override 31 | public Object encode(ParseObjectEncodingStrategy objectEncoder) 32 | throws JSONException { 33 | JSONObject output = new JSONObject(); 34 | output.put("__op", "Remove"); 35 | output.put("objects", ParseEncoder.encode(new ArrayList(this.objects), objectEncoder)); 36 | return output; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/operation/SetFieldOperation.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.operation; 2 | 3 | import org.json.JSONException; 4 | import org.parse4j.ParseObject; 5 | import org.parse4j.encode.ParseObjectEncodingStrategy; 6 | import org.parse4j.util.ParseEncoder; 7 | 8 | public class SetFieldOperation implements ParseFieldOperation { 9 | 10 | private Object value; 11 | 12 | public SetFieldOperation(Object value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public Object apply(Object oldValue, ParseObject parseObject, String key) { 18 | return value; 19 | } 20 | 21 | @Override 22 | public Object encode(ParseObjectEncodingStrategy objectEncoder) throws JSONException { 23 | 24 | return ParseEncoder.encode(value, objectEncoder); 25 | 26 | /* 27 | if(value instanceof byte[]) { 28 | byte[] bytes = (byte[]) value; 29 | JSONObject output = new JSONObject(); 30 | output.put("__type", "Bytes"); 31 | output.put("base64", Base64.encodeBase64String(bytes)); 32 | return output; 33 | } 34 | 35 | if(value instanceof Date) { 36 | Date dt = (Date) value; 37 | JSONObject output = new JSONObject(); 38 | output.put("__type", "Date"); 39 | output.put("iso", Parse.encodeDate(dt)); 40 | return output; 41 | } 42 | 43 | if(value instanceof Map) { 44 | Map map = (Map) value; 45 | JSONObject json = new JSONObject(); 46 | for (String key : map.keySet()) { 47 | json.put(key, map.get(key)); 48 | } 49 | return json; 50 | } 51 | 52 | if(value instanceof ParseFile) { 53 | ParseFile file = (ParseFile) value; 54 | JSONObject output = new JSONObject(); 55 | output.put("__type", "File"); 56 | output.put("name", file.getName()); 57 | output.put("url", file.getUrl()); 58 | return output; 59 | } 60 | 61 | if(value instanceof ParseGeoPoint) { 62 | ParseGeoPoint gp = (ParseGeoPoint) value; 63 | JSONObject output = new JSONObject(); 64 | output.put("__type", "GeoPoint"); 65 | output.put("latitude", gp.getLatitude()); 66 | output.put("longitude", gp.getLongitude()); 67 | return output; 68 | } 69 | 70 | if(value instanceof ParseObject) { 71 | ParseObject po = (ParseObject) value; 72 | JSONObject output = new JSONObject(); 73 | output.put("__type", "Pointer"); 74 | output.put("className", po.getClassName()); 75 | output.put("objectId", po.getObjectId()); 76 | return output; 77 | } 78 | 79 | return value; 80 | 81 | */ 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/util/ParseEncoder.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.util; 2 | 3 | import java.util.Date; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.apache.commons.codec.binary.Base64; 9 | import org.json.JSONArray; 10 | import org.json.JSONObject; 11 | import org.parse4j.Parse; 12 | import org.parse4j.ParseFile; 13 | import org.parse4j.ParseGeoPoint; 14 | import org.parse4j.ParseObject; 15 | import org.parse4j.ParseQuery; 16 | import org.parse4j.ParseRelation; 17 | import org.parse4j.encode.ParseObjectEncodingStrategy; 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | 21 | public class ParseEncoder { 22 | 23 | private static Logger LOGGER = LoggerFactory.getLogger(ParseEncoder.class); 24 | 25 | @SuppressWarnings({ "rawtypes", "unchecked" }) 26 | public static Object encode(Object value, ParseObjectEncodingStrategy objectEncoder) { 27 | 28 | if (value instanceof ParseObject) { 29 | return objectEncoder.encodeRelatedObject((ParseObject) value); 30 | } 31 | 32 | if (value instanceof byte[]) { 33 | byte[] bytes = (byte[]) value; 34 | JSONObject output = new JSONObject(); 35 | output.put("__type", "Bytes"); 36 | output.put("base64", Base64.encodeBase64String(bytes)); 37 | return output; 38 | } 39 | 40 | if (value instanceof Date) { 41 | Date dt = (Date) value; 42 | JSONObject output = new JSONObject(); 43 | output.put("__type", "Date"); 44 | output.put("iso", Parse.encodeDate(dt)); 45 | return output; 46 | } 47 | 48 | if (value instanceof List) { 49 | JSONArray array = new JSONArray(); 50 | List list = (List) value; 51 | Iterator i = list.iterator(); 52 | while (i.hasNext()) { 53 | array.put(encode(i.next(), objectEncoder)); 54 | } 55 | return array; 56 | } 57 | 58 | if (value instanceof JSONObject) { 59 | JSONObject map = (JSONObject) value; 60 | JSONObject json = new JSONObject(); 61 | Iterator keys = map.keys(); 62 | while (keys.hasNext()) { 63 | String key = (String) keys.next(); 64 | json.put(key, encode(map.opt(key), objectEncoder)); 65 | } 66 | return json; 67 | } 68 | 69 | if (value instanceof JSONArray) { 70 | JSONArray array = (JSONArray) value; 71 | JSONArray json = new JSONArray(); 72 | for (int i = 0; i < array.length(); i++) { 73 | json.put(encode(array.opt(i), objectEncoder)); 74 | } 75 | return json; 76 | } 77 | 78 | if (value instanceof Map) { 79 | Map map = (Map) value; 80 | JSONObject json = new JSONObject(); 81 | for (String key : map.keySet()) { 82 | json.put(key, encode(map.get(key), objectEncoder)); 83 | } 84 | return json; 85 | } 86 | 87 | if ((value instanceof ParseRelation)) { 88 | ParseRelation relation = (ParseRelation) value; 89 | return relation.encodeToJSON(objectEncoder); 90 | } 91 | 92 | if ((value instanceof ParseQuery.RelationConstraint)) { 93 | return ((ParseQuery.RelationConstraint) value).encode(objectEncoder); 94 | } 95 | 96 | if(value instanceof ParseFile) { 97 | ParseFile file = (ParseFile) value; 98 | JSONObject output = new JSONObject(); 99 | output.put("__type", "File"); 100 | output.put("name", file.getName()); 101 | output.put("url", file.getUrl()); 102 | return output; 103 | } 104 | 105 | if(value instanceof ParseGeoPoint) { 106 | ParseGeoPoint gp = (ParseGeoPoint) value; 107 | JSONObject output = new JSONObject(); 108 | output.put("__type", "GeoPoint"); 109 | output.put("latitude", gp.getLatitude()); 110 | output.put("longitude", gp.getLongitude()); 111 | return output; 112 | } 113 | 114 | if(value instanceof ParseObject) { 115 | ParseObject po = (ParseObject) value; 116 | JSONObject output = new JSONObject(); 117 | output.put("__type", "Pointer"); 118 | output.put("className", po.getClassName()); 119 | output.put("objectId", po.getObjectId()); 120 | return output; 121 | } 122 | 123 | if(value instanceof ParseQuery){ 124 | return ((ParseQuery) value).toREST(); 125 | } 126 | 127 | if(Parse.isValidType(value)) { 128 | return value; 129 | } 130 | 131 | LOGGER.error("Object type not decoded: " + value.getClass().getCanonicalName()); 132 | throw new IllegalArgumentException("Invalid type for ParseObject: " + value.getClass().toString()); 133 | 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/util/ParseRegistry.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.util; 2 | 3 | import java.lang.reflect.Member; 4 | import java.lang.reflect.Modifier; 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | import org.parse4j.ParseClassName; 9 | import org.parse4j.ParseObject; 10 | import org.parse4j.ParseRole; 11 | import org.parse4j.ParseUser; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | public class ParseRegistry { 16 | 17 | private static Logger LOGGER = LoggerFactory.getLogger(ParseRegistry.class); 18 | 19 | private static final Map, String> classNames = 20 | new ConcurrentHashMap, String>(); 21 | 22 | private static final Map> objectTypes = 23 | new ConcurrentHashMap>(); 24 | 25 | public static void registerDefaultSubClasses() { 26 | registerSubclass(ParseUser.class); 27 | registerSubclass(ParseRole.class); 28 | } 29 | 30 | public static void unregisterSubclass(String className) { 31 | objectTypes.remove(className); 32 | } 33 | 34 | public static void registerSubclass(Class subclass) { 35 | 36 | String className = getClassName(subclass); 37 | if(LOGGER.isDebugEnabled()) { 38 | LOGGER.debug("Registering sub class {}", className); 39 | } 40 | if (className == null) { 41 | throw new IllegalArgumentException( 42 | "No ParseClassName annoation provided on " + subclass); 43 | } 44 | 45 | if (subclass.getDeclaredConstructors().length > 0) { 46 | try { 47 | if (!isAccessible(subclass.getDeclaredConstructor(new Class[0]))) 48 | throw new IllegalArgumentException( 49 | "Default constructor for " + subclass 50 | + " is not accessible."); 51 | } catch (NoSuchMethodException e) { 52 | throw new IllegalArgumentException( 53 | "No default constructor provided for " + subclass); 54 | } 55 | } 56 | 57 | Class oldValue = (Class) objectTypes.get(className); 58 | if ((oldValue != null) && (subclass.isAssignableFrom(oldValue))) { 59 | return; 60 | } 61 | 62 | objectTypes.put(className, subclass); 63 | 64 | } 65 | 66 | private static boolean isAccessible(Member m) { 67 | return (Modifier.isPublic(m.getModifiers())) 68 | || ((m.getDeclaringClass().getPackage().getName() 69 | .equals("com.parse")) 70 | && (!Modifier.isPrivate(m.getModifiers())) && (!Modifier 71 | .isProtected(m.getModifiers()))); 72 | } 73 | 74 | public static String getClassName(Class clazz) { 75 | String name = (String) classNames.get(clazz); 76 | if (name == null) { 77 | ParseClassName info = (ParseClassName) clazz.getAnnotation(ParseClassName.class); 78 | if (info == null) { 79 | return null; 80 | } 81 | name = info.value(); 82 | classNames.put(clazz, name); 83 | } 84 | return name; 85 | } 86 | 87 | public static Class getParseClass(String className) { 88 | Class value = (Class) objectTypes.get(className); 89 | return value; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/parse4j/util/Preconditions.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.util; 2 | 3 | import java.util.NoSuchElementException; 4 | 5 | /** 6 | * Simple static methods to be called at the start of your own methods to verify 7 | * correct arguments and state. This allows constructs such as 8 | * 9 | *
 10 |  * if (count <= 0) {
 11 |  * 	throw new IllegalArgumentException("must be positive: " + count);
 12 |  * }
 13 |  * 
14 | * 15 | * to be replaced with the more compact 16 | * 17 | *
 18 |  * checkArgument(count > 0, "must be positive: %s", count);
 19 |  * 
20 | * 21 | * Note that the sense of the expression is inverted; with {@code Preconditions} 22 | * you declare what you expect to be true, just as you do with an 24 | * {@code assert} or a JUnit {@code assertTrue} call. 25 | * 26 | *

27 | * Warning: only the {@code "%s"} specifier is recognized as a 28 | * placeholder in these messages, not the full range of 29 | * {@link String#format(String, Object[])} specifiers. 30 | * 31 | *

32 | * Take care not to confuse precondition checking with other similar types of 33 | * checks! Precondition exceptions -- including those provided here, but also 34 | * {@link IndexOutOfBoundsException}, {@link NoSuchElementException}, 35 | * {@link UnsupportedOperationException} and others -- are used to signal that 36 | * the calling method has made an error. This tells the caller that it 37 | * should not have invoked the method when it did, with the arguments it did, or 38 | * perhaps ever. Postcondition or other invariant failures should not throw 39 | * these types of exceptions. 40 | * 41 | *

42 | * See the Guava User Guide on using 44 | * {@code Preconditions}. 45 | * 46 | * @author Kevin Bourrillion 47 | * @since 2.0 (imported from Google Collections Library) 48 | */ 49 | public final class Preconditions { 50 | private Preconditions() { 51 | } 52 | 53 | /** 54 | * Ensures the truth of an expression involving one or more parameters to 55 | * the calling method. 56 | * 57 | * @param expression 58 | * a boolean expression 59 | * @throws IllegalArgumentException 60 | * if {@code expression} is false 61 | */ 62 | public static void checkArgument(boolean expression) { 63 | if (!expression) { 64 | throw new IllegalArgumentException(); 65 | } 66 | } 67 | 68 | /** 69 | * Ensures the truth of an expression involving one or more parameters to 70 | * the calling method. 71 | * 72 | * @param expression 73 | * a boolean expression 74 | * @param errorMessage 75 | * the exception message to use if the check fails; will be 76 | * converted to a string using {@link String#valueOf(Object)} 77 | * @throws IllegalArgumentException 78 | * if {@code expression} is false 79 | */ 80 | public static void checkArgument(boolean expression, Object errorMessage) { 81 | if (!expression) { 82 | throw new IllegalArgumentException(String.valueOf(errorMessage)); 83 | } 84 | } 85 | 86 | /** 87 | * Ensures the truth of an expression involving one or more parameters to 88 | * the calling method. 89 | * 90 | * @param expression 91 | * a boolean expression 92 | * @param errorMessageTemplate 93 | * a template for the exception message should the check fail. 94 | * The message is formed by replacing each {@code %s} placeholder 95 | * in the template with an argument. These are matched by 96 | * position - the first {@code %s} gets 97 | * {@code errorMessageArgs[0]}, etc. Unmatched arguments will be 98 | * appended to the formatted message in square braces. Unmatched 99 | * placeholders will be left as-is. 100 | * @param errorMessageArgs 101 | * the arguments to be substituted into the message template. 102 | * Arguments are converted to strings using 103 | * {@link String#valueOf(Object)}. 104 | * @throws IllegalArgumentException 105 | * if {@code expression} is false 106 | * @throws NullPointerException 107 | * if the check fails and either {@code errorMessageTemplate} or 108 | * {@code errorMessageArgs} is null (don't let this happen) 109 | */ 110 | public static void checkArgument(boolean expression, 111 | String errorMessageTemplate, Object... errorMessageArgs) { 112 | if (!expression) { 113 | throw new IllegalArgumentException(format(errorMessageTemplate, 114 | errorMessageArgs)); 115 | } 116 | } 117 | 118 | /** 119 | * Ensures the truth of an expression involving the state of the calling 120 | * instance, but not involving any parameters to the calling method. 121 | * 122 | * @param expression 123 | * a boolean expression 124 | * @throws IllegalStateException 125 | * if {@code expression} is false 126 | */ 127 | public static void checkState(boolean expression) { 128 | if (!expression) { 129 | throw new IllegalStateException(); 130 | } 131 | } 132 | 133 | /** 134 | * Ensures the truth of an expression involving the state of the calling 135 | * instance, but not involving any parameters to the calling method. 136 | * 137 | * @param expression 138 | * a boolean expression 139 | * @param errorMessage 140 | * the exception message to use if the check fails; will be 141 | * converted to a string using {@link String#valueOf(Object)} 142 | * @throws IllegalStateException 143 | * if {@code expression} is false 144 | */ 145 | public static void checkState(boolean expression, Object errorMessage) { 146 | if (!expression) { 147 | throw new IllegalStateException(String.valueOf(errorMessage)); 148 | } 149 | } 150 | 151 | /** 152 | * Ensures the truth of an expression involving the state of the calling 153 | * instance, but not involving any parameters to the calling method. 154 | * 155 | * @param expression 156 | * a boolean expression 157 | * @param errorMessageTemplate 158 | * a template for the exception message should the check fail. 159 | * The message is formed by replacing each {@code %s} placeholder 160 | * in the template with an argument. These are matched by 161 | * position - the first {@code %s} gets 162 | * {@code errorMessageArgs[0]}, etc. Unmatched arguments will be 163 | * appended to the formatted message in square braces. Unmatched 164 | * placeholders will be left as-is. 165 | * @param errorMessageArgs 166 | * the arguments to be substituted into the message template. 167 | * Arguments are converted to strings using 168 | * {@link String#valueOf(Object)}. 169 | * @throws IllegalStateException 170 | * if {@code expression} is false 171 | * @throws NullPointerException 172 | * if the check fails and either {@code errorMessageTemplate} or 173 | * {@code errorMessageArgs} is null (don't let this happen) 174 | */ 175 | public static void checkState(boolean expression, 176 | String errorMessageTemplate, Object... errorMessageArgs) { 177 | if (!expression) { 178 | throw new IllegalStateException(format(errorMessageTemplate, 179 | errorMessageArgs)); 180 | } 181 | } 182 | 183 | /** 184 | * Ensures that an object reference passed as a parameter to the calling 185 | * method is not null. 186 | * 187 | * @param reference 188 | * an object reference 189 | * @return the non-null reference that was validated 190 | * @throws NullPointerException 191 | * if {@code reference} is null 192 | */ 193 | public static T checkNotNull(T reference) { 194 | if (reference == null) { 195 | throw new NullPointerException(); 196 | } 197 | return reference; 198 | } 199 | 200 | /** 201 | * Ensures that an object reference passed as a parameter to the calling 202 | * method is not null. 203 | * 204 | * @param reference 205 | * an object reference 206 | * @param errorMessage 207 | * the exception message to use if the check fails; will be 208 | * converted to a string using {@link String#valueOf(Object)} 209 | * @return the non-null reference that was validated 210 | * @throws NullPointerException 211 | * if {@code reference} is null 212 | */ 213 | public static T checkNotNull(T reference, Object errorMessage) { 214 | if (reference == null) { 215 | throw new NullPointerException(String.valueOf(errorMessage)); 216 | } 217 | return reference; 218 | } 219 | 220 | /** 221 | * Ensures that an object reference passed as a parameter to the calling 222 | * method is not null. 223 | * 224 | * @param reference 225 | * an object reference 226 | * @param errorMessageTemplate 227 | * a template for the exception message should the check fail. 228 | * The message is formed by replacing each {@code %s} placeholder 229 | * in the template with an argument. These are matched by 230 | * position - the first {@code %s} gets 231 | * {@code errorMessageArgs[0]}, etc. Unmatched arguments will be 232 | * appended to the formatted message in square braces. Unmatched 233 | * placeholders will be left as-is. 234 | * @param errorMessageArgs 235 | * the arguments to be substituted into the message template. 236 | * Arguments are converted to strings using 237 | * {@link String#valueOf(Object)}. 238 | * @return the non-null reference that was validated 239 | * @throws NullPointerException 240 | * if {@code reference} is null 241 | */ 242 | public static T checkNotNull(T reference, String errorMessageTemplate, 243 | Object... errorMessageArgs) { 244 | if (reference == null) { 245 | // If either of these parameters is null, the right thing happens 246 | // anyway 247 | throw new NullPointerException(format(errorMessageTemplate, 248 | errorMessageArgs)); 249 | } 250 | return reference; 251 | } 252 | 253 | /* 254 | * All recent hotspots (as of 2009) *really* like to have the natural code 255 | * 256 | * if (guardExpression) { throw new BadException(messageExpression); } 257 | * 258 | * refactored so that messageExpression is moved to a separate 259 | * String-returning method. 260 | * 261 | * if (guardExpression) { throw new BadException(badMsg(...)); } 262 | * 263 | * The alternative natural refactorings into void or Exception-returning 264 | * methods are much slower. This is a big deal - we're talking factors of 265 | * 2-8 in microbenchmarks, not just 10-20%. (This is a hotspot optimizer 266 | * bug, which should be fixed, but that's a separate, big project). 267 | * 268 | * The coding pattern above is heavily used in java.util, e.g. in ArrayList. 269 | * There is a RangeCheckMicroBenchmark in the JDK that was used to test 270 | * this. 271 | * 272 | * But the methods in this class want to throw different exceptions, 273 | * depending on the args, so it appears that this pattern is not directly 274 | * applicable. But we can use the ridiculous, devious trick of throwing an 275 | * exception in the middle of the construction of another exception. Hotspot 276 | * is fine with that. 277 | */ 278 | 279 | /** 280 | * Ensures that {@code index} specifies a valid element in an array, 281 | * list or string of size {@code size}. An element index may range from 282 | * zero, inclusive, to {@code size}, exclusive. 283 | * 284 | * @param index 285 | * a user-supplied index identifying an element of an array, list 286 | * or string 287 | * @param size 288 | * the size of that array, list or string 289 | * @return the value of {@code index} 290 | * @throws IndexOutOfBoundsException 291 | * if {@code index} is negative or is not less than {@code size} 292 | * @throws IllegalArgumentException 293 | * if {@code size} is negative 294 | */ 295 | public static int checkElementIndex(int index, int size) { 296 | return checkElementIndex(index, size, "index"); 297 | } 298 | 299 | /** 300 | * Ensures that {@code index} specifies a valid element in an array, 301 | * list or string of size {@code size}. An element index may range from 302 | * zero, inclusive, to {@code size}, exclusive. 303 | * 304 | * @param index 305 | * a user-supplied index identifying an element of an array, list 306 | * or string 307 | * @param size 308 | * the size of that array, list or string 309 | * @param desc 310 | * the text to use to describe this index in an error message 311 | * @return the value of {@code index} 312 | * @throws IndexOutOfBoundsException 313 | * if {@code index} is negative or is not less than {@code size} 314 | * @throws IllegalArgumentException 315 | * if {@code size} is negative 316 | */ 317 | public static int checkElementIndex(int index, int size, String desc) { 318 | // Carefully optimized for execution by hotspot (explanatory comment 319 | // above) 320 | if (index < 0 || index >= size) { 321 | throw new IndexOutOfBoundsException(badElementIndex(index, size, 322 | desc)); 323 | } 324 | return index; 325 | } 326 | 327 | private static String badElementIndex(int index, int size, String desc) { 328 | if (index < 0) { 329 | return format("%s (%s) must not be negative", desc, index); 330 | } else if (size < 0) { 331 | throw new IllegalArgumentException("negative size: " + size); 332 | } else { // index >= size 333 | return format("%s (%s) must be less than size (%s)", desc, index, 334 | size); 335 | } 336 | } 337 | 338 | /** 339 | * Ensures that {@code index} specifies a valid position in an array, 340 | * list or string of size {@code size}. A position index may range from zero 341 | * to {@code size}, inclusive. 342 | * 343 | * @param index 344 | * a user-supplied index identifying a position in an array, list 345 | * or string 346 | * @param size 347 | * the size of that array, list or string 348 | * @return the value of {@code index} 349 | * @throws IndexOutOfBoundsException 350 | * if {@code index} is negative or is greater than {@code size} 351 | * @throws IllegalArgumentException 352 | * if {@code size} is negative 353 | */ 354 | public static int checkPositionIndex(int index, int size) { 355 | return checkPositionIndex(index, size, "index"); 356 | } 357 | 358 | /** 359 | * Ensures that {@code index} specifies a valid position in an array, 360 | * list or string of size {@code size}. A position index may range from zero 361 | * to {@code size}, inclusive. 362 | * 363 | * @param index 364 | * a user-supplied index identifying a position in an array, list 365 | * or string 366 | * @param size 367 | * the size of that array, list or string 368 | * @param desc 369 | * the text to use to describe this index in an error message 370 | * @return the value of {@code index} 371 | * @throws IndexOutOfBoundsException 372 | * if {@code index} is negative or is greater than {@code size} 373 | * @throws IllegalArgumentException 374 | * if {@code size} is negative 375 | */ 376 | public static int checkPositionIndex(int index, int size, String desc) { 377 | // Carefully optimized for execution by hotspot (explanatory comment 378 | // above) 379 | if (index < 0 || index > size) { 380 | throw new IndexOutOfBoundsException(badPositionIndex(index, size, 381 | desc)); 382 | } 383 | return index; 384 | } 385 | 386 | private static String badPositionIndex(int index, int size, String desc) { 387 | if (index < 0) { 388 | return format("%s (%s) must not be negative", desc, index); 389 | } else if (size < 0) { 390 | throw new IllegalArgumentException("negative size: " + size); 391 | } else { // index > size 392 | return format("%s (%s) must not be greater than size (%s)", desc, 393 | index, size); 394 | } 395 | } 396 | 397 | /** 398 | * Ensures that {@code start} and {@code end} specify a valid 399 | * positions in an array, list or string of size {@code size}, and 400 | * are in order. A position index may range from zero to {@code size}, 401 | * inclusive. 402 | * 403 | * @param start 404 | * a user-supplied index identifying a starting position in an 405 | * array, list or string 406 | * @param end 407 | * a user-supplied index identifying a ending position in an 408 | * array, list or string 409 | * @param size 410 | * the size of that array, list or string 411 | * @throws IndexOutOfBoundsException 412 | * if either index is negative or is greater than {@code size}, 413 | * or if {@code end} is less than {@code start} 414 | * @throws IllegalArgumentException 415 | * if {@code size} is negative 416 | */ 417 | public static void checkPositionIndexes(int start, int end, int size) { 418 | // Carefully optimized for execution by hotspot (explanatory comment 419 | // above) 420 | if (start < 0 || end < start || end > size) { 421 | throw new IndexOutOfBoundsException(badPositionIndexes(start, end, 422 | size)); 423 | } 424 | } 425 | 426 | private static String badPositionIndexes(int start, int end, int size) { 427 | if (start < 0 || start > size) { 428 | return badPositionIndex(start, size, "start index"); 429 | } 430 | if (end < 0 || end > size) { 431 | return badPositionIndex(end, size, "end index"); 432 | } 433 | // end < start 434 | return format("end index (%s) must not be less than start index (%s)", 435 | end, start); 436 | } 437 | 438 | /** 439 | * Substitutes each {@code %s} in {@code template} with an argument. These 440 | * are matched by position - the first {@code %s} gets {@code args[0]}, etc. 441 | * If there are more arguments than placeholders, the unmatched arguments 442 | * will be appended to the end of the formatted message in square braces. 443 | * 444 | * @param template 445 | * a non-null string containing 0 or more {@code %s} 446 | * placeholders. 447 | * @param args 448 | * the arguments to be substituted into the message template. 449 | * Arguments are converted to strings using 450 | * {@link String#valueOf(Object)}. Arguments can be null. 451 | */ 452 | static String format(String template, Object... args) { 453 | template = String.valueOf(template); // null -> "null" 454 | 455 | // start substituting the arguments into the '%s' placeholders 456 | StringBuilder builder = new StringBuilder(template.length() + 16 457 | * args.length); 458 | int templateStart = 0; 459 | int i = 0; 460 | while (i < args.length) { 461 | int placeholderStart = template.indexOf("%s", templateStart); 462 | if (placeholderStart == -1) { 463 | break; 464 | } 465 | builder.append(template.substring(templateStart, placeholderStart)); 466 | builder.append(args[i++]); 467 | templateStart = placeholderStart + 2; 468 | } 469 | builder.append(template.substring(templateStart)); 470 | 471 | // if we run out of placeholders, append the extra args in square braces 472 | if (i < args.length) { 473 | builder.append(" ["); 474 | builder.append(args[i++]); 475 | while (i < args.length) { 476 | builder.append(", "); 477 | builder.append(args[i++]); 478 | } 479 | builder.append(']'); 480 | } 481 | 482 | return builder.toString(); 483 | } 484 | } -------------------------------------------------------------------------------- /src/test/java/org/parse4j/Parse4JTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.io.IOException; 4 | import java.io.RandomAccessFile; 5 | import java.util.ArrayList; 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | import org.junit.AfterClass; 10 | import org.junit.BeforeClass; 11 | 12 | public class Parse4JTestCase { 13 | 14 | public static String CLASS_NAME = "parse4j"; 15 | private static String APP_ID = "RWjFpDDbwCIXF8Gy9dHEBpR7Fs2PZ0UzcNdxhAvf"; 16 | private static String APP_REST_API_ID = "EWpTGoOFgGr9vXfPLBRYZjhDL0pg4MQ1F7i3wWAq"; 17 | 18 | @BeforeClass 19 | public static void setupParse() { 20 | System.out.println("setupParse(): initializing..."); 21 | Parse.initialize(APP_ID, APP_REST_API_ID); 22 | } 23 | 24 | @AfterClass 25 | public static void tearDown() { 26 | System.out.println("tearDown(): finalizing..."); 27 | ParseExecutor.getExecutor().shutdown(); 28 | //while(!ParseExecutor.getExecutor().isTerminated()) { } 29 | } 30 | 31 | protected ParseObject getEmptyParseObject(String className) { 32 | ParseObject parseObject = new ParseObject(className); 33 | return parseObject; 34 | } 35 | 36 | protected ParseObject getParseObject(String className) { 37 | ParseObject parseObject = new ParseObject(className); 38 | parseObject.put("name", "parse developer"); 39 | parseObject.put("int", 10); 40 | parseObject.put("long", 10l); 41 | parseObject.put("boolean", true); 42 | parseObject.put("dob", new Date()); 43 | parseObject.put("double", 10.5); 44 | 45 | List types = new ArrayList(); 46 | types.add("type1"); 47 | types.add("type2"); 48 | types.add("type3"); 49 | parseObject.put("types", types); 50 | 51 | ParseGeoPoint gp = new ParseGeoPoint(40.0, -30.0); 52 | parseObject.put("location", gp); 53 | 54 | return parseObject; 55 | } 56 | 57 | protected ParseUser getParseUser(String number) { 58 | ParseUser parseUser = new ParseUser(); 59 | parseUser.setUsername("parse4j-user" + number); 60 | parseUser.setPassword("parse4j-password"); 61 | parseUser.setEmail("parse4j-email"+number+"@gmail.com"); 62 | parseUser.put("dob", new Date()); 63 | parseUser.put("city", "westbury"); 64 | parseUser.put("state", "ny"); 65 | return parseUser; 66 | } 67 | 68 | protected void sleep(int millis) { 69 | try { 70 | Thread.sleep(millis); 71 | } 72 | catch(InterruptedException e) { 73 | 74 | } 75 | } 76 | 77 | public byte[] getBytes(String fileName) throws ParseException { 78 | try { 79 | RandomAccessFile f = new RandomAccessFile(getClass().getResource(fileName).getFile(), "r"); 80 | byte[] b = new byte[(int)f.length()]; 81 | f.read(b); 82 | f.close(); 83 | return b; 84 | } 85 | catch(IOException e) { 86 | throw new ParseException(e); 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseAnalyticsTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.junit.Test; 7 | 8 | public class ParseAnalyticsTestCase extends Parse4JTestCase { 9 | 10 | 11 | @Test 12 | public void trackAppOpened() { 13 | System.out.println("trackAppOpened(): initializing..."); 14 | ParseAnalytics.trackAppOpened(); 15 | sleep(1000); 16 | } 17 | 18 | @Test 19 | public void trackJunitTest() { 20 | System.out.println("trackJunitTest(): initializing..."); 21 | ParseAnalytics.trackEvent("JUnitTestStarted"); 22 | sleep(1000); 23 | } 24 | 25 | @Test 26 | public void trackJunitTest2() { 27 | System.out.println("trackJunitTest2(): initializing..."); 28 | Map dimensions = new HashMap(); 29 | dimensions.put("attr1", "10"); 30 | dimensions.put("attr2", "127.0.0.1"); 31 | ParseAnalytics.trackEvent("JUnitTestStarted"); 32 | sleep(1000); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseBatchTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import java.util.List; 8 | 9 | import org.json.JSONArray; 10 | import org.json.JSONObject; 11 | import org.junit.Test; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | public class ParseBatchTestCase extends Parse4JTestCase { 16 | 17 | private static Logger LOGGER = LoggerFactory.getLogger(ParseBatchTestCase.class); 18 | 19 | @Test 20 | public void testReadData() throws ParseException{ 21 | ParseQuery query = ParseQuery.getQuery("Post"); 22 | query.limit(20); 23 | List find = query.find(); 24 | 25 | for (int i = 0; i < find.size(); i++) { 26 | ParseObject current = find.get(i); 27 | System.out.println(current.get("title")); 28 | System.out.println(current.getUpdatedAt()); 29 | } 30 | } 31 | @Test 32 | public void testBatchInsert() throws ParseException{ 33 | ParseBatch batcher = new ParseBatch(); 34 | for (int i = 0; i < 20; i++) { 35 | ParseObject obj = new ParseObject("Post"); 36 | obj.put("title", "input message " + i); 37 | batcher.createObject(obj); 38 | 39 | } 40 | JSONArray batch = batcher.batch(); 41 | assertNotNull(batch); 42 | assertTrue(batch.length() == 20); 43 | 44 | } 45 | @Test 46 | public void testBatchUpdate() throws ParseException{ 47 | ParseQuery query = ParseQuery.getQuery("Post"); 48 | query.limit(20); 49 | query.addDescendingOrder("updateAt"); 50 | List find = query.find(); 51 | LOGGER.info("size is " + find.size()); 52 | 53 | ParseBatch batcher = new ParseBatch(); 54 | for (int i = 0; i < find.size(); i++) { 55 | ParseObject current = find.get(i); 56 | current.put("title", "input updated message " + i); 57 | batcher.updateObject(current); 58 | } 59 | 60 | //send batch update 61 | JSONArray batch = batcher.batch(); 62 | assertNotNull(batch); 63 | assertTrue(batch.length() == 20); 64 | 65 | //refresh results 66 | find = query.find(); 67 | for (int i = 0; i < find.size(); i++) { 68 | assertEquals("not equal", "input updated message " + i , find.get(i).getString("title")); 69 | } 70 | } 71 | @Test 72 | public void testBatchDelete() throws ParseException{ 73 | final int size = 5; 74 | //first insert 5 objects that should be deleted ! 75 | for(int i = 0;i query = ParseQuery.getQuery("Post"); 82 | query.limit(size); 83 | query.addDescendingOrder("updatedAt"); 84 | List find = query.find(); 85 | ParseBatch batcher = new ParseBatch(); 86 | for (int i = 0; i < find.size(); i++) { 87 | ParseObject current = find.get(i); 88 | LOGGER.info("object found " + current.get("title")); 89 | LOGGER.info("updated at " + current.getUpdatedAt()); 90 | batcher.deleteObject(current); 91 | } 92 | JSONArray batch = batcher.batch(); 93 | assertNotNull(batch); 94 | assertEquals(batch.length(), find.size()); 95 | } 96 | 97 | @Test(expected = IllegalArgumentException.class) 98 | public void testFailureOnDelete() throws ParseException{ 99 | ParseBatch batch = new ParseBatch(); 100 | ParseObject obj = new ParseObject(); 101 | batch.deleteObject(obj); 102 | batch.batch(); 103 | } 104 | @Test(expected = IllegalArgumentException.class) 105 | public void testFailureOnUpdate() throws ParseException{ 106 | ParseBatch batch = new ParseBatch(); 107 | ParseObject obj = new ParseObject(); 108 | batch.updateObject(obj); 109 | batch.batch(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseCloudTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import java.util.HashMap; 7 | 8 | import org.junit.Test; 9 | import org.parse4j.callback.FunctionCallback; 10 | 11 | public class ParseCloudTestCase extends Parse4JTestCase { 12 | 13 | /* 14 | Parse.Cloud.define("helloWorld", function(request, response) { 15 | response.success("Hello, " + request.params.name + "!!!"); 16 | }); 17 | 18 | Parse.Cloud.define("Multiply", function(request, response) { 19 | response.success(request.params.A * request.params.B); 20 | }); 21 | 22 | Parse.Cloud.define("ForcedError", function(request, response) { 23 | response.error("forced error"); 24 | }); 25 | */ 26 | 27 | @Test 28 | public void testInvalidFunction() { 29 | System.out.println("InvalidFunction(): initializing..."); 30 | try { 31 | HashMap params = new HashMap(); 32 | params.put("name", "Parse"); 33 | String result = ParseCloud.callFunction("InvalidFunction", params); 34 | assertEquals("Hello, Parse!!!", result); 35 | } 36 | catch(ParseException pe) { 37 | assertEquals(ParseException.CLOUD_ERROR, pe.getCode()); 38 | } 39 | } 40 | 41 | @Test 42 | public void testForcedError() { 43 | System.out.println("testForcedError(): initializing..."); 44 | try { 45 | HashMap params = new HashMap(); 46 | params.put("name", "Parse"); 47 | String result = ParseCloud.callFunction("ForcedError", params); 48 | assertEquals("Hello, Parse!!!", result); 49 | } 50 | catch(ParseException pe) { 51 | assertEquals(ParseException.CLOUD_ERROR, pe.getCode()); 52 | } 53 | } 54 | 55 | @Test 56 | public void testHelloWorld() { 57 | System.out.println("testHelloWorld(): initializing..."); 58 | try { 59 | HashMap params = new HashMap(); 60 | params.put("name", "Parse"); 61 | String result = ParseCloud.callFunction("helloWorld", params); 62 | assertEquals("Hello, Parse!!!", result); 63 | } 64 | catch(ParseException pe) { 65 | assertNull("testHelloWorld(): should not have thrown ParseException", pe); 66 | } 67 | } 68 | 69 | @Test 70 | public void testMultiply() { 71 | System.out.println("testMultiply(): initializing..."); 72 | try { 73 | HashMap params = new HashMap(); 74 | params.put("A", 12); 75 | params.put("B", 4); 76 | Integer result = ParseCloud.callFunction("Multiply", params); 77 | assertEquals("48", result.toString()); 78 | } 79 | catch(ParseException pe) { 80 | assertNull("testMultiply(): should not have thrown ParseException", pe); 81 | } 82 | 83 | } 84 | 85 | @Test 86 | public void testCallInBackground() { 87 | System.out.println("testCallInBackground(): initializing..."); 88 | 89 | HashMap params = new HashMap(); 90 | params.put("A", 12); 91 | params.put("B", 4); 92 | ParseCloud.callFunctionInBackground("Multiply", params, new FunctionCallback() { 93 | 94 | @Override 95 | public void done(Integer result, ParseException parseException) { 96 | assertEquals("48", result.toString()); 97 | 98 | } 99 | 100 | }); 101 | sleep(2000); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseDecoderTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import org.json.JSONObject; 10 | import org.junit.Test; 11 | import org.parse4j.operation.ParseFieldOperation; 12 | 13 | public class ParseDecoderTestCase { 14 | 15 | @Test 16 | public void decode() throws ParseException { 17 | JSONObject jsonObject = new JSONObject( 18 | "{\"createdAt\":\"2015-12-28T06:18:45.493Z\",\"__type\":\"Object\",\"name\":\"test object\",\"nested_object\":{ \"createdAt\":\"2015-12-28T04:24:57.680Z\",\"__type\":\"Object\",\"name\":\"nested object\",\"className\":\"NestedTestClass\",\"objectId\":\"DdDjWiUT8y\",\"updatedAt\":\"2015-12-28T04:42:38.980Z\"},\"className\":\"TestClass\",\"objectId\":\"Ts7L6Bhv00\",\"updatedAt\":\"2015-12-30T11:31:51.512Z\"}"); 19 | ParseObject decodedObject = (ParseObject) ParseDecoder.decode(jsonObject); 20 | assertFalse(decodedObject.isDirty); 21 | assertNotNull(decodedObject.getCreatedAt()); 22 | assertNotNull(decodedObject.getUpdatedAt()); 23 | assertEquals("TestClass", decodedObject.getClassName()); 24 | assertEquals("test object", decodedObject.getString("name")); 25 | assertEquals("Object", decodedObject.getString("__type")); 26 | assertEquals("Ts7L6Bhv00", decodedObject.getObjectId()); 27 | List dirtyKeys = (List) getPrivateField(decodedObject, "dirtyKeys"); 28 | @SuppressWarnings("unchecked") 29 | Map operations = (Map) getPrivateField(decodedObject, "operations"); 30 | assertTrue(dirtyKeys.size() == 0); 31 | assertTrue(operations.size() == 0); 32 | ParseObject nestedObject = decodedObject.getParseObject("nested_object"); 33 | assertFalse(nestedObject.isDirty); 34 | assertNotNull(nestedObject.getCreatedAt()); 35 | assertNotNull(nestedObject.getUpdatedAt()); 36 | assertEquals("NestedTestClass", nestedObject.getClassName()); 37 | assertEquals("nested object", nestedObject.getString("name")); 38 | assertEquals("Object", nestedObject.getString("__type")); 39 | assertEquals("DdDjWiUT8y", nestedObject.getObjectId()); 40 | List dirtyKeys2 = (List) getPrivateField(nestedObject, "dirtyKeys"); 41 | @SuppressWarnings("unchecked") 42 | Map operations2 = (Map) getPrivateField(nestedObject, "operations"); 43 | assertTrue(dirtyKeys2.size() == 0); 44 | assertTrue(operations2.size() == 0); 45 | } 46 | 47 | private Object getPrivateField(Object obj, String fieldName) { 48 | try { 49 | Field field = obj.getClass().getDeclaredField(fieldName); 50 | field.setAccessible(true); 51 | Object value = field.get(obj); 52 | field.setAccessible(false); 53 | return value; 54 | } catch (Exception e) { 55 | return null; 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseFileTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.assertNull; 6 | import junit.framework.Assert; 7 | 8 | import org.junit.Test; 9 | import org.parse4j.callback.ProgressCallback; 10 | 11 | public class ParseFileTestCase extends Parse4JTestCase { 12 | 13 | @Test 14 | public void uploadTxt() { 15 | System.out.println("uploadTxt(): initializing..."); 16 | try { 17 | byte[] data = "Working at Parse is great!".getBytes(); 18 | ParseFile file = new ParseFile("resume.txt", data); 19 | file.save(); 20 | testParseFile(file); 21 | } 22 | catch(ParseException pe) { 23 | assertNull("uploadTxt(): should not have thrown ParseException", pe); 24 | } 25 | } 26 | 27 | @Test 28 | public void uploadPng() { 29 | System.out.println("uploadPng(): initializing..."); 30 | assertNotNull("Test file missing", getClass().getResource("/parse.png")); 31 | 32 | try { 33 | byte[] data = getBytes("/parse.png"); 34 | ParseFile file = new ParseFile("parse.png", data); 35 | file.save(); 36 | testParseFile(file); 37 | } 38 | catch(ParseException pe) { 39 | assertNull("uploadTxt(): should not have thrown ParseException", pe); 40 | } 41 | } 42 | 43 | @Test 44 | public void uploadDoc() { 45 | System.out.println("uploadDoc(): initializing..."); 46 | try { 47 | byte[] data = getBytes("/parse.docx"); 48 | ParseFile file = new ParseFile("parse.docx", data); 49 | file.save(); 50 | testParseFile(file); 51 | } 52 | catch(ParseException pe) { 53 | assertNull("uploadDoc(): should not have thrown ParseException", pe); 54 | } 55 | } 56 | 57 | @Test 58 | public void uploadExr() { 59 | System.out.println("uploadExr(): initializing..."); 60 | try { 61 | byte[] data = getBytes("/parse.exr"); 62 | ParseFile file = new ParseFile("parse.exr", data); 63 | file.save(); 64 | testParseFile(file); 65 | } 66 | catch(ParseException pe) { 67 | assertNull("uploadExr(): should not have thrown ParseException", pe); 68 | } 69 | } 70 | 71 | @Test 72 | public void uploadPdf() { 73 | System.out.println("uploadPdf(): initializing..."); 74 | try { 75 | byte[] data = getBytes("/parse.pdf"); 76 | ParseFile file = new ParseFile("parse.pdf", data); 77 | file.save(); 78 | testParseFile(file); 79 | } 80 | catch(ParseException pe) { 81 | assertNull("uploadPdf(): should not have thrown ParseException", pe); 82 | } 83 | } 84 | 85 | public void uploadPdfWithProgressCallback() { 86 | System.out.println("uploadPdf(): initializing..."); 87 | try { 88 | byte[] data = getBytes("/ml-1m.zip"); 89 | ParseFile file = new ParseFile("ml-1m.zip", data); 90 | file.save(new ProgressCallback() { 91 | 92 | @Override 93 | public void done(Integer percentDone) { 94 | System.out.println("uploadPdf(): progress " + percentDone + "%"); 95 | } 96 | }); 97 | sleep(2000); 98 | testParseFile(file); 99 | } 100 | catch(ParseException pe) { 101 | assertNull("uploadPdfWithProgressCallback(): should not have thrown ParseException", pe); 102 | } 103 | } 104 | 105 | @Test 106 | public void uploadDocAndGetData() { 107 | System.out.println("uploadDocAndGetData(): initializing..."); 108 | try { 109 | byte[] data = getBytes("/parse.docx"); 110 | ParseFile file = new ParseFile("parse.docx", data); 111 | file.save(); 112 | testParseFile(file); 113 | 114 | ParseFile getFile = new ParseFile(file.getName(), file.getUrl()); 115 | byte[] getData = getFile.getData(); 116 | System.out.println("uploadDocAndGetData(): data.length: " + data.length); 117 | System.out.println("uploadDocAndGetData(): getData.length: " + getData.length); 118 | assertEquals(data.length, getData.length); 119 | } 120 | catch(ParseException pe) { 121 | assertNull("uploadDocAndGetData(): should not have thrown ParseException", pe); 122 | } 123 | } 124 | 125 | public void testParseFile(ParseFile file) { 126 | System.out.println("Name: " + file.getName()); 127 | assertNotNull("name should not be null", file.getName()); 128 | System.out.println("File: " + file.getUrl()); 129 | assertNotNull("url should not be null", file.getUrl()); 130 | } 131 | 132 | 133 | 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseObjectCRUDTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertNotNull; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import java.util.Date; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.junit.runners.JUnit4; 11 | import org.parse4j.callback.DeleteCallback; 12 | import org.parse4j.callback.SaveCallback; 13 | 14 | @RunWith(JUnit4.class) 15 | public class ParseObjectCRUDTestCase extends Parse4JTestCase { 16 | 17 | @Test 18 | public void save() { 19 | System.out.println("save(): initializing..."); 20 | ParseObject parseObject = getParseObject(CLASS_NAME); 21 | 22 | try { 23 | parseObject.save(); 24 | System.out.println("save(): objectId: " + parseObject.getObjectId()); 25 | System.out.println("save(): createdAt: " + parseObject.getCreatedAt()); 26 | System.out.println("save(): updatedAt: " + parseObject.getUpdatedAt()); 27 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 28 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 29 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 30 | } 31 | catch(ParseException pe) { 32 | assertNull("save(): should not have thrown ParseException", pe); 33 | } 34 | } 35 | 36 | @Test 37 | public void saveWithFile() { 38 | System.out.println("saveWithFile(): initializing..."); 39 | ParseObject parseObject = getParseObject(CLASS_NAME); 40 | byte[] data = null; 41 | ParseFile file = null; 42 | 43 | try { 44 | 45 | data = getBytes("/parse.png"); 46 | file = new ParseFile("parse.png", data); 47 | file.save(); 48 | parseObject.put("pngFile", file); 49 | 50 | data = getBytes("/parse.pdf"); 51 | file = new ParseFile("parse.pdf", data); 52 | file.save(); 53 | parseObject.put("pdfFile", file); 54 | 55 | data = getBytes("/parse.docx"); 56 | file = new ParseFile("parse.docx", data); 57 | file.save(); 58 | parseObject.put("docxFile", file); 59 | 60 | parseObject.save(); 61 | System.out.println("saveWithFile(): objectId: " + parseObject.getObjectId()); 62 | System.out.println("saveWithFile(): createdAt: " + parseObject.getCreatedAt()); 63 | System.out.println("saveWithFile(): updatedAt: " + parseObject.getUpdatedAt()); 64 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 65 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 66 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 67 | } 68 | catch(ParseException pe) { 69 | assertNull("saveWithFile(): should not have thrown ParseException", pe); 70 | } 71 | } 72 | 73 | @Test 74 | public void update() { 75 | System.out.println("update(): initializing..."); 76 | ParseObject parseObject = getParseObject(CLASS_NAME); 77 | 78 | try { 79 | parseObject.save(); 80 | System.out.println("update(): objectId: " + parseObject.getObjectId()); 81 | System.out.println("update(): createdAt: " + parseObject.getCreatedAt()); 82 | System.out.println("update(): updatedAt: " + parseObject.getUpdatedAt()); 83 | System.out.println("update(): initial name: " + parseObject.getString("name")); 84 | System.out.println("update(): initial int: " + parseObject.getInt("int")); 85 | System.out.println("update(): initial double: " + parseObject.getDouble("double")); 86 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 87 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 88 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 89 | 90 | parseObject.put("name", "updated"); 91 | parseObject.increment("int"); 92 | parseObject.decrement("double"); 93 | parseObject.save(); 94 | System.out.println("update(): name: " + parseObject.getString("name")); 95 | System.out.println("update(): incrementedInt: " + parseObject.getInt("int")); 96 | System.out.println("update(): incrementedInt: " + parseObject.getDouble("double")); 97 | System.out.println("update(): createdAt: " + parseObject.getCreatedAt()); 98 | System.out.println("update(): updatedAt: " + parseObject.getUpdatedAt()); 99 | 100 | } 101 | catch(ParseException pe) { 102 | assertNull("update(): should not have thrown ParseException", pe); 103 | } 104 | } 105 | 106 | @Test 107 | public void delete() { 108 | System.out.println("delete(): initializing..."); 109 | ParseObject parseObject = getParseObject(CLASS_NAME); 110 | 111 | try { 112 | System.out.println("delete(): saving parseObject first..."); 113 | parseObject.save(); 114 | System.out.println("delete(): objectId: " + parseObject.getObjectId()); 115 | assertNotNull("delete(): objectId should not be null", parseObject.getObjectId()); 116 | assertNotNull("delete(): createdAt should not be null", parseObject.getCreatedAt()); 117 | assertNotNull("delete(): updatedAt should not be null", parseObject.getUpdatedAt()); 118 | System.out.println("delete(): deleting parseObject with objectId " + parseObject.getObjectId()); 119 | parseObject.delete(); 120 | assertNull("delete(): parseObject deleted, objectId should be null", parseObject.getObjectId()); 121 | assertNull("delete(): parseObject deleted, createdAt should not be null", parseObject.getCreatedAt()); 122 | assertNull("delete(): parseObject deleted, updatedAt should not be null", parseObject.getUpdatedAt()); 123 | } 124 | catch(ParseException pe) { 125 | assertNull("delete() should not have thrown ParseException", pe); 126 | } 127 | } 128 | 129 | 130 | public void saveInBackground() { 131 | System.out.println("saveInBackground(): initializing..."); 132 | final ParseObject parseObject = getParseObject(CLASS_NAME); 133 | 134 | parseObject.saveInBackground(new SaveCallback() { 135 | @Override 136 | public void done(ParseException parseException) { 137 | assertNull("saveInBackground(): parseException should not be null", parseException); 138 | System.out.println("saveInBackground(): objectId: " + parseObject.getObjectId()); 139 | System.out.println("saveInBackground(): createdAt: " + parseObject.getCreatedAt()); 140 | System.out.println("saveInBackground(): updatedAt: " + parseObject.getUpdatedAt()); 141 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 142 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 143 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 144 | } 145 | }); 146 | 147 | } 148 | 149 | public void updateInBackground() { 150 | System.out.println("update(): initializing..."); 151 | final ParseObject parseObject = getParseObject(CLASS_NAME); 152 | 153 | try { 154 | parseObject.save(); 155 | System.out.println("updateInBackground(): objectId: " + parseObject.getObjectId()); 156 | System.out.println("updateInBackground(): createdAt: " + parseObject.getCreatedAt()); 157 | System.out.println("updateInBackground(): updatedAt: " + parseObject.getUpdatedAt()); 158 | System.out.println("updateInBackground(): initial name: " + parseObject.getString("name")); 159 | System.out.println("updateInBackground(): initial int: " + parseObject.getInt("int")); 160 | System.out.println("updateInBackground(): initial double: " + parseObject.getDouble("double")); 161 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 162 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 163 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 164 | 165 | parseObject.put("name", "updated"); 166 | parseObject.increment("int"); 167 | parseObject.decrement("double"); 168 | parseObject.saveInBackground(new SaveCallback() { 169 | 170 | @Override 171 | public void done(ParseException parseException) { 172 | assertNull("updateInBackground(): parseException should not be null", parseException); 173 | System.out.println("updateInBackground(): name: " + parseObject.getString("name")); 174 | System.out.println("updateInBackground(): incrementedInt: " + parseObject.getInt("int")); 175 | System.out.println("updateInBackground(): incrementedInt: " + parseObject.getDouble("double")); 176 | System.out.println("updateInBackground(): createdAt: " + parseObject.getCreatedAt()); 177 | System.out.println("updateInBackground(): updatedAt: " + parseObject.getUpdatedAt()); 178 | 179 | } 180 | }); 181 | 182 | } 183 | catch(ParseException pe) { 184 | assertNull("update(): should not have thrown ParseException", pe); 185 | } 186 | } 187 | 188 | public void deleteInBackground() { 189 | System.out.println("deleteInBackground(): initializing..."); 190 | final ParseObject parseObject = getParseObject(CLASS_NAME); 191 | 192 | try { 193 | System.out.println("deleteInBackground(): saving parseObject first..."); 194 | parseObject.save(); 195 | String objectId = parseObject.getObjectId(); 196 | Date createdAt = parseObject.getCreatedAt(); 197 | Date updatedAt = parseObject.getUpdatedAt(); 198 | System.out.println("deleteInBackground(): objectId: " + objectId); 199 | System.out.println("deleteInBackground(): createdAt: " + createdAt); 200 | System.out.println("deleteInBackground(): updatedAt: " + updatedAt); 201 | assertNotNull("objectId should not be null", objectId); 202 | assertNotNull("createdAt should not be null", createdAt); 203 | assertNotNull("updatedAt should not be null", updatedAt); 204 | System.out.println("deleteInBackground(): deleting parseObject with objectId " + objectId); 205 | } 206 | catch(ParseException pe) { 207 | assertNull("deleteInBackground(): should not have thrown ParseException", pe); 208 | } 209 | 210 | parseObject.deleteInBackground(new DeleteCallback() { 211 | 212 | @Override 213 | public void done(ParseException parseException) { 214 | String objectId = parseObject.getObjectId(); 215 | Date createdAt = parseObject.getCreatedAt(); 216 | Date updatedAt = parseObject.getUpdatedAt(); 217 | assertNull("deleteInBackground(): parseObject deleted, objectId should be null", objectId); 218 | assertNull("deleteInBackground(): parseObject deleted, createdAt should not be null", createdAt); 219 | assertNull("deleteInBackground(): parseObject deleted, updatedAt should not be null", updatedAt); 220 | 221 | } 222 | }); 223 | 224 | } 225 | 226 | } 227 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseObjectCustomTest.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.assertNull; 6 | 7 | import org.junit.Test; 8 | import org.parse4j.custom.Person; 9 | import org.parse4j.custom.Person2; 10 | import org.parse4j.util.ParseRegistry; 11 | 12 | public class ParseObjectCustomTest extends Parse4JTestCase { 13 | 14 | @Test(expected = IllegalArgumentException.class) 15 | public void parseSubclassNoAnnotation() { 16 | ParseRegistry.registerSubclass(Person2.class); 17 | } 18 | 19 | @Test 20 | public void parseSubclass() { 21 | ParseRegistry.registerSubclass(Person.class); 22 | } 23 | 24 | @Test 25 | public void save() { 26 | System.out.println("save(): initializing..."); 27 | ParseRegistry.registerSubclass(Person.class); 28 | Person parseObject = new Person(); 29 | parseObject.setAge(15); 30 | parseObject.setGender("male"); 31 | parseObject.getString("age"); 32 | 33 | try { 34 | parseObject.save(); 35 | System.out.println("save(): objectId: " + parseObject.getObjectId()); 36 | System.out.println("save(): createdAt: " + parseObject.getCreatedAt()); 37 | System.out.println("save(): updatedAt: " + parseObject.getUpdatedAt()); 38 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 39 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 40 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 41 | } 42 | catch(ParseException pe) { 43 | assertNull("save(): should not have thrown ParseException", pe); 44 | } 45 | } 46 | 47 | @Test 48 | public void get() { 49 | System.out.println("get(): initializing..."); 50 | ParseRegistry.registerSubclass(Person.class); 51 | Person parseObject = new Person(); 52 | parseObject.setAge(31); 53 | parseObject.setGender("female"); 54 | 55 | try { 56 | parseObject.save(); 57 | 58 | ParseQuery query = ParseQuery.getQuery(Person.class); 59 | Person person = query.get(parseObject.getObjectId()); 60 | System.out.println("get(): objectId - " + person.getObjectId() + "-" + parseObject.getObjectId()); 61 | System.out.println("get(): gender - " + person.getGender() + "-" + parseObject.getGender()); 62 | System.out.println("get(): ages - " + person.getAge() + "-" + parseObject.getAge()); 63 | assertFalse("get(): ObjectIds should be the same", !parseObject.getObjectId().equals(person.getObjectId())); 64 | assertFalse("get(): Ages should be the same", parseObject.getAge() != person.getAge()); 65 | assertFalse("get(): Genders should be the same", !parseObject.getGender().equals(person.getGender())); 66 | } 67 | catch(ParseException pe) { 68 | assertNull("save(): should not have thrown ParseException", pe); 69 | } 70 | } 71 | 72 | @Test 73 | public void saveWithChar() { 74 | System.out.println("save(): initializing..."); 75 | ParseRegistry.registerSubclass(Person.class); 76 | Person parseObject = new Person(); 77 | parseObject.setAge(15); 78 | parseObject.setGender("Suíça"); 79 | parseObject.getString("age"); 80 | 81 | try { 82 | parseObject.save(); 83 | System.out.println("save(): objectId: " + parseObject.getObjectId()); 84 | System.out.println("save(): createdAt: " + parseObject.getCreatedAt()); 85 | System.out.println("save(): updatedAt: " + parseObject.getUpdatedAt()); 86 | assertNotNull("objectId should not be null", parseObject.getObjectId()); 87 | assertNotNull("createdAt should not be null", parseObject.getCreatedAt()); 88 | assertNotNull("updatedAt should not be null", parseObject.getUpdatedAt()); 89 | } 90 | catch(ParseException pe) { 91 | assertNull("save(): should not have thrown ParseException", pe); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseObjectOperationsTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | 6 | import org.junit.Test; 7 | import org.parse4j.util.MimeType; 8 | 9 | public class ParseObjectOperationsTestCase extends Parse4JTestCase { 10 | 11 | @Test(expected = IllegalArgumentException.class ) 12 | public void putNullKey() { 13 | System.out.println("putNullKey(): initializing..."); 14 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 15 | parseObject.put(null, "parse developer"); 16 | } 17 | 18 | @Test(expected = IllegalArgumentException.class ) 19 | public void putNullValue() { 20 | System.out.println("putNullValue(): initializing..."); 21 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 22 | parseObject.put("name", null); 23 | } 24 | 25 | @Test(expected = IllegalArgumentException.class) 26 | public void incrementString() { 27 | System.out.println("incrementString(): initializing..."); 28 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 29 | parseObject.put("field", "value"); 30 | parseObject.increment("field"); 31 | } 32 | 33 | @Test(expected = IllegalArgumentException.class) 34 | public void decrementString() { 35 | System.out.println("decrementString(): initializing..."); 36 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 37 | parseObject.put("field", "value"); 38 | parseObject.decrement("field"); 39 | } 40 | 41 | @Test 42 | public void incrementNumbers() { 43 | System.out.println("incrementNumbers(): initializing..."); 44 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 45 | parseObject.put("field1", 1); 46 | parseObject.increment("field1"); 47 | parseObject.put("field2", 2L); 48 | parseObject.increment("field2"); 49 | parseObject.put("field3", 3.3); 50 | parseObject.increment("field3"); 51 | } 52 | 53 | @Test(expected = IllegalArgumentException.class) 54 | public void invalidPutKey1() { 55 | System.out.println("invalidPutKey1(): initializing..."); 56 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 57 | parseObject.put("objectId", "value"); 58 | } 59 | 60 | @Test(expected = IllegalArgumentException.class) 61 | public void invalidPutKey2() { 62 | System.out.println("invalidPutKey2(): initializing..."); 63 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 64 | parseObject.put("createdAt", "value"); 65 | } 66 | 67 | @Test(expected = IllegalArgumentException.class) 68 | public void invalidPutKey3() { 69 | System.out.println("invalidPutKey3(): initializing..."); 70 | ParseObject parseObject = getEmptyParseObject(CLASS_NAME); 71 | parseObject.put("updatedAt", "value"); 72 | } 73 | 74 | @Test 75 | public void extension() { 76 | System.out.println("extension(): initializing..."); 77 | 78 | for(String extension : MimeType.mimeTypes.keySet()) { 79 | String fileName = "test." + extension; 80 | //System.out.println("File name:" + fileName); 81 | assertEquals("Expected " + MimeType.getFileExtension(fileName), MimeType.getFileExtension(fileName), extension); 82 | } 83 | 84 | String fileName = "test"; 85 | //System.out.println("File name:" + fileName); 86 | assertEquals("Expected " + MimeType.getFileExtension(fileName), MimeType.getFileExtension(fileName), ""); 87 | } 88 | 89 | @Test 90 | public void extensionNotEqual() { 91 | System.out.println("extensionNotEqual(): initializing..."); 92 | 93 | for(String extension : MimeType.mimeTypes.keySet()) { 94 | String fileName = "test." + extension; 95 | //System.out.println("File name:" + fileName + ", testing against: " + (extension+"x")); 96 | boolean result = (extension+"x").equals(MimeType.getFileExtension(fileName)); 97 | assertFalse(result); 98 | } 99 | } 100 | 101 | @Test 102 | public void mimeType() { 103 | System.out.println("mimeType(): initializing..."); 104 | 105 | for(String extension : MimeType.mimeTypes.keySet()) { 106 | String fileName = "test." + extension; 107 | //System.out.print("File name:" + fileName); 108 | String mime = MimeType.getMimeType(MimeType.getFileExtension(fileName)); 109 | //System.out.println(", content-type: " + mime); 110 | assertEquals("Expected " + MimeType.getMimeType(extension), MimeType.getMimeType(extension), mime); 111 | } 112 | 113 | String fileName = "test"; 114 | //System.out.print("File name:" + fileName); 115 | String mime = MimeType.getMimeType(MimeType.getFileExtension(fileName)); 116 | String extension = MimeType.getFileExtension(fileName); 117 | //System.out.println(", content-type: " + mime); 118 | assertEquals("Expected " + MimeType.getMimeType(extension), MimeType.getMimeType(extension), mime); 119 | 120 | } 121 | 122 | @Test(expected = IllegalArgumentException.class) 123 | public void testFileNotSave() { 124 | System.out.println("testFileNotSave(): initializing..."); 125 | try { 126 | byte[] data = getBytes("/parse.png"); 127 | ParseFile file = new ParseFile("parse.png", data); 128 | ParseObject po = getParseObject(CLASS_NAME); 129 | po.put("logo", file); 130 | } 131 | catch(ParseException pe) { 132 | 133 | } 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseQueryTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertNotNull; 5 | import static org.junit.Assert.assertNull; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | import org.junit.Test; 11 | import org.parse4j.callback.CountCallback; 12 | import org.parse4j.callback.FindCallback; 13 | import org.parse4j.callback.GetCallback; 14 | 15 | public class ParseQueryTestCase extends Parse4JTestCase { 16 | 17 | 18 | @Test 19 | public void query1() { 20 | ParseQuery query = ParseQuery.getQuery("games"); 21 | String[] names = {"Jonathan Walsh", "Dario Wunsch", "Shawn Simon"}; 22 | query.addAscendingOrder("loosingScore") 23 | .addDescendingOrder("score2") 24 | .whereGreaterThan("score1", 6) 25 | .whereLessThanOrEqualTo("score2", 2) 26 | .whereContainedIn("playerName", Arrays.asList(names));; 27 | query.limit(10); 28 | query.skip(10); 29 | System.out.println(query.toREST()); 30 | } 31 | 32 | @Test 33 | public void test1() { 34 | System.out.println("test1(): initializing..."); 35 | 36 | try { 37 | ParseQuery query = ParseQuery.getQuery("games"); 38 | ParseObject po = query.get("GLVPuc2X8H"); 39 | assertNotNull("ObjectId should not be null", po.getObjectId()); 40 | } 41 | catch(ParseException e) { 42 | assertNull("test1(): should not have thrown ParseException", e); 43 | } 44 | 45 | } 46 | 47 | @Test 48 | public void test12() { 49 | System.out.println("test12(): initializing..."); 50 | 51 | ParseQuery query = ParseQuery.getQuery("games"); 52 | query.getInBackground("GLVPuc2X8H", new GetCallback() { 53 | 54 | @Override 55 | public void done(ParseObject t, ParseException parseException) { 56 | assertNotNull("ObjectId should not be null", t); 57 | assertNull("test12(): should not have thrown ParseException", parseException); 58 | } 59 | }); 60 | sleep(1000); 61 | } 62 | 63 | @Test 64 | public void test13() { 65 | System.out.println("test13(): initializing..."); 66 | 67 | ParseQuery query = ParseQuery.getQuery("games"); 68 | query.getInBackground("NOT_FOUND", new GetCallback() { 69 | 70 | @Override 71 | public void done(ParseObject t, ParseException parseException) { 72 | assertNull("ObjectId should be null", t); 73 | assertNull("test13(): should not have been trown", parseException); 74 | } 75 | }); 76 | sleep(1000); 77 | } 78 | 79 | @Test 80 | public void test2() { 81 | System.out.println("test2(): initializing..."); 82 | 83 | try { 84 | ParseQuery query = ParseQuery.getQuery("games"); 85 | query.whereGreaterThan("losingScore", 140); 86 | List po = query.find(); 87 | assertFalse("There should be 15 items on the list", po.size() != 15); 88 | } 89 | catch(ParseException e) { 90 | assertNull("test2(): should not have thrown ParseException", e); 91 | } 92 | 93 | } 94 | 95 | @Test 96 | public void test21() { 97 | System.out.println("test21(): initializing..."); 98 | 99 | ParseQuery query = ParseQuery.getQuery("games"); 100 | query.whereGreaterThan("losingScore", 140); 101 | query.findInBackground(new FindCallback() { 102 | 103 | @Override 104 | public void done(List list, ParseException parseException) { 105 | assertFalse("test21(): There should be 15 items on the list", list.size() != 15); 106 | assertNull("test21(): should not have thrown ParseException", parseException); 107 | 108 | } 109 | }); 110 | 111 | sleep(1000); 112 | } 113 | 114 | @Test 115 | public void test22() { 116 | System.out.println("test21(): initializing..."); 117 | 118 | ParseQuery query = ParseQuery.getQuery("games"); 119 | query.whereGreaterThan("losingScore", 140); 120 | query.skip(4); 121 | query.findInBackground(new FindCallback() { 122 | 123 | @Override 124 | public void done(List list, ParseException parseException) { 125 | assertFalse("test21(): There should be 15 items on the list", list.size() != 11); 126 | assertNull("test21(): should not have thrown ParseException", parseException); 127 | 128 | } 129 | }); 130 | 131 | sleep(1000); 132 | } 133 | 134 | @Test 135 | public void test23() { 136 | System.out.println("test21(): initializing..."); 137 | 138 | ParseQuery query = ParseQuery.getQuery("games"); 139 | query.whereGreaterThan("losingScore", 140); 140 | query.limit(7); 141 | query.findInBackground(new FindCallback() { 142 | 143 | @Override 144 | public void done(List list, ParseException parseException) { 145 | assertFalse("test21(): There should be 15 items on the list", list.size() != 7); 146 | assertNull("test21(): should not have thrown ParseException", parseException); 147 | 148 | } 149 | }); 150 | 151 | sleep(1000); 152 | } 153 | 154 | @Test 155 | public void test3() { 156 | System.out.println("test3(): initializing..."); 157 | 158 | try { 159 | ParseQuery query = ParseQuery.getQuery("games"); 160 | query.whereGreaterThan("losingScore", 140) 161 | .whereLessThan("winningScore", 150) 162 | .whereStartsWith("losingTeam", "Denver"); 163 | List po = query.find(); 164 | assertFalse("There should be 3 items on the list", po.size() != 3); 165 | } 166 | catch(ParseException e) { 167 | assertNull("test3(): should not have thrown ParseException", e); 168 | } 169 | 170 | } 171 | 172 | @Test 173 | public void test31() { 174 | System.out.println("test31(): initializing..."); 175 | 176 | ParseQuery query = ParseQuery.getQuery("games"); 177 | query.whereGreaterThan("losingScore", 140) 178 | .whereLessThan("winningScore", 150) 179 | .whereStartsWith("losingTeam", "Denver"); 180 | query.findInBackground(new FindCallback() { 181 | 182 | @Override 183 | public void done(List list, ParseException parseException) { 184 | assertFalse("test31(): There shoult be 3 items on the list", list.size() != 3); 185 | assertNull("test31(): should not have thrown ParseException", parseException); 186 | 187 | } 188 | }); 189 | 190 | sleep(1000); 191 | } 192 | 193 | @Test 194 | public void test4() { 195 | System.out.println("test4(): initializing..."); 196 | 197 | try { 198 | ParseQuery query = ParseQuery.getQuery("games"); 199 | query.whereGreaterThan("losingScore", 140); 200 | int total = query.count(); 201 | assertFalse("There should be 15 items on the list", total != 15); 202 | } 203 | catch(ParseException e) { 204 | assertNull("test4(): should not have thrown ParseException", e); 205 | } 206 | 207 | } 208 | 209 | @Test 210 | public void test41() { 211 | System.out.println("test41(): initializing..."); 212 | 213 | ParseQuery query = ParseQuery.getQuery("games"); 214 | query.whereGreaterThan("losingScore", 140); 215 | query.countInBackground(new CountCallback() { 216 | 217 | @Override 218 | public void done(Integer count, ParseException parseException) { 219 | assertFalse("test41(): There should be 15 items on the list", count != 15); 220 | assertNull("test41(): should not have thrown ParseException", parseException); 221 | 222 | } 223 | }); 224 | 225 | sleep(1000); 226 | } 227 | 228 | @Test 229 | public void test5() { 230 | //selectKeys 231 | System.out.println("test5(): initializing..."); 232 | 233 | try { 234 | ParseQuery query = ParseQuery.getQuery("games"); 235 | query.selectKeys(Arrays.asList("losingTeam", "losingScore")); 236 | query.setTrace(true); 237 | ParseObject po = query.get("GLVPuc2X8H"); 238 | assertNotNull("test5(): ObjectId should not be null", po.getObjectId()); 239 | } 240 | catch(ParseException e) { 241 | assertNull("test5(): should not have thrown ParseException", e); 242 | } 243 | } 244 | 245 | @Test 246 | public void test6() { 247 | System.out.println("test6(): initializing..."); 248 | 249 | try { 250 | ParseQuery query = ParseQuery.getQuery("games"); 251 | ParseObject po = query.get("GLVPuc2X8H"); 252 | //po.increment("losingScore", -3); 253 | //po.remove("data"); 254 | //po.save(); 255 | assertNotNull("test6(): ObjectId should not be null", po.getObjectId()); 256 | } 257 | catch(ParseException e) { 258 | assertNull("test6(): should not have thrown ParseException", e); 259 | } 260 | 261 | } 262 | 263 | } 264 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseRelationTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import static org.junit.Assert.assertNotNull; 4 | import static org.junit.Assert.assertNull; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | import org.junit.Test; 12 | import org.parse4j.callback.GetCallback; 13 | 14 | public class ParseRelationTestCase extends Parse4JTestCase { 15 | 16 | 17 | @Test 18 | public void test1() throws ParseException { 19 | 20 | for(int i = 1; i < 21; i++) { 21 | 22 | // Create the post 23 | ParseObject myPost = new ParseObject("Post"); 24 | myPost.put("title", "Post Number " + i); 25 | myPost.put("content", "Content for Post " + 1); 26 | myPost.save(); 27 | 28 | // Create the comment 29 | ParseObject myComment = new ParseObject("Comment"); 30 | myComment.put("content", "Content for Post" + i); 31 | myComment.put("parent", myPost); 32 | myComment.save(); 33 | 34 | ParseQuery query = ParseQuery.getQuery("Comment"); 35 | ParseObject fetchedComment = query.get(myComment.getObjectId()); 36 | 37 | ParseObject postObj = fetchedComment.getParseObject("parent"); 38 | postObj.fetchIfNeeded(new GetCallback() { 39 | public void done(ParseObject post, ParseException e) { 40 | String title = post.getString("title"); 41 | assertNull("title should not be null", title); 42 | } 43 | }); 44 | 45 | //myComment.remove("parent"); 46 | //myComment.save(); 47 | //postObj.delete(); 48 | //myComment.delete(); 49 | } 50 | 51 | } 52 | 53 | @Test 54 | public void list() throws ParseException { 55 | ParseQuery query = ParseQuery.getQuery("Comment"); 56 | List list = query.find(); 57 | for(ParseObject po : list) { 58 | System.out.println(po.getObjectId()); 59 | po.remove("parent"); 60 | po.save(); 61 | } 62 | } 63 | 64 | 65 | 66 | @Test 67 | public void relation4() throws ParseException { 68 | ParseQuery query = ParseQuery.getQuery("Post"); 69 | query.whereEqualTo("title", "Post Number 20"); 70 | 71 | ParseQuery commentsQuery = ParseQuery.getQuery("Comment"); 72 | commentsQuery.whereMatchesQuery("parent", query); 73 | List find = commentsQuery.find(); 74 | 75 | assertNotNull(find); 76 | assertTrue(find.size()>1); 77 | } 78 | @Test 79 | public void relation() throws ParseException { 80 | 81 | ParseObject member = new ParseObject("Member"); 82 | member.put("name", "member name"); 83 | member.put("country", "brazil"); 84 | member.save(); 85 | 86 | ParseObject project1 = new ParseObject("Project"); 87 | project1.put("name", "project name 1"); 88 | project1.put("start", new Date()); 89 | project1.save(); 90 | 91 | ParseObject project2 = new ParseObject("Project"); 92 | project2.put("name", "project name 2"); 93 | project2.put("start", new Date()); 94 | project2.save(); 95 | 96 | ParseRelation relation = member.getRelation("projects"); 97 | relation.add(project1); 98 | relation.add(project2); 99 | member.save(); 100 | 101 | ParseQuery query = ParseQuery.getQuery("Member"); 102 | ParseObject fetchedMember = query.get(member.getObjectId()); 103 | 104 | ParseRelation fetchedRelations = member.getRelation("projects"); 105 | ParseQuery fetchQuery = fetchedRelations.getQuery(); 106 | List list = fetchQuery.find(); 107 | 108 | } 109 | 110 | @Test 111 | public void relation3() throws ParseException { 112 | 113 | ParseQuery query = ParseQuery.getQuery("Member"); 114 | ParseObject member = query.get("8EOuUQSV38"); 115 | 116 | ParseRelation fetchedRelations = member.getRelation("projects"); 117 | ParseQuery fetchQuery = fetchedRelations.getQuery(); 118 | List list = fetchQuery.find(); 119 | for(ParseObject po : list) { 120 | System.out.println(po.getDate("start")); 121 | } 122 | } 123 | 124 | @Test 125 | public void relation2() throws ParseException { 126 | 127 | ParseObject member = new ParseObject("GameScore"); 128 | member.put("date", new Date()); 129 | member.put("local", "usa"); 130 | member.save(); 131 | 132 | ParseObject project1 = new ParseObject("Team"); 133 | project1.put("name", "Team C"); 134 | project1.save(); 135 | 136 | ParseObject project2 = new ParseObject("Team"); 137 | project2.put("name", "Team D"); 138 | project2.save(); 139 | 140 | ParseRelation relation = member.getRelation("opponents"); 141 | relation.add(project1); 142 | //relation.add(project2); 143 | member.save(); 144 | 145 | ParseQuery query = ParseQuery.getQuery("GameScore"); 146 | ParseObject fetchedMember = query.get(member.getObjectId()); 147 | 148 | ParseRelation fetchedRelations = member.getRelation("opponents"); 149 | } 150 | 151 | 152 | @Test 153 | public void arrayParseObject() { 154 | 155 | // let's say we have four weapons 156 | ParseObject scimitar = new ParseObject("weapon"); 157 | scimitar.put("name", "scimitar"); 158 | ParseObject plasmaRifle = new ParseObject("weapon"); 159 | plasmaRifle.put("name", "plasmaRifle"); 160 | ParseObject grenade = new ParseObject("weapon"); 161 | grenade.put("name", "grenade"); 162 | ParseObject bunnyRabbit = new ParseObject("weapon"); 163 | bunnyRabbit.put("name", "bunnyRabbit"); 164 | 165 | // stick the objects in an array 166 | ArrayList weapons = new ArrayList(); 167 | weapons.add(scimitar); 168 | weapons.add(plasmaRifle); 169 | weapons.add(grenade); 170 | weapons.add(bunnyRabbit); 171 | 172 | ParseObject soldier = new ParseObject("soldier"); 173 | soldier.put("name", "soldier"); 174 | 175 | 176 | } 177 | 178 | @Test 179 | public void arrayStrings() throws ParseException { 180 | 181 | // stick the objects in an array 182 | ArrayList weapons = new ArrayList(); 183 | weapons.add("scimitar"); 184 | weapons.add("plasmaRifle"); 185 | weapons.add("grenade"); 186 | weapons.add("bunnyRabbit"); 187 | 188 | ParseObject soldier = new ParseObject("soldier"); 189 | soldier.put("name", "soldier"); 190 | soldier.put("weapons", weapons); 191 | soldier.save(); 192 | 193 | ParseQuery query = ParseQuery.getQuery("soldier"); 194 | ParseObject fetchedSoldier = query.get(soldier.getObjectId()); 195 | System.out.println(fetchedSoldier.getList("weapons")); 196 | 197 | } 198 | 199 | } 200 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/ParseUserTestCase.java: -------------------------------------------------------------------------------- 1 | package org.parse4j; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.UUID; 6 | 7 | import static org.hamcrest.CoreMatchers.is; 8 | import static org.hamcrest.CoreMatchers.notNullValue; 9 | import static org.junit.Assert.*; 10 | 11 | public class ParseUserTestCase extends Parse4JTestCase { 12 | 13 | @Test(expected = IllegalArgumentException.class) 14 | public void signupNoUsername() { 15 | System.out.println("signupNoUsername(): initializing..."); 16 | 17 | ParseUser parseUser = new ParseUser(); 18 | try { 19 | parseUser.signUp(); 20 | } catch (ParseException e) { 21 | assertNull("ParseException should be null", e); 22 | } 23 | 24 | } 25 | 26 | @Test(expected = IllegalArgumentException.class) 27 | public void signupNoPassword() { 28 | System.out.println("signupNoPassword(): initializing..."); 29 | 30 | ParseUser parseUser = new ParseUser(); 31 | try { 32 | parseUser.setUsername("parse4j-user"); 33 | parseUser.signUp(); 34 | } catch (ParseException e) { 35 | assertNull("ParseException should be null", e); 36 | } 37 | 38 | } 39 | 40 | @Test(expected = IllegalArgumentException.class) 41 | public void signupWithObjectId() { 42 | System.out.println("signupWithObjectId(): initializing..."); 43 | 44 | ParseUser parseUser = new ParseUser(); 45 | try { 46 | parseUser.setUsername("parse4j-user"); 47 | parseUser.setPassword("parse4j-password"); 48 | parseUser.setObjectId("tempObjectId"); 49 | parseUser.signUp(); 50 | } catch (ParseException e) { 51 | assertNull("ParseException should be null", e); 52 | } 53 | 54 | } 55 | 56 | @Test public void 57 | sign_up_and_delete_an_user() throws ParseException { 58 | final String number = UUID.randomUUID().toString(); 59 | ParseUser parseUser = getParseUser(number); 60 | parseUser.signUp(); 61 | assertThat(parseUser.getObjectId(), is(notNullValue())); 62 | assertThat(parseUser.getSessionToken(), is(notNullValue())); 63 | assertThat(parseUser.getSessionToken(), is(notNullValue())); 64 | 65 | parseUser.delete(); 66 | } 67 | 68 | @Test(expected = ParseException.class) 69 | public void signupExistingUsername() throws ParseException { 70 | System.out.println("signupExistingUsername(): initializing..."); 71 | 72 | ParseUser parseUser = getParseUser("2"); 73 | parseUser.signUp(); 74 | 75 | parseUser = getParseUser("2"); 76 | parseUser.signUp(); 77 | 78 | assertNotNull("objectId should not be null", parseUser.getObjectId()); 79 | assertNotNull("createdAt should not be null", parseUser.getCreatedAt()); 80 | assertNotNull("sessionToken should not be null", parseUser.getSessionToken()); 81 | } 82 | 83 | @Test public void 84 | login() throws ParseException { 85 | final String number = UUID.randomUUID().toString(); 86 | ParseUser pu = getParseUser(number); 87 | pu.signUp(); 88 | 89 | ParseUser parseUser = ParseUser.login(pu.getUsername(), "parse4j-password"); 90 | 91 | assertThat(parseUser.getString("city"), is("westbury")); 92 | assertThat(parseUser.getString("state"), is("ny")); 93 | 94 | assertThat(parseUser.getObjectId(), is(notNullValue())); 95 | assertThat(parseUser.getSessionToken(), is(notNullValue())); 96 | assertThat(parseUser.getSessionToken(), is(notNullValue())); 97 | 98 | pu.delete(); 99 | } 100 | 101 | @Test public void 102 | verify_email() throws ParseException { 103 | final String number = UUID.randomUUID().toString(); 104 | ParseUser parseUser = getParseUser(number); 105 | parseUser.signUp(); 106 | 107 | ParseUser.requestPasswordReset(parseUser.getEmail()); 108 | 109 | parseUser.delete(); 110 | } 111 | 112 | @Test(expected = ParseException.class) 113 | public void verifyInvalidEmail() throws ParseException { 114 | System.out.println("verifyEmail(): initializing..."); 115 | 116 | try { 117 | ParseUser.requestPasswordReset("invalid@gamil.com"); 118 | } catch (ParseException e) { 119 | throw e; 120 | } 121 | 122 | } 123 | 124 | 125 | } 126 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/bolts/TestBolts.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.bolts; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.util.List; 7 | import java.util.concurrent.Callable; 8 | 9 | import org.junit.Test; 10 | import org.parse4j.Parse4JTestCase; 11 | import org.parse4j.ParseObject; 12 | import org.parse4j.ParseQuery; 13 | 14 | public class TestBolts extends Parse4JTestCase { 15 | 16 | @Test 17 | public void testBackgroundCallWaiting() throws Exception { 18 | 19 | Task> task = Task.callInBackground(new Callable>() { 20 | 21 | @Override 22 | public List call() throws Exception { 23 | ParseQuery query = ParseQuery.getQuery("games"); 24 | query.whereGreaterThan("losingScore", 140); 25 | query.skip(4); 26 | System.out.println("before running"); 27 | return query.find(); 28 | } 29 | 30 | }); 31 | 32 | //task.waitForCompletion(); 33 | assertTrue(task.isCompleted()); 34 | assertEquals(11, task.getResult().size()); 35 | System.out.println("finish"); 36 | } 37 | 38 | @Test 39 | public void testForResult() throws Exception { 40 | ParseQuery query = ParseQuery.getQuery("games"); 41 | query.whereGreaterThan("losingScore", 140); 42 | query.skip(4); 43 | Task> task = Task.forResult(query.find()); 44 | 45 | //task.waitForCompletion(); 46 | assertTrue(task.isCompleted()); 47 | assertEquals(11, task.getResult().size()); 48 | } 49 | 50 | 51 | @Test 52 | public void testContinuationWith() throws InterruptedException { 53 | 54 | 55 | Task> task = Task.callInBackground(new Callable>() { 56 | 57 | @Override 58 | public List call() throws Exception { 59 | ParseQuery query = ParseQuery.getQuery("games"); 60 | query.whereGreaterThan("losingScore", 140); 61 | query.skip(4); 62 | return query.find(); 63 | } 64 | 65 | }).continueWith(new Continuation, List>() { 66 | 67 | @Override 68 | public List then(Task> task) throws Exception { 69 | System.out.println("completed"); 70 | return null; 71 | } 72 | 73 | }).onSuccess(new Continuation, List>() { 74 | 75 | @Override 76 | public List then(Task> task) throws Exception { 77 | System.out.println("onSucess 1"); 78 | return null; 79 | } 80 | 81 | }).onSuccess(new Continuation, List>() { 82 | 83 | @Override 84 | public List then(Task> task) throws Exception { 85 | System.out.println("onSucess 2"); 86 | return null; 87 | } 88 | 89 | }).onSuccess(new Continuation, List>() { 90 | 91 | @Override 92 | public List then(Task> task) throws Exception { 93 | System.out.println("onSucess 3"); 94 | return null; 95 | } 96 | 97 | }); 98 | 99 | task.waitForCompletion(); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/bolts/TestTask.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.bolts; 2 | 3 | import java.util.ArrayList; 4 | import java.util.concurrent.Callable; 5 | import java.util.concurrent.CancellationException; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.atomic.AtomicInteger; 8 | 9 | import junit.framework.TestCase; 10 | 11 | public class TestTask extends TestCase { 12 | 13 | private void runTaskTest(Callable> callable) { 14 | try { 15 | Task task = callable.call(); 16 | task.waitForCompletion(); 17 | if (task.isFaulted()) { 18 | Exception error = task.getError(); 19 | if (error instanceof RuntimeException) { 20 | throw (RuntimeException) error; 21 | } 22 | throw new RuntimeException(error); 23 | } else if (task.isCancelled()) { 24 | throw new RuntimeException(new CancellationException()); 25 | } 26 | } catch (Exception e) { 27 | throw new RuntimeException(e); 28 | } 29 | } 30 | 31 | public void testPrimitives() { 32 | Task complete = Task.forResult(5); 33 | Task error = Task.forError(new RuntimeException()); 34 | Task cancelled = Task.cancelled(); 35 | 36 | assertTrue(complete.isCompleted()); 37 | assertEquals(5, complete.getResult().intValue()); 38 | assertFalse(complete.isFaulted()); 39 | assertFalse(complete.isCancelled()); 40 | 41 | assertTrue(error.isCompleted()); 42 | assertTrue(error.getError() instanceof RuntimeException); 43 | assertTrue(error.isFaulted()); 44 | assertFalse(error.isCancelled()); 45 | 46 | assertTrue(cancelled.isCompleted()); 47 | assertFalse(cancelled.isFaulted()); 48 | assertTrue(cancelled.isCancelled()); 49 | } 50 | 51 | public void testSynchronousContinuation() { 52 | 53 | final Task complete = Task.forResult(5); 54 | final Task error = Task.forError(new RuntimeException()); 55 | final Task cancelled = Task.cancelled(); 56 | 57 | complete.continueWith(new Continuation() { 58 | public Void then(Task task) { 59 | assertEquals(complete, task); 60 | assertTrue(task.isCompleted()); 61 | assertEquals(5, task.getResult().intValue()); 62 | assertFalse(task.isFaulted()); 63 | assertFalse(task.isCancelled()); 64 | return null; 65 | } 66 | }); 67 | 68 | error.continueWith(new Continuation() { 69 | public Void then(Task task) { 70 | assertEquals(error, task); 71 | assertTrue(task.isCompleted()); 72 | assertTrue(task.getError() instanceof RuntimeException); 73 | assertTrue(task.isFaulted()); 74 | assertFalse(task.isCancelled()); 75 | return null; 76 | } 77 | }); 78 | 79 | cancelled.continueWith(new Continuation() { 80 | public Void then(Task task) { 81 | assertEquals(cancelled, task); 82 | assertTrue(cancelled.isCompleted()); 83 | assertFalse(cancelled.isFaulted()); 84 | assertTrue(cancelled.isCancelled()); 85 | return null; 86 | } 87 | }); 88 | } 89 | 90 | public void testSynchronousChaining() { 91 | Task first = Task.forResult(1); 92 | Task second = first 93 | .continueWith(new Continuation() { 94 | public Integer then(Task task) { 95 | return 2; 96 | } 97 | }); 98 | Task third = second 99 | .continueWithTask(new Continuation>() { 100 | public Task then(Task task) { 101 | return Task.forResult(3); 102 | } 103 | }); 104 | assertTrue(first.isCompleted()); 105 | assertTrue(second.isCompleted()); 106 | assertTrue(third.isCompleted()); 107 | assertEquals(1, first.getResult().intValue()); 108 | assertEquals(2, second.getResult().intValue()); 109 | assertEquals(3, third.getResult().intValue()); 110 | } 111 | 112 | public void testBackgroundCall() { 113 | runTaskTest(new Callable>() { 114 | public Task call() throws Exception { 115 | return Task.callInBackground(new Callable() { 116 | public Integer call() throws Exception { 117 | Thread.sleep(100); 118 | return 5; 119 | } 120 | }).continueWith(new Continuation() { 121 | public Void then(Task task) { 122 | assertEquals(5, task.getResult().intValue()); 123 | return null; 124 | } 125 | }); 126 | } 127 | }); 128 | } 129 | 130 | public void testBackgroundCallWaiting() throws Exception { 131 | Task task = Task.callInBackground(new Callable() { 132 | public Integer call() throws Exception { 133 | Thread.sleep(100); 134 | return 5; 135 | } 136 | }); 137 | task.waitForCompletion(); 138 | assertTrue(task.isCompleted()); 139 | assertEquals(5, task.getResult().intValue()); 140 | } 141 | 142 | public void testBackgroundCallWaitingOnError() throws Exception { 143 | Task task = Task.callInBackground(new Callable() { 144 | public Integer call() throws Exception { 145 | Thread.sleep(100); 146 | throw new RuntimeException(); 147 | } 148 | }); 149 | task.waitForCompletion(); 150 | assertTrue(task.isCompleted()); 151 | assertTrue(task.isFaulted()); 152 | } 153 | 154 | public void testBackgroundCallWaitOnCancellation() throws Exception { 155 | Task task = Task.callInBackground(new Callable() { 156 | public Integer call() throws Exception { 157 | Thread.sleep(100); 158 | return 5; 159 | } 160 | }).continueWithTask(new Continuation>() { 161 | 162 | public Task then(Task task) { 163 | return Task.cancelled(); 164 | } 165 | }); 166 | task.waitForCompletion(); 167 | assertTrue(task.isCompleted()); 168 | assertTrue(task.isCancelled()); 169 | } 170 | 171 | public void testBackgroundError() { 172 | runTaskTest(new Callable>() { 173 | public Task call() throws Exception { 174 | return Task.callInBackground(new Callable() { 175 | public Integer call() throws Exception { 176 | throw new IllegalStateException(); 177 | } 178 | }).continueWith(new Continuation() { 179 | public Void then(Task task) { 180 | assertTrue(task.isFaulted()); 181 | assertTrue(task.getError() instanceof IllegalStateException); 182 | return null; 183 | } 184 | }); 185 | } 186 | }); 187 | } 188 | 189 | public void testWhenAllSuccess() { 190 | runTaskTest(new Callable>() { 191 | @Override 192 | public Task call() throws Exception { 193 | final ArrayList> tasks = new ArrayList>(); 194 | for (int i = 0; i < 20; i++) { 195 | Task task = Task 196 | .callInBackground(new Callable() { 197 | @Override 198 | public Void call() throws Exception { 199 | Thread.sleep((long) (Math.random() * 1000)); 200 | return null; 201 | } 202 | }); 203 | tasks.add(task); 204 | } 205 | return Task.whenAll(tasks).continueWith( 206 | new Continuation() { 207 | @Override 208 | public Void then(Task task) { 209 | assertTrue(task.isCompleted()); 210 | assertFalse(task.isFaulted()); 211 | assertFalse(task.isCancelled()); 212 | 213 | for (Task t : tasks) { 214 | assertTrue(t.isCompleted()); 215 | } 216 | return null; 217 | } 218 | }); 219 | } 220 | }); 221 | } 222 | 223 | public void testWhenAllOneError() { 224 | final Exception error = new RuntimeException("This task failed."); 225 | 226 | runTaskTest(new Callable>() { 227 | @Override 228 | public Task call() throws Exception { 229 | final ArrayList> tasks = new ArrayList>(); 230 | for (int i = 0; i < 20; i++) { 231 | final int number = i; 232 | Task task = Task 233 | .callInBackground(new Callable() { 234 | @Override 235 | public Void call() throws Exception { 236 | Thread.sleep((long) (Math.random() * 1000)); 237 | if (number == 10) { 238 | throw error; 239 | } 240 | return null; 241 | } 242 | }); 243 | tasks.add(task); 244 | } 245 | return Task.whenAll(tasks).continueWith( 246 | new Continuation() { 247 | @Override 248 | public Void then(Task task) { 249 | assertTrue(task.isCompleted()); 250 | assertTrue(task.isFaulted()); 251 | assertFalse(task.isCancelled()); 252 | 253 | assertFalse(task.getError() instanceof AggregateException); 254 | assertEquals(error, task.getError()); 255 | 256 | for (Task t : tasks) { 257 | assertTrue(t.isCompleted()); 258 | } 259 | return null; 260 | } 261 | }); 262 | } 263 | }); 264 | } 265 | 266 | public void testWhenAllTwoErrors() { 267 | final Exception error = new RuntimeException("This task failed."); 268 | 269 | runTaskTest(new Callable>() { 270 | @Override 271 | public Task call() throws Exception { 272 | final ArrayList> tasks = new ArrayList>(); 273 | for (int i = 0; i < 20; i++) { 274 | final int number = i; 275 | Task task = Task 276 | .callInBackground(new Callable() { 277 | @Override 278 | public Void call() throws Exception { 279 | Thread.sleep((long) (Math.random() * 1000)); 280 | if (number == 10 || number == 11) { 281 | throw error; 282 | } 283 | return null; 284 | } 285 | }); 286 | tasks.add(task); 287 | } 288 | return Task.whenAll(tasks).continueWith( 289 | new Continuation() { 290 | @Override 291 | public Void then(Task task) { 292 | assertTrue(task.isCompleted()); 293 | assertTrue(task.isFaulted()); 294 | assertFalse(task.isCancelled()); 295 | 296 | assertTrue(task.getError() instanceof AggregateException); 297 | assertEquals(2, ((AggregateException) task 298 | .getError()).getErrors().size()); 299 | assertEquals(error, ((AggregateException) task 300 | .getError()).getErrors().get(0)); 301 | assertEquals(error, ((AggregateException) task 302 | .getError()).getErrors().get(1)); 303 | 304 | for (Task t : tasks) { 305 | assertTrue(t.isCompleted()); 306 | } 307 | return null; 308 | } 309 | }); 310 | } 311 | }); 312 | } 313 | 314 | public void testWhenAllCancel() { 315 | runTaskTest(new Callable>() { 316 | @Override 317 | public Task call() throws Exception { 318 | final ArrayList> tasks = new ArrayList>(); 319 | for (int i = 0; i < 20; i++) { 320 | final Task.TaskCompletionSource tcs = Task.create(); 321 | 322 | final int number = i; 323 | Task.callInBackground(new Callable() { 324 | @Override 325 | public Void call() throws Exception { 326 | Thread.sleep((long) (Math.random() * 1000)); 327 | if (number == 10) { 328 | tcs.setCancelled(); 329 | } else { 330 | tcs.setResult(null); 331 | } 332 | return null; 333 | } 334 | }); 335 | 336 | tasks.add(tcs.getTask()); 337 | } 338 | return Task.whenAll(tasks).continueWith( 339 | new Continuation() { 340 | @Override 341 | public Void then(Task task) { 342 | assertTrue(task.isCompleted()); 343 | assertFalse(task.isFaulted()); 344 | assertTrue(task.isCancelled()); 345 | 346 | for (Task t : tasks) { 347 | assertTrue(t.isCompleted()); 348 | } 349 | return null; 350 | } 351 | }); 352 | } 353 | }); 354 | } 355 | 356 | public void testAsyncChaining() { 357 | runTaskTest(new Callable>() { 358 | public Task call() throws Exception { 359 | final ArrayList sequence = new ArrayList(); 360 | Task result = Task.forResult(null); 361 | for (int i = 0; i < 20; i++) { 362 | final int taskNumber = i; 363 | result = result 364 | .continueWithTask(new Continuation>() { 365 | public Task then(Task task) { 366 | return Task 367 | .callInBackground(new Callable() { 368 | public Void call() 369 | throws Exception { 370 | sequence.add(taskNumber); 371 | return null; 372 | } 373 | }); 374 | } 375 | }); 376 | } 377 | result = result.continueWith(new Continuation() { 378 | public Void then(Task task) { 379 | assertEquals(20, sequence.size()); 380 | for (int i = 0; i < 20; i++) { 381 | assertEquals(i, sequence.get(i).intValue()); 382 | } 383 | return null; 384 | } 385 | }); 386 | return result; 387 | } 388 | }); 389 | } 390 | 391 | public void testOnSuccess() { 392 | Continuation continuation = new Continuation() { 393 | public Integer then(Task task) { 394 | return task.getResult().intValue() + 1; 395 | } 396 | }; 397 | Task complete = Task.forResult(5).onSuccess(continuation); 398 | Task error = Task. forError( 399 | new IllegalStateException()).onSuccess(continuation); 400 | Task cancelled = Task. cancelled().onSuccess( 401 | continuation); 402 | 403 | assertTrue(complete.isCompleted()); 404 | assertEquals(6, complete.getResult().intValue()); 405 | assertFalse(complete.isFaulted()); 406 | assertFalse(complete.isCancelled()); 407 | 408 | assertTrue(error.isCompleted()); 409 | assertTrue(error.getError() instanceof RuntimeException); 410 | assertTrue(error.isFaulted()); 411 | assertFalse(error.isCancelled()); 412 | 413 | assertTrue(cancelled.isCompleted()); 414 | assertFalse(cancelled.isFaulted()); 415 | assertTrue(cancelled.isCancelled()); 416 | } 417 | 418 | public void testOnSuccessTask() { 419 | Continuation> continuation = new Continuation>() { 420 | public Task then(Task task) { 421 | return Task.forResult(task.getResult().intValue() + 1); 422 | } 423 | }; 424 | Task complete = Task.forResult(5).onSuccessTask(continuation); 425 | Task error = Task. forError( 426 | new IllegalStateException()).onSuccessTask(continuation); 427 | Task cancelled = Task. cancelled().onSuccessTask( 428 | continuation); 429 | 430 | assertTrue(complete.isCompleted()); 431 | assertEquals(6, complete.getResult().intValue()); 432 | assertFalse(complete.isFaulted()); 433 | assertFalse(complete.isCancelled()); 434 | 435 | assertTrue(error.isCompleted()); 436 | assertTrue(error.getError() instanceof RuntimeException); 437 | assertTrue(error.isFaulted()); 438 | assertFalse(error.isCancelled()); 439 | 440 | assertTrue(cancelled.isCompleted()); 441 | assertFalse(cancelled.isFaulted()); 442 | assertTrue(cancelled.isCancelled()); 443 | } 444 | 445 | public void testContinueWhile() { 446 | final AtomicInteger count = new AtomicInteger(0); 447 | runTaskTest(new Callable>() { 448 | public Task call() throws Exception { 449 | return Task.forResult(null) 450 | .continueWhile(new Callable() { 451 | public Boolean call() throws Exception { 452 | return count.get() < 10; 453 | } 454 | }, new Continuation>() { 455 | public Task then(Task task) 456 | throws Exception { 457 | count.incrementAndGet(); 458 | return null; 459 | } 460 | }).continueWith(new Continuation() { 461 | public Void then(Task task) throws Exception { 462 | assertEquals(10, count.get()); 463 | return null; 464 | } 465 | }); 466 | } 467 | }); 468 | } 469 | 470 | public void testContinueWhileAsync() { 471 | final AtomicInteger count = new AtomicInteger(0); 472 | runTaskTest(new Callable>() { 473 | public Task call() throws Exception { 474 | return Task 475 | .forResult(null) 476 | .continueWhile(new Callable() { 477 | public Boolean call() throws Exception { 478 | return count.get() < 10; 479 | } 480 | }, new Continuation>() { 481 | public Task then(Task task) 482 | throws Exception { 483 | count.incrementAndGet(); 484 | return null; 485 | } 486 | }, Executors.newCachedThreadPool()) 487 | .continueWith(new Continuation() { 488 | public Void then(Task task) throws Exception { 489 | assertEquals(10, count.get()); 490 | return null; 491 | } 492 | }); 493 | } 494 | }); 495 | } 496 | } -------------------------------------------------------------------------------- /src/test/java/org/parse4j/custom/Person.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.custom; 2 | 3 | import org.parse4j.ParseClassName; 4 | import org.parse4j.ParseObject; 5 | 6 | @ParseClassName("person") 7 | public class Person extends ParseObject { 8 | 9 | public void setAge(int age) { 10 | put("age", age); 11 | } 12 | 13 | public int getAge() { 14 | return getInt("age"); 15 | } 16 | 17 | public void setGender(String gender) { 18 | put("gender", gender); 19 | } 20 | 21 | public String getGender() { 22 | return getString("gender"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/parse4j/custom/Person2.java: -------------------------------------------------------------------------------- 1 | package org.parse4j.custom; 2 | 3 | import org.parse4j.ParseObject; 4 | 5 | public class Person2 extends ParseObject { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/parse.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thiagolocatelli/parse4j/200b2959c18b3d2f517cd3842d1bb646371cc994/src/test/resources/parse.docx -------------------------------------------------------------------------------- /src/test/resources/parse.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thiagolocatelli/parse4j/200b2959c18b3d2f517cd3842d1bb646371cc994/src/test/resources/parse.exr -------------------------------------------------------------------------------- /src/test/resources/parse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thiagolocatelli/parse4j/200b2959c18b3d2f517cd3842d1bb646371cc994/src/test/resources/parse.jpg -------------------------------------------------------------------------------- /src/test/resources/parse.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thiagolocatelli/parse4j/200b2959c18b3d2f517cd3842d1bb646371cc994/src/test/resources/parse.pdf -------------------------------------------------------------------------------- /src/test/resources/parse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thiagolocatelli/parse4j/200b2959c18b3d2f517cd3842d1bb646371cc994/src/test/resources/parse.png --------------------------------------------------------------------------------