132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/doc/package-list:
--------------------------------------------------------------------------------
1 | fr.pcreations.labs.RESTDroid
2 | fr.pcreations.labs.RESTDroid.core
3 | fr.pcreations.labs.RESTDroid.exceptions
4 |
--------------------------------------------------------------------------------
/doc/resources/background.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/doc/resources/background.gif
--------------------------------------------------------------------------------
/doc/resources/tab.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/doc/resources/tab.gif
--------------------------------------------------------------------------------
/doc/resources/titlebar.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/doc/resources/titlebar.gif
--------------------------------------------------------------------------------
/doc/resources/titlebar_end.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/doc/resources/titlebar_end.gif
--------------------------------------------------------------------------------
/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/ic_launcher-web.png
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=Google Inc.:Google APIs:15
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-mdpi/ic_action_search.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PCreations/RESTDroid/699fc9b85d4ad67457f3ae1a655c661368094ca2/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | RESTDroid
4 | Hello world!
5 | Settings
6 | RESTDroid
7 |
8 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/CacheManager.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.FileNotFoundException;
7 | import java.io.FileOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 | import java.util.Date;
12 |
13 | /**
14 | * CacheManager handles caching request in flat file
15 | *
16 | * @author Pierre Criulanscy
17 | *
18 | * @version 0.8
19 | */
20 | public class CacheManager {
21 |
22 | /**
23 | * Don't use caching for this request
24 | */
25 | public static final long DURATION_NO_CACHE = 0L;
26 |
27 | public static final long DURATION_ONE_SECOND = 1000L;
28 | public static final long DURATION_ONE_MINUTE = 60 * DURATION_ONE_SECOND;
29 | public static final long DURATION_ONE_HOUR = 60 * DURATION_ONE_MINUTE;
30 | public static final long DURATION_ONE_DAY = 24 * DURATION_ONE_HOUR;
31 | public static final long DURATION_ONE_WEEK = 7 * DURATION_ONE_DAY;
32 | public static final long DURATION_ONE_MONTH = 30 * DURATION_ONE_WEEK;
33 | public static final long DURATION_ONE_YEAR = 365 * DURATION_ONE_DAY;
34 |
35 | /**
36 | * Android cache directory
37 | */
38 | private static File cacheDir;
39 |
40 | private CacheManager(){}
41 |
42 | /**
43 | * Setter for {@link CacheManager#cacheDir}
44 | *
45 | * @param cacheDir
46 | * The directory used for caching
47 | */
48 | public static void setCacheDir(File cacheDir) {
49 | CacheManager.cacheDir = cacheDir;
50 | }
51 |
52 | /**
53 | * Getter for {@link CacheManager#cacheDir}
54 | *
55 | * @return
56 | * {@link CacheManager#cacheDir}
57 | */
58 | public static File getCacheDir() {
59 | return CacheManager.cacheDir;
60 | }
61 |
62 | /**
63 | * Cache request in {@link CacheManager#cacheDir}
64 | *
65 | * @param request
66 | * The request to cache
67 | *
68 | * @throws IOException
69 | */
70 | public static void cacheRequest(RESTRequest extends Resource> request) throws IOException {
71 | InputStream input = request.getResultStream();
72 | try {
73 | final File file = new File(CacheManager.getCacheDir(), String.valueOf(request.getUrl().hashCode()));
74 | final OutputStream output = new FileOutputStream(file);
75 | try {
76 | try {
77 | final byte[] buffer = new byte[1024];
78 | int read;
79 |
80 | while ((read = input.read(buffer)) != -1)
81 | output.write(buffer, 0, read);
82 |
83 | output.flush();
84 | } finally {
85 | output.close();
86 | }
87 | } catch (Exception e) {
88 | e.printStackTrace();
89 | }
90 | } catch (FileNotFoundException e) {
91 | // TODO Auto-generated catch block
92 | e.printStackTrace();
93 | } finally {
94 | input.close();
95 | }
96 | }
97 |
98 | /**
99 | * Retrieves a {@link RESTRequest} from cache
100 | *
101 | * @param r
102 | * The {@link RESTRequest} to retrieve
103 | *
104 | * @return
105 | */
106 | public static InputStream getRequestFromCache(RESTRequest extends Resource> r) {
107 | InputStream input = null;
108 | int requestHashcode = r.getUrl().hashCode();
109 | Date date = new Date();
110 | long actualTime = date.getTime();
111 | try {
112 | final File file = new File(CacheManager.getCacheDir(), String.valueOf(requestHashcode));
113 | if(file.exists()) {
114 | long lastModifiedTime = file.lastModified();
115 | long difference = actualTime - lastModifiedTime;
116 | if(actualTime - file.lastModified() <= r.getExpirationTime()) {
117 | input = new BufferedInputStream(new FileInputStream(file));
118 | file.setLastModified(lastModifiedTime);
119 | lastModifiedTime = file.lastModified();
120 | difference = difference + 5;
121 | return input;
122 | }
123 | return null;
124 | }
125 | } catch(Exception e) {
126 | e.printStackTrace();
127 | }
128 | return null;
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/DefaultRetryAtDelayedTimeFailBehavior.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Iterator;
5 |
6 | import android.os.Handler;
7 |
8 | /**
9 | * Behavior to retry a request every minute by default until the request is successful
10 | *
11 | *
12 | * If you want to change the default time value just extend this class and call {@link DefaultRetryAtDelayedTimeFailBehavior#setDelayedTime(long)} in {@link DefaultRetryAtDelayedTimeFailBehavior#failAction(WebService, ArrayList)} to set the time you want
13 | *
14 | *
15 | * @author Pierre Criulanscy
16 | *
17 | * @version 0.8
18 | */
19 | public class DefaultRetryAtDelayedTimeFailBehavior extends FailBehavior {
20 |
21 | /**
22 | * Time after which the request will be re-sent
23 | *
24 | * @see DefaultRetryAtDelayedTimeFailBehavior#getDelayedTime()
25 | * @see DefaultRetryAtDelayedTimeFailBehavior#setDelayedTime(long)
26 | */
27 | private long mDelayedTime = CacheManager.DURATION_ONE_MINUTE;
28 |
29 | /**
30 | * @see FailBehavior#failAction(WebService, ArrayList)
31 | */
32 | @Override
33 | public void failAction(WebService context, ArrayList> failedRequests) {
34 | final ArrayList> finalFailedRequests = failedRequests;
35 | final WebService finalContext = context;
36 | Handler handler = new Handler();
37 | handler.postDelayed(new Runnable() {
38 |
39 | @Override
40 | public void run() {
41 | for(Iterator> it = finalFailedRequests.iterator(); it.hasNext();) {
42 | RESTRequest> request = it.next();
43 | finalContext.retryRequest(request);
44 | }
45 | }
46 |
47 | }, mDelayedTime);
48 | }
49 |
50 | /**
51 | * Getter for {@link DefaultRetryAtDelayedTimeFailBehavior#mDelayedTime}
52 | *
53 | * @return
54 | * {@link DefaultRetryAtDelayedTimeFailBehavior#mDelayedTime}
55 | *
56 | * @see DefaultRetryAtDelayedTimeFailBehavior#mDelayedTime
57 | * @see DefaultRetryAtDelayedTimeFailBehavior#setDelayedTime(long)
58 | */
59 | protected long getDelayedTime() {
60 | return mDelayedTime;
61 | }
62 |
63 | /**
64 | * Setter for {@link DefaultRetryAtDelayedTimeFailBehavior#mDelayedTime}
65 | *
66 | * @param delayedTime
67 | * The new delayed time to set
68 | *
69 | * @see DefaultRetryAtDelayedTimeFailBehavior#mDelayedTime
70 | * @see DefaultRetryAtDelayedTimeFailBehavior#getDelayedTime()
71 | */
72 | protected void setDelayedTime(long delayedTime) {
73 | mDelayedTime = delayedTime;
74 | }
75 |
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/FailBehavior.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * FailBehavior lets you implement a behavior for request failure. This behavior is managed by {@link FailBehaviorManager}
7 | *
8 | * @author Pierre Criulanscy
9 | *
10 | * @version 0.8
11 | */
12 | public abstract class FailBehavior {
13 |
14 | /**
15 | * Action to perform for all requests which defined this FailBehavior as behavior of failure
16 | *
17 | * @param context
18 | * Instance of {@link WebService} within which the specified request is running
19 | *
20 | * @param failedRequests
21 | * List of all failed requests
22 | */
23 | abstract public void failAction(WebService context, ArrayList> failedRequests);
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/FailBehaviorManager.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.lang.reflect.Constructor;
4 | import java.lang.reflect.InvocationTargetException;
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.Iterator;
8 | import java.util.Map.Entry;
9 | import java.util.concurrent.CopyOnWriteArrayList;
10 |
11 | /**
12 | * Manages triggering of request's {@link FailBehavior}
13 | *
14 | * @author Pierre Criulanscy
15 | *
16 | * @version 0.8
17 | */
18 | public class FailBehaviorManager {
19 |
20 | /**
21 | * HashMap to store instance of FailBehavior as singletons
22 | *
23 | *
24 | *
key : Class object of {@link FailBehavior} class
25 | *
value : Instance of {@link FailBehavior} store as singleton
26 | *
27 | */
28 | private static HashMap, FailBehavior> failBehaviors = new HashMap, FailBehavior>();
29 |
30 | private FailBehaviorManager() {}
31 |
32 | /**
33 | * Triggers the specified {@link FailBehavior} for each failed request which defines it as behavior of failure
34 | *
35 | * @param context
36 | * Instance of {@link WebService} within which the specified request is running
37 | *
38 | * @param failBehaviorClass
39 | * The {@link FailBehavior} Class object to trigger
40 | *
41 | * @throws NoSuchMethodException
42 | * @throws IllegalArgumentException
43 | * @throws InstantiationException
44 | * @throws IllegalAccessException
45 | * @throws InvocationTargetException
46 | */
47 | public static void trigger(WebService context, Class extends FailBehavior> failBehaviorClass) throws NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
48 | CopyOnWriteArrayList> failedRequests = WebService.getFailedRequests();
49 |
50 | /* HashMap used to manage polymorphism if user decided to extend basic FailBehavior classes */
51 | HashMap, ArrayList>> requestsToRetry = new HashMap, ArrayList>>();
52 |
53 | for(Iterator> it = failedRequests.iterator(); it.hasNext();) {
54 | RESTRequest> r = it.next();
55 | if(r.getFailBehaviorClass().equals(failBehaviorClass) || (r.getFailBehaviorClass().getSuperclass().equals(failBehaviorClass))) {
56 | if(!requestsToRetry.containsKey(r.getFailBehaviorClass())) {
57 | requestsToRetry.put(r.getFailBehaviorClass(), new ArrayList>());
58 | }
59 | requestsToRetry.get(r.getFailBehaviorClass()).add(r);
60 | }
61 | }
62 |
63 | for(Entry, ArrayList>> entry : requestsToRetry.entrySet()) {
64 | /* Iteration to initialize new instance of FailBehavior if needed */
65 | for(Iterator> it = entry.getValue().iterator(); it.hasNext();) {
66 | RESTRequest extends Resource> r = it.next();
67 | if(!failBehaviors.containsKey(entry.getKey())) {
68 | Constructor extends FailBehavior> ctor = r.getFailBehaviorClass().getConstructor();
69 | failBehaviors.put(entry.getKey(), ctor.newInstance());
70 | }
71 | }
72 |
73 | failBehaviors.get(entry.getKey()).failAction(context, entry.getValue());
74 | }
75 |
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/HTTPVerb.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | /**
4 | * Public enumeration of HTTP verb
5 | *
6 | * @author Pierre Criulanscy
7 | *
8 | * @version 0.5
9 | */
10 | public enum HTTPVerb { GET, POST, PUT, DELETE };
11 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/ListenerState.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | /**
4 | * Enum which represents ListenerState
5 | *
6 | *
7 | *
8 | *
SET : indicates that the listener is activate and ready to be triggered
9 | *
UNSET : indicates that the listener is deactivate. If listener has to be triggered, his state is updated to {@link ListenerState#TRIGGER_ME}
10 | *
TRIGGER_ME : indicates that the listener has to be triggered as soon as possible
11 | *
TRIGGERED : indicates that the listener has been triggered
12 | *
13 | *
14 | *
15 | * @author Pierre Criulanscy
16 | *
17 | * @version 0.8
18 | *
19 | * @see OnStartedRequestListener
20 | * @see OnFailedRequestListener
21 | * @see OnSucceededRequestListener
22 | */
23 | public enum ListenerState {
24 | SET,
25 | UNSET,
26 | TRIGGER_ME,
27 | TRIGGERED
28 | }
29 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/Module.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | /**
4 | * Class used to hold all your specifics needs without editing the core classes
5 | *
6 | * A module has to be register on {@link WebService} instance. It provides {@link Processor}, {@link ParserFactory} and {@link PersistableFactory} that will be used during all process
7 | *
8 | *
9 | * @author Pierre Criulanscy
10 | *
11 | * @version 0.6.1
12 | *
13 | * @see Processor
14 | * @see ParserFactory
15 | * @see PersistableFactory
16 | * @see WebService#registerModule(Module)
17 | */
18 | abstract public class Module {
19 |
20 | /**
21 | * Instance of {@link Processor}
22 | */
23 | protected Processor mProcessor;
24 |
25 | /**
26 | * Initialize the {@link Processor} and the {@link ParserFactory} and {@link PersistableFactory} of the processor
27 | *
28 | * @see Module#setProcessor()
29 | * @see Module#setParserFactory()
30 | * @see Module#setPersistableFactory()
31 | */
32 | public void init() {
33 | mProcessor = setProcessor();
34 | mProcessor.setParserFactory(setParserFactory());
35 | mProcessor.setPersistableFactory(setPersistableFactory());
36 | }
37 |
38 | /**
39 | * Return the {@link Processor} you want for this module
40 | *
41 | * @return
42 | * Instance of {@link Processor}
43 | *
44 | * @see Module#mProcessor
45 | */
46 | abstract public Processor setProcessor();
47 |
48 | /**
49 | * Return the {@link ParserFactory} you want for this module
50 | *
51 | * @return
52 | * Instance of {@link ParserFactory}
53 | */
54 | abstract public ParserFactory setParserFactory();
55 |
56 | /**
57 | * Return the {@link PersistableFactory} you want for this module
58 | *
59 | * @return
60 | * Instance of {@link PersistableFactory}
61 | */
62 | abstract public PersistableFactory setPersistableFactory();
63 |
64 | /**
65 | * Getter for {@link Processor} field
66 | *
67 | * @return
68 | * The {@link Processor} field
69 | *
70 | * @see Module#mProcessor
71 | */
72 | public Processor getProcessor() {
73 | return mProcessor;
74 | }
75 |
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/Parser.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.io.InputStream;
4 |
5 | import fr.pcreations.labs.RESTDroid.exceptions.ParsingException;
6 |
7 | /**
8 | * Interface which represents Parser
9 | *
10 | * @author Pierre Criulanscy
11 | *
12 | * @param
13 | * The Class object of {@link ResourceRepresentation} which is parsed with this parser
14 | *
15 | * @version 0.5
16 | */
17 | public interface Parser {
18 |
19 | /**
20 | * Use this method to return parsed {@link ResourceRepresentation} from InputStream
21 | *
22 | * @param content
23 | * The InputStream representing {@link ResourceRepresentation}
24 | *
25 | * @return
26 | * Parsed {@link ResourceRepresentation}
27 | *
28 | * @throws ParsingException
29 | */
30 | public T parseToObject(InputStream content) throws ParsingException;
31 |
32 | /**
33 | * Use this method to return InputStream parsed from {@link ResourceRepresentation}
34 | *
35 | * @param resource
36 | * The {@link ResourceRepresentation} which will be parsed to InputStream
37 | *
38 | * @return
39 | * InputStream representing the {@link ResourceRepresentation}
40 | *
41 | * @throws ParsingException
42 | */
43 | public InputStream parseToInputStream(T resource) throws ParsingException;
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/ParserFactory.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.util.HashMap;
4 |
5 | /**
6 | * Base class for ParserFactory that handle creation and access of Parser as Singleton
7 | *
8 | * @author Pierre Criulanscy
9 | *
10 | * @version 0.5
11 | */
12 | abstract public class ParserFactory {
13 |
14 | /**
15 | * HashMap to store Parser as Singleton
16 | *
17 | *
18 | *
key : {@link ResourceRepresentation} Class object
19 | *
value : {@link Parser} instance
20 | *
21 | *
22 | */
23 | protected HashMap, Parser extends Resource>> mParserMap;
24 |
25 | /**
26 | * Constructor
27 | */
28 | protected ParserFactory() {
29 | mParserMap = new HashMap, Parser extends Resource>>();
30 | }
31 |
32 | /**
33 | * Method to retrieve Parser. Parser should be store in mParserMap in order to store parser as singleton :
34 |
42 |
43 | *
44 | * @param clazz
45 | * The {@link ResourceRepresentation} class
46 | *
47 | * @return
48 | * Instance of {@link Parser}
49 | */
50 | public abstract
, T extends Resource> P getParser(Class clazz);
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/Persistable.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.sql.SQLException;
4 | import java.util.List;
5 |
6 |
7 | /**
8 | * Interface which represents methods to implement for object persistency
9 | *
10 | * @author Pierre Criulanscy
11 | *
12 | * @param
13 | * A class derivated from {@link ResourceRepresentation}
14 | *
15 | * @version 0.6.1
16 | *
17 | * @see ResourceRepresentation
18 | */
19 | public interface Persistable {
20 |
21 | /**
22 | * This method has to create a new resource or update it if already exists.
23 | *
24 | * @param resource
25 | * The resource to create or update
26 | *
27 | * @throws SQLException if a sql error occurs.
28 | *
29 | */
30 | abstract public void updateOrCreate(T resource)throws Exception;
31 |
32 | /**
33 | * This method has to return the resource corresponding to the given ID. ID is a parametrized type corresponding to the {@link ResourceRepresentation} id field type
34 | *
35 | * @param resourceId
36 | * The id of the resource
37 | *
38 | * @return
39 | * The resource corresponding to the given ID
40 | *
41 | * @throws SQLException if a sql error occurs
42 | */
43 | abstract public T findById(ID resourceId) throws Exception;
44 |
45 | /**
46 | * This method has to return all resources of the parameterized type defined by the interface
47 | *
48 | * @return
49 | * A list of all the resources
50 | *
51 | * @throws SQLException if a sql error occurs
52 | */
53 | abstract public List queryForAll() throws Exception;
54 |
55 | /**
56 | * This method has to delete the specified resource
57 | *
58 | * @param resource
59 | * The resource to delete
60 | *
61 | * @return
62 | * Number of resource actually deleted (should be 1)
63 | *
64 | * @throws SQLException if a sql error occurs
65 | */
66 | abstract public int deleteResource(T resource) throws Exception;
67 |
68 | /**
69 | * This method has to update the specified resource
70 | *
71 | * @param resource
72 | * The resource to update
73 | *
74 | * @return
75 | * Number of resource actually updated (should be 1)
76 | *
77 | * @throws SQLException if a sql error occurs
78 | */
79 | abstract public int updateResource(T resource) throws Exception;
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/PersistableFactory.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.util.HashMap;
4 |
5 | /**
6 | * Base class for DaoFactory that handle creation and access of Persistable classes as Singleton
7 | *
8 | * @author Pierre Criulanscy
9 | *
10 | * @version 0.6.1
11 | */
12 | abstract public class PersistableFactory {
13 |
14 | /**
15 | * HashMap to store Persistable as Singleton
16 | *
17 | *
18 | *
key : {@link ResourceRepresentation} Class object
19 | *
value : {@link Persistable} instance
20 | *
21 | *
22 | */
23 | protected HashMap, Persistable extends Resource>> mPersistables;
24 |
25 | /**
26 | * Constructor
27 | */
28 | public PersistableFactory() {
29 | mPersistables = new HashMap, Persistable extends Resource>>();
30 | }
31 |
32 | /**
33 | * Method to retrieve Persistable. Persistable should be store in mDaos in order to store Persistable as singleton :
34 | *
35 | *
43 | *
44 | * @param clazz
45 | * Class object of the {@link ResourceRepresentation} in order to get the corresponding Persistable
46 | *
47 | * @return
48 | * The Persistable instance
49 | *
50 | * @see Persistable
51 | * @see ResourceRepresentation
52 | */
53 | public abstract
, R extends Resource> P getPersistable(Class clazz);
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/RESTDroid.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.lang.reflect.Constructor;
4 | import java.lang.reflect.InvocationTargetException;
5 | import java.util.HashMap;
6 |
7 | import android.content.Context;
8 | import android.util.Log;
9 | import fr.pcreations.labs.RESTDroid.exceptions.RESTDroidNotInitializedException;
10 |
11 | /**
12 | * RESTDroid is an open source library to handle calls to REST webservice with data caching and persistence features
13 | * @author Pierre Criulanscy
14 | * @version 0.5
15 | */
16 | public class RESTDroid {
17 |
18 | /**
19 | * Unique instance of RESTDroid class
20 | *
21 | * @see RESTDroid#init(Context)
22 | * @see RESTDroid#getInstance()
23 | */
24 | private static RESTDroid instance;
25 |
26 | /**
27 | * Actual application context
28 | * @see RESTDroid#init(Context)
29 | */
30 | private Context mContext;
31 |
32 | /**
33 | * HashMap to store WebService class as singleton
34 | *
35 | *
36 | *
37 | *
key : Class extends WebService>
38 | *
value : WebService instance
39 | *
40 | *
41 | *
42 | * @see WebService
43 | * @see RESTDroid#getWebService(Class)
44 | */
45 | private HashMap, WebService> mWebServices;
46 |
47 |
48 | /**
49 | * Private constructor for singleton
50 | *
51 | * @param context
52 | *
53 | * @see RESTDroid#init(Context)
54 | * @see RESTDroid#getInstance()
55 | */
56 | private RESTDroid(Context context) {
57 | mContext = context;
58 | mWebServices = new HashMap, WebService>();
59 | }
60 |
61 |
62 | /**
63 | * Initializer for RESTDroid singleton. Call it in Activity.onStart()
64 | *
65 | * @param context
66 | * The actual application context
67 | *
68 | * @see RESTDroid#getInstance()
69 | */
70 | static public void init(Context context) {
71 | if(null == instance)
72 | instance = new RESTDroid(context);
73 | }
74 |
75 | /**
76 | * Gives the unique RESTDroid instance
77 | *
78 | * @see RESTDroid#init(Context)
79 | * @see RESTDroid#instance
80 | *
81 | * @throws RESTDroidNotInitializedException if RESTDroid hasn't been initialized with {@link RESTDroid#init(Context)}
82 | */
83 | static public RESTDroid getInstance() throws RESTDroidNotInitializedException {
84 | if(instance != null)
85 | return instance;
86 | throw new RESTDroidNotInitializedException();
87 | }
88 |
89 | /**
90 | *
91 | * @param clazz
92 | * Class object of WebService class to retrieve
93 | *
94 | * @return Instance of WebService class
95 | *
96 | * @throws RESTDroidNotInitializedException
97 | *
98 | * @see WebService
99 | */
100 | @SuppressWarnings("unchecked")
101 | public WebService getWebService(Class clazz) throws RESTDroidNotInitializedException {
102 | if(null == instance)
103 | throw new RESTDroidNotInitializedException();
104 | if(instance.mWebServices.containsKey(clazz)) {
105 | Log.i("debug", "webservice ALREADY exists");
106 | return instance.mWebServices.get(clazz);
107 | }
108 | Log.i("debug", "webservice doesn't exists");
109 | Class _tempClass;
110 | try {
111 | _tempClass = (Class) Class.forName(clazz.getName());
112 | Constructor ctor = _tempClass.getDeclaredConstructor(Context.class);
113 | instance.mWebServices.put(clazz, ctor.newInstance(instance.mContext));
114 | return instance.mWebServices.get(clazz);
115 | } catch (ClassNotFoundException e) {
116 | // TODO Auto-generated catch block
117 | e.printStackTrace();
118 | } catch (NoSuchMethodException e) {
119 | // TODO Auto-generated catch block
120 | e.printStackTrace();
121 | } catch (IllegalArgumentException e) {
122 | // TODO Auto-generated catch block
123 | e.printStackTrace();
124 | } catch (InstantiationException e) {
125 | // TODO Auto-generated catch block
126 | e.printStackTrace();
127 | } catch (IllegalAccessException e) {
128 | // TODO Auto-generated catch block
129 | e.printStackTrace();
130 | } catch (InvocationTargetException e) {
131 | // TODO Auto-generated catch block
132 | e.printStackTrace();
133 | }
134 |
135 | return null;
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/RequestState.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | /**
4 | * Constant class which defined request state. Used to mirror the server state of {@link ResourceRepresentation}
5 | *
6 | * @author Pierre Criulanscy
7 | *
8 | * @version 0.5
9 | *
10 | */
11 | public class RequestState {
12 |
13 | /**
14 | * Request has succeed
15 | */
16 |
17 | public final static int STATE_OK = 0;
18 |
19 | /**
20 | * Request is updating data to the server
21 | */
22 | public final static int STATE_UPDATING = 1;
23 |
24 | /**
25 | * Request is deleting data to the server
26 | */
27 | public final static int STATE_DELETING = 2;
28 |
29 | /**
30 | * Request is posting data to the server
31 | */
32 | public final static int STATE_POSTING = 3;
33 |
34 | }
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/Resource.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Interface which represents a Resource
7 | *
8 | * @author Pierre Criulanscy
9 | *
10 | * @version 0.8
11 | *
12 | * @see ResourcesList
13 | * @see ResourceRepresentation
14 | */
15 | public interface Resource extends Serializable {}
16 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/ResourceRepresentation.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 |
4 | /**
5 | * Interface which represents application items that have to be synchronized with the server
6 | *
7 | * @author Pierre Criulanscy
8 | *
9 | * @param
10 | * The type of the id field of the item
11 | *
12 | * @version 0.5
13 | */
14 | public interface ResourceRepresentation extends Resource {
15 |
16 | /**
17 | * Getter for id field
18 | *
19 | * @return
20 | * The item's id
21 | *
22 | * @see ResourceRepresentation#setId(Object)
23 | */
24 | abstract public ID getId();
25 |
26 | /**
27 | * Getter for {@link RequestState}. Used by {@link Processor} to handle server mirroring
28 | *
29 | * @return
30 | * The item's {@link RequestState}
31 | *
32 | * @see ResourceRepresentation#setState(int)
33 | * @see Processor#mirrorServerState(RESTRequest)
34 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
35 | */
36 | abstract public int getState();
37 |
38 | /**
39 | * Getter for result code. Used by {@link Processor} to handle server mirroring
40 | *
41 | * @return
42 | * The item's result code
43 | *
44 | * @see ResourceRepresentation#setResultCode(int)
45 | * @see Processor#mirrorServerState(RESTRequest)
46 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
47 | */
48 | abstract public int getResultCode();
49 |
50 | /**
51 | * Getter for transacting flag. Used by {@link Processor} to handle server mirroring
52 | *
53 | * @return
54 | * The item's transacting flag
55 | *
56 | * @see ResourceRepresentation#setTransactingFlag(boolean)
57 | * @see Processor#mirrorServerState(RESTRequest)
58 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
59 | */
60 | abstract public boolean getTransactingFlag();
61 |
62 | /**
63 | * Setter for item's id
64 | *
65 | * @param id
66 | * Id to store in this item
67 | *
68 | * @see ResourceRepresentation#getId()
69 | * @see Processor#mirrorServerState(RESTRequest)
70 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
71 | */
72 | abstract public void setId(ID id);
73 |
74 | /**
75 | * Setter for item's {@link RequestState}. Used by {@link Processor} to handle server mirroring
76 | *
77 | * @param state
78 | * The {@link RequestState} to store in this item
79 | *
80 | * @see ResourceRepresentation#getState()
81 | * @see Processor#mirrorServerState(RESTRequest)
82 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
83 | */
84 | abstract public void setState(int state);
85 |
86 | /**
87 | * Setter for transacting flag. Used by {@link Processor} to handle server mirroring
88 | *
89 | * @param transacting
90 | * The transacting flag to store in this item
91 | *
92 | * @see ResourceRepresentation#getTransactingFlag()
93 | * @see Processor#mirrorServerState(RESTRequest)
94 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
95 | */
96 | abstract public void setTransactingFlag(boolean transacting);
97 |
98 | /**
99 | * Setter for item's result code. Used by {@link Processor} to handle server mirroring
100 | *
101 | * @param resultCode
102 | * The result code to store in this item
103 | *
104 | * @see ResourceRepresentation#getResultCode()
105 | * @see Processor#mirrorServerState(RESTRequest)
106 | * @see Processor#updateLocalResource(int, RESTRequest, java.io.InputStream)
107 | */
108 | abstract public void setResultCode(int resultCode);
109 | }
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/ResourcesList.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Interface which represents a list of {@link ResourceRepresentation}
7 | *
8 | * @author Pierre Criulanscy
9 | *
10 | * @version 0.8
11 | *
12 | * @see Resource
13 | * @see ResourceRepresentation
14 | */
15 | public interface ResourcesList extends Resource {
16 |
17 | /**
18 | * Getter for the {@link ResourceRepresentation} list holding by this {@link ResourcesList}
19 | *
20 | * @return
21 | * List of {@link ResourceRepresentation}
22 | */
23 | abstract public List extends ResourceRepresentation>> getResourcesList();
24 |
25 | /**
26 | * Getter for the {@link ResourceRepresentation} list holding by this {@link ResourcesList}
27 | *
28 | * @param list
29 | * List of {@link ResourceRepresentation}
30 | */
31 | abstract public void setResourcesList(List extends ResourceRepresentation>> list);
32 |
33 | /**
34 | * Add a {@link ResourceRepresentation} in the list of {@link ResourceRepresentation}
35 | *
36 | * @param resourceRepresentation
37 | * The {@link ResourceRepresentation} to add in list
38 | *
39 | * @return
40 | * True if the {@link ResourceRepresentation} has been added, false otherwise
41 | */
42 | abstract public boolean addInList(ResourceRepresentation> resourceRepresentation);
43 | }
44 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/RestResultReceiver.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.ResultReceiver;
6 |
7 | /**
8 | * Specific implementation of {@link ResultReceiver} for {@link RESTDroid}
9 | *
10 | * @author Pierre Criulanscy
11 | *
12 | * @version 0.5
13 | *
14 | */
15 | public class RestResultReceiver extends ResultReceiver {
16 | private Receiver mReceiver;
17 |
18 | public RestResultReceiver(Handler handler) {
19 | super(handler);
20 | }
21 |
22 | public void setReceiver(Receiver receiver) {
23 | mReceiver = receiver;
24 | }
25 |
26 | public interface Receiver {
27 | public void onReceiveResult(int resultCode, Bundle resultData);
28 | }
29 |
30 | @Override
31 | protected void onReceiveResult(int resultCode, Bundle resultData) {
32 | if (mReceiver != null) {
33 | mReceiver.onReceiveResult(resultCode, resultData);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/fr/pcreations/labs/RESTDroid/core/RestService.java:
--------------------------------------------------------------------------------
1 | package fr.pcreations.labs.RESTDroid.core;
2 |
3 | import android.app.IntentService;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.ResultReceiver;
7 | import fr.pcreations.labs.RESTDroid.core.Processor.RESTServiceCallback;
8 |
9 | /**
10 | * Service class which hold all process populating an Intent map and calling {@link Processor#process(RESTRequest)}
11 | *
12 | *
13 | * On the forward path the service receives the Intent sent by {@link WebService} and starts the corresponding REST method.
14 | * On the return path the service handles the callback fires by {@link Processor} and sends the result to the {@link RestResultReceiver}
15 | *