Index: trunk/src/google_apis/drive/drive_api_requests.cc |
=================================================================== |
--- trunk/src/google_apis/drive/drive_api_requests.cc (revision 288215) |
+++ trunk/src/google_apis/drive/drive_api_requests.cc (working copy) |
@@ -11,6 +11,7 @@ |
#include "base/sequenced_task_runner.h" |
#include "base/task_runner_util.h" |
#include "base/values.h" |
+#include "google_apis/drive/drive_api_parser.h" |
#include "google_apis/drive/request_sender.h" |
#include "google_apis/drive/request_util.h" |
#include "google_apis/drive/time_util.h" |
@@ -22,6 +23,70 @@ |
const char kContentTypeApplicationJson[] = "application/json"; |
const char kParentLinkKind[] = "drive#fileLink"; |
+// Parses the JSON value to a resource typed |T| and runs |callback| on the UI |
+// thread once parsing is done. |
+template<typename T> |
+void ParseJsonAndRun( |
+ const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback, |
+ GDataErrorCode error, |
+ scoped_ptr<base::Value> value) { |
+ DCHECK(!callback.is_null()); |
+ |
+ scoped_ptr<T> resource; |
+ if (value) { |
+ resource = T::CreateFrom(*value); |
+ if (!resource) { |
+ // Failed to parse the JSON value, although the JSON value is available, |
+ // so let the callback know the parsing error. |
+ error = GDATA_PARSE_ERROR; |
+ } |
+ } |
+ |
+ callback.Run(error, resource.Pass()); |
+} |
+ |
+// Thin adapter of T::CreateFrom. |
+template<typename T> |
+scoped_ptr<T> ParseJsonOnBlockingPool(scoped_ptr<base::Value> value) { |
+ return T::CreateFrom(*value); |
+} |
+ |
+// Runs |callback| with given |error| and |value|. If |value| is null, |
+// overwrites |error| to GDATA_PARSE_ERROR. |
+template<typename T> |
+void ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask( |
+ const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback, |
+ GDataErrorCode error, scoped_ptr<T> value) { |
+ if (!value) |
+ error = GDATA_PARSE_ERROR; |
+ callback.Run(error, value.Pass()); |
+} |
+ |
+// Parses the JSON value to a resource typed |T| and runs |callback| on |
+// blocking pool, and then run on the current thread. |
+// TODO(hidehiko): Move this and ParseJsonAndRun defined above into base with |
+// merging the tasks running on blocking pool into one. |
+template<typename T> |
+void ParseJsonOnBlockingPoolAndRun( |
+ scoped_refptr<base::TaskRunner> blocking_task_runner, |
+ const base::Callback<void(GDataErrorCode, scoped_ptr<T>)>& callback, |
+ GDataErrorCode error, |
+ scoped_ptr<base::Value> value) { |
+ DCHECK(!callback.is_null()); |
+ |
+ if (!value) { |
+ callback.Run(error, scoped_ptr<T>()); |
+ return; |
+ } |
+ |
+ base::PostTaskAndReplyWithResult( |
+ blocking_task_runner, |
+ FROM_HERE, |
+ base::Bind(&ParseJsonOnBlockingPool<T>, base::Passed(&value)), |
+ base::Bind(&ParseJsonOnBlockingPoolAndRunAfterBlockingPoolTask<T>, |
+ callback, error)); |
+} |
+ |
// Parses the JSON value to FileResource instance and runs |callback| on the |
// UI thread once parsing is done. |
// This is customized version of ParseJsonAndRun defined above to adapt the |
@@ -61,16 +126,17 @@ |
namespace drive { |
-//============================ DriveApiPartialFieldRequest ==================== |
+//============================ DriveApiDataRequest =========================== |
-DriveApiPartialFieldRequest::DriveApiPartialFieldRequest( |
- RequestSender* sender) : UrlFetchRequestBase(sender) { |
+DriveApiDataRequest::DriveApiDataRequest(RequestSender* sender, |
+ const GetDataCallback& callback) |
+ : GetDataRequest(sender, callback) { |
} |
-DriveApiPartialFieldRequest::~DriveApiPartialFieldRequest() { |
+DriveApiDataRequest::~DriveApiDataRequest() { |
} |
-GURL DriveApiPartialFieldRequest::GetURL() const { |
+GURL DriveApiDataRequest::GetURL() const { |
GURL url = GetURLInternal(); |
if (!fields_.empty()) |
url = net::AppendOrReplaceQueryParameter(url, "fields", fields_); |
@@ -83,7 +149,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileResourceCallback& callback) |
- : DriveApiDataRequest<FileResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<FileResource>, callback)), |
url_generator_(url_generator) { |
DCHECK(!callback.is_null()); |
} |
@@ -100,7 +168,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileResourceCallback& callback) |
- : DriveApiDataRequest<FileResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<FileResource>, callback)), |
url_generator_(url_generator) { |
DCHECK(!callback.is_null()); |
} |
@@ -121,7 +191,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileResourceCallback& callback) |
- : DriveApiDataRequest<FileResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<FileResource>, callback)), |
url_generator_(url_generator) { |
DCHECK(!callback.is_null()); |
} |
@@ -178,7 +250,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileResourceCallback& callback) |
- : DriveApiDataRequest<FileResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<FileResource>, callback)), |
url_generator_(url_generator), |
set_modified_date_(false), |
update_viewed_date_(true) { |
@@ -246,7 +320,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileResourceCallback& callback) |
- : DriveApiDataRequest<FileResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<FileResource>, callback)), |
url_generator_(url_generator) { |
DCHECK(!callback.is_null()); |
} |
@@ -299,7 +375,11 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileListCallback& callback) |
- : DriveApiDataRequest<FileList>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>, |
+ make_scoped_refptr(sender->blocking_task_runner()), |
+ callback)), |
url_generator_(url_generator), |
max_results_(100) { |
DCHECK(!callback.is_null()); |
@@ -316,7 +396,11 @@ |
FilesListNextPageRequest::FilesListNextPageRequest( |
RequestSender* sender, |
const FileListCallback& callback) |
- : DriveApiDataRequest<FileList>(sender, callback) { |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>, |
+ make_scoped_refptr(sender->blocking_task_runner()), |
+ callback)) { |
DCHECK(!callback.is_null()); |
} |
@@ -361,7 +445,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const FileResourceCallback& callback) |
- : DriveApiDataRequest<FileResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<FileResource>, callback)), |
url_generator_(url_generator) { |
DCHECK(!callback.is_null()); |
} |
@@ -382,7 +468,9 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const AboutResourceCallback& callback) |
- : DriveApiDataRequest<AboutResource>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<AboutResource>, callback)), |
url_generator_(url_generator) { |
DCHECK(!callback.is_null()); |
} |
@@ -399,7 +487,11 @@ |
RequestSender* sender, |
const DriveApiUrlGenerator& url_generator, |
const ChangeListCallback& callback) |
- : DriveApiDataRequest<ChangeList>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>, |
+ make_scoped_refptr(sender->blocking_task_runner()), |
+ callback)), |
url_generator_(url_generator), |
include_deleted_(true), |
max_results_(100), |
@@ -419,7 +511,11 @@ |
ChangesListNextPageRequest::ChangesListNextPageRequest( |
RequestSender* sender, |
const ChangeListCallback& callback) |
- : DriveApiDataRequest<ChangeList>(sender, callback) { |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>, |
+ make_scoped_refptr(sender->blocking_task_runner()), |
+ callback)) { |
DCHECK(!callback.is_null()); |
} |
@@ -437,7 +533,9 @@ |
const DriveApiUrlGenerator& url_generator, |
bool use_internal_endpoint, |
const AppListCallback& callback) |
- : DriveApiDataRequest<AppList>(sender, callback), |
+ : DriveApiDataRequest( |
+ sender, |
+ base::Bind(&ParseJsonAndRun<AppList>, callback)), |
url_generator_(url_generator), |
use_internal_endpoint_(use_internal_endpoint) { |
DCHECK(!callback.is_null()); |