Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / google_apis / drive / drive_api_requests.h
index 59bffd6..a983dd5 100644 (file)
@@ -8,17 +8,18 @@
 #include <string>
 
 #include "base/callback_forward.h"
+#include "base/location.h"
+#include "base/sequenced_task_runner.h"
+#include "base/task_runner_util.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "google_apis/drive/base_requests.h"
+#include "google_apis/drive/drive_api_parser.h"
 #include "google_apis/drive/drive_api_url_generator.h"
 #include "google_apis/drive/drive_common_callbacks.h"
 
 namespace google_apis {
 
-class ChangeList;
-class FileResource;
-class FileList;
-
 // Callback used for requests that the server returns FileResource data
 // formatted into JSON value.
 typedef base::Callback<void(GDataErrorCode error,
@@ -37,23 +38,23 @@ typedef base::Callback<void(GDataErrorCode error,
 
 namespace drive {
 
-//============================ DriveApiDataRequest ===========================
+//============================ DriveApiPartialFieldRequest ====================
 
 // This is base class of the Drive API related requests. All Drive API requests
 // support partial request (to improve the performance). The function can be
 // shared among the Drive API requests.
 // See also https://developers.google.com/drive/performance
-class DriveApiDataRequest : public GetDataRequest {
+class DriveApiPartialFieldRequest : public UrlFetchRequestBase {
  public:
-  DriveApiDataRequest(RequestSender* sender, const GetDataCallback& callback);
-  virtual ~DriveApiDataRequest();
+  explicit DriveApiPartialFieldRequest(RequestSender* sender);
+  virtual ~DriveApiPartialFieldRequest();
 
   // Optional parameter.
   const std::string& fields() const { return fields_; }
   void set_fields(const std::string& fields) { fields_ = fields; }
 
  protected:
-  // Overridden from GetDataRequest.
+  // UrlFetchRequestBase overrides.
   virtual GURL GetURL() const OVERRIDE;
 
   // Derived classes should override GetURLInternal instead of GetURL()
@@ -63,6 +64,75 @@ class DriveApiDataRequest : public GetDataRequest {
  private:
   std::string fields_;
 
+  DISALLOW_COPY_AND_ASSIGN(DriveApiPartialFieldRequest);
+};
+
+//============================ DriveApiDataRequest ===========================
+
+// The base class of Drive API related requests that receive a JSON response
+// representing |DataType|.
+template<class DataType>
+class DriveApiDataRequest : public DriveApiPartialFieldRequest {
+ public:
+  typedef base::Callback<void(GDataErrorCode error,
+                              scoped_ptr<DataType> data)> Callback;
+
+  // |callback| is called when the request finishes either by success or by
+  // failure. On success, a JSON Value object is passed. It must not be null.
+  DriveApiDataRequest(RequestSender* sender, const Callback& callback)
+      : DriveApiPartialFieldRequest(sender),
+        callback_(callback),
+        weak_ptr_factory_(this) {
+    DCHECK(!callback_.is_null());
+  }
+  virtual ~DriveApiDataRequest() {}
+
+ protected:
+  // UrlFetchRequestBase overrides.
+  virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE {
+    GDataErrorCode error = GetErrorCode();
+    switch (error) {
+      case HTTP_SUCCESS:
+      case HTTP_CREATED:
+        base::PostTaskAndReplyWithResult(
+            blocking_task_runner(),
+            FROM_HERE,
+            base::Bind(&DriveApiDataRequest::Parse, response_writer()->data()),
+            base::Bind(&DriveApiDataRequest::OnDataParsed,
+                       weak_ptr_factory_.GetWeakPtr(), error));
+        break;
+      default:
+        RunCallbackOnPrematureFailure(error);
+        OnProcessURLFetchResultsComplete();
+        break;
+    }
+  }
+
+  virtual void RunCallbackOnPrematureFailure(GDataErrorCode error) OVERRIDE {
+    callback_.Run(error, scoped_ptr<DataType>());
+  }
+
+ private:
+  // Parses the |json| string by using DataType::CreateFrom.
+  static scoped_ptr<DataType> Parse(const std::string& json) {
+    scoped_ptr<base::Value> value = ParseJson(json);
+    return value ? DataType::CreateFrom(*value) : scoped_ptr<DataType>();
+  }
+
+  // Receives the parsed result and invokes the callback.
+  void OnDataParsed(GDataErrorCode error, scoped_ptr<DataType> value) {
+    if (!value)
+      error = GDATA_PARSE_ERROR;
+    callback_.Run(error, value.Pass());
+    OnProcessURLFetchResultsComplete();
+  }
+
+  const Callback callback_;
+
+  // Note: This should remain the last member so it'll be destroyed and
+  // invalidate its weak pointers before any other members are destroyed.
+  base::WeakPtrFactory<DriveApiDataRequest> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(DriveApiDataRequest);
 };
 
@@ -71,7 +141,7 @@ class DriveApiDataRequest : public GetDataRequest {
 // This class performs the request for fetching a file.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/files/get
-class FilesGetRequest : public DriveApiDataRequest {
+class FilesGetRequest : public DriveApiDataRequest<FileResource> {
  public:
   FilesGetRequest(RequestSender* sender,
                   const DriveApiUrlGenerator& url_generator,
@@ -97,7 +167,7 @@ class FilesGetRequest : public DriveApiDataRequest {
 
 // This class performs request for authorizing an app to access a file.
 // This request is mapped to /drive/v2internal/file/authorize internal endpoint.
-class FilesAuthorizeRequest : public DriveApiDataRequest {
+class FilesAuthorizeRequest : public DriveApiDataRequest<FileResource> {
  public:
   FilesAuthorizeRequest(RequestSender* sender,
                         const DriveApiUrlGenerator& url_generator,
@@ -132,7 +202,7 @@ class FilesAuthorizeRequest : public DriveApiDataRequest {
 // https://developers.google.com/drive/v2/reference/files/insert
 // See also https://developers.google.com/drive/manage-uploads and
 // https://developers.google.com/drive/folder
-class FilesInsertRequest : public DriveApiDataRequest {
+class FilesInsertRequest : public DriveApiDataRequest<FileResource> {
  public:
   FilesInsertRequest(RequestSender* sender,
                      const DriveApiUrlGenerator& url_generator,
@@ -189,7 +259,7 @@ class FilesInsertRequest : public DriveApiDataRequest {
 // This class performs the request for patching file metadata.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/files/patch
-class FilesPatchRequest : public DriveApiDataRequest {
+class FilesPatchRequest : public DriveApiDataRequest<FileResource> {
  public:
   FilesPatchRequest(RequestSender* sender,
                     const DriveApiUrlGenerator& url_generator,
@@ -263,7 +333,7 @@ class FilesPatchRequest : public DriveApiDataRequest {
 // This class performs the request for copying a resource.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/files/copy
-class FilesCopyRequest : public DriveApiDataRequest {
+class FilesCopyRequest : public DriveApiDataRequest<FileResource> {
  public:
   // Upon completion, |callback| will be called. |callback| must not be null.
   FilesCopyRequest(RequestSender* sender,
@@ -315,7 +385,7 @@ class FilesCopyRequest : public DriveApiDataRequest {
 // or by FilesListRequest with setting page token.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/files/list
-class FilesListRequest : public DriveApiDataRequest {
+class FilesListRequest : public DriveApiDataRequest<FileList> {
  public:
   FilesListRequest(RequestSender* sender,
                    const DriveApiUrlGenerator& url_generator,
@@ -353,7 +423,7 @@ class FilesListRequest : public DriveApiDataRequest {
 // 1) Set pageToken and all params used for the initial request.
 // 2) Use URL in the nextLink field in the previous response.
 // This class implements 2)'s request.
-class FilesListNextPageRequest : public DriveApiDataRequest {
+class FilesListNextPageRequest : public DriveApiDataRequest<FileList> {
  public:
   FilesListNextPageRequest(RequestSender* sender,
                            const FileListCallback& callback);
@@ -408,7 +478,7 @@ class FilesDeleteRequest : public EntryActionRequest {
 // This class performs the request for trashing a resource.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/files/trash
-class FilesTrashRequest : public DriveApiDataRequest {
+class FilesTrashRequest : public DriveApiDataRequest<FileResource> {
  public:
   FilesTrashRequest(RequestSender* sender,
                     const DriveApiUrlGenerator& url_generator,
@@ -438,7 +508,7 @@ class FilesTrashRequest : public DriveApiDataRequest {
 // This class performs the request for fetching About data.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/about/get
-class AboutGetRequest : public DriveApiDataRequest {
+class AboutGetRequest : public DriveApiDataRequest<AboutResource> {
  public:
   AboutGetRequest(RequestSender* sender,
                   const DriveApiUrlGenerator& url_generator,
@@ -463,7 +533,7 @@ class AboutGetRequest : public DriveApiDataRequest {
 // or by ChangesListRequest with setting page token.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/changes/list
-class ChangesListRequest : public DriveApiDataRequest {
+class ChangesListRequest : public DriveApiDataRequest<ChangeList> {
  public:
   ChangesListRequest(RequestSender* sender,
                      const DriveApiUrlGenerator& url_generator,
@@ -509,7 +579,7 @@ class ChangesListRequest : public DriveApiDataRequest {
 // 1) Set pageToken and all params used for the initial request.
 // 2) Use URL in the nextLink field in the previous response.
 // This class implements 2)'s request.
-class ChangesListNextPageRequest : public DriveApiDataRequest {
+class ChangesListNextPageRequest : public DriveApiDataRequest<ChangeList> {
  public:
   ChangesListNextPageRequest(RequestSender* sender,
                              const ChangeListCallback& callback);
@@ -533,7 +603,7 @@ class ChangesListNextPageRequest : public DriveApiDataRequest {
 // This class performs the request for fetching AppList.
 // This request is mapped to
 // https://developers.google.com/drive/v2/reference/apps/list
-class AppsListRequest : public DriveApiDataRequest {
+class AppsListRequest : public DriveApiDataRequest<AppList> {
  public:
   AppsListRequest(RequestSender* sender,
                   const DriveApiUrlGenerator& url_generator,