// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "google_apis/drive/drive_api_requests.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/json/json_writer.h"
#include "base/location.h"
#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"
#include "net/base/url_util.h"
namespace google_apis {
namespace {
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
// remaining response type.
void ParseFileResourceWithUploadRangeAndRun(
const drive::UploadRangeCallback& callback,
const UploadRangeResponse& response,
scoped_ptr<base::Value> value) {
DCHECK(!callback.is_null());
scoped_ptr<FileResource> file_resource;
if (value) {
file_resource = FileResource::CreateFrom(*value);
if (!file_resource) {
callback.Run(
UploadRangeResponse(GDATA_PARSE_ERROR,
response.start_position_received,
response.end_position_received),
scoped_ptr<FileResource>());
return;
}
}
callback.Run(response, file_resource.Pass());
}
// Creates a Parents value which can be used as a part of request body.
scoped_ptr<base::DictionaryValue> CreateParentValue(
const std::string& file_id) {
scoped_ptr<base::DictionaryValue> parent(new base::DictionaryValue);
parent->SetString("kind", kParentLinkKind);
parent->SetString("id", file_id);
return parent.Pass();
}
} // namespace
namespace drive {
//============================ DriveApiDataRequest ===========================
DriveApiDataRequest::DriveApiDataRequest(RequestSender* sender,
const GetDataCallback& callback)
: GetDataRequest(sender, callback) {
}
DriveApiDataRequest::~DriveApiDataRequest() {
}
GURL DriveApiDataRequest::GetURL() const {
GURL url = GetURLInternal();
if (!fields_.empty())
url = net::AppendOrReplaceQueryParameter(url, "fields", fields_);
return url;
}
//=============================== FilesGetRequest =============================
FilesGetRequest::FilesGetRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesGetRequest::~FilesGetRequest() {}
GURL FilesGetRequest::GetURLInternal() const {
return url_generator_.GetFilesGetUrl(file_id_);
}
//============================ FilesAuthorizeRequest ===========================
FilesAuthorizeRequest::FilesAuthorizeRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesAuthorizeRequest::~FilesAuthorizeRequest() {}
net::URLFetcher::RequestType FilesAuthorizeRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
GURL FilesAuthorizeRequest::GetURLInternal() const {
return url_generator_.GetFilesAuthorizeUrl(file_id_, app_id_);
}
//============================ FilesInsertRequest ============================
FilesInsertRequest::FilesInsertRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesInsertRequest::~FilesInsertRequest() {}
net::URLFetcher::RequestType FilesInsertRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
bool FilesInsertRequest::GetContentData(std::string* upload_content_type,
std::string* upload_content) {
*upload_content_type = kContentTypeApplicationJson;
base::DictionaryValue root;
if (!last_viewed_by_me_date_.is_null()) {
root.SetString("lastViewedByMeDate",
util::FormatTimeAsString(last_viewed_by_me_date_));
}
if (!mime_type_.empty())
root.SetString("mimeType", mime_type_);
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
if (!parents_.empty()) {
base::ListValue* parents_value = new base::ListValue;
for (size_t i = 0; i < parents_.size(); ++i) {
base::DictionaryValue* parent = new base::DictionaryValue;
parent->SetString("id", parents_[i]);
parents_value->Append(parent);
}
root.Set("parents", parents_value);
}
if (!title_.empty())
root.SetString("title", title_);
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "FilesInsert data: " << *upload_content_type << ", ["
<< *upload_content << "]";
return true;
}
GURL FilesInsertRequest::GetURLInternal() const {
return url_generator_.GetFilesInsertUrl();
}
//============================== FilesPatchRequest ============================
FilesPatchRequest::FilesPatchRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator),
set_modified_date_(false),
update_viewed_date_(true) {
DCHECK(!callback.is_null());
}
FilesPatchRequest::~FilesPatchRequest() {}
net::URLFetcher::RequestType FilesPatchRequest::GetRequestType() const {
return net::URLFetcher::PATCH;
}
std::vector<std::string> FilesPatchRequest::GetExtraRequestHeaders() const {
std::vector<std::string> headers;
headers.push_back(util::kIfMatchAllHeader);
return headers;
}
GURL FilesPatchRequest::GetURLInternal() const {
return url_generator_.GetFilesPatchUrl(
file_id_, set_modified_date_, update_viewed_date_);
}
bool FilesPatchRequest::GetContentData(std::string* upload_content_type,
std::string* upload_content) {
if (title_.empty() &&
modified_date_.is_null() &&
last_viewed_by_me_date_.is_null() &&
parents_.empty())
return false;
*upload_content_type = kContentTypeApplicationJson;
base::DictionaryValue root;
if (!title_.empty())
root.SetString("title", title_);
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
if (!last_viewed_by_me_date_.is_null()) {
root.SetString("lastViewedByMeDate",
util::FormatTimeAsString(last_viewed_by_me_date_));
}
if (!parents_.empty()) {
base::ListValue* parents_value = new base::ListValue;
for (size_t i = 0; i < parents_.size(); ++i) {
base::DictionaryValue* parent = new base::DictionaryValue;
parent->SetString("id", parents_[i]);
parents_value->Append(parent);
}
root.Set("parents", parents_value);
}
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "FilesPatch data: " << *upload_content_type << ", ["
<< *upload_content << "]";
return true;
}
//============================= FilesCopyRequest ==============================
FilesCopyRequest::FilesCopyRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesCopyRequest::~FilesCopyRequest() {
}
net::URLFetcher::RequestType FilesCopyRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
GURL FilesCopyRequest::GetURLInternal() const {
return url_generator_.GetFilesCopyUrl(file_id_);
}
bool FilesCopyRequest::GetContentData(std::string* upload_content_type,
std::string* upload_content) {
if (parents_.empty() && title_.empty())
return false;
*upload_content_type = kContentTypeApplicationJson;
base::DictionaryValue root;
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
if (!parents_.empty()) {
base::ListValue* parents_value = new base::ListValue;
for (size_t i = 0; i < parents_.size(); ++i) {
base::DictionaryValue* parent = new base::DictionaryValue;
parent->SetString("id", parents_[i]);
parents_value->Append(parent);
}
root.Set("parents", parents_value);
}
if (!title_.empty())
root.SetString("title", title_);
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "FilesCopy data: " << *upload_content_type << ", ["
<< *upload_content << "]";
return true;
}
//============================= FilesListRequest =============================
FilesListRequest::FilesListRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileListCallback& 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());
}
FilesListRequest::~FilesListRequest() {}
GURL FilesListRequest::GetURLInternal() const {
return url_generator_.GetFilesListUrl(max_results_, page_token_, q_);
}
//======================== FilesListNextPageRequest =========================
FilesListNextPageRequest::FilesListNextPageRequest(
RequestSender* sender,
const FileListCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonOnBlockingPoolAndRun<FileList>,
make_scoped_refptr(sender->blocking_task_runner()),
callback)) {
DCHECK(!callback.is_null());
}
FilesListNextPageRequest::~FilesListNextPageRequest() {
}
GURL FilesListNextPageRequest::GetURLInternal() const {
return next_link_;
}
//============================ FilesDeleteRequest =============================
FilesDeleteRequest::FilesDeleteRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const EntryActionCallback& callback)
: EntryActionRequest(sender, callback),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesDeleteRequest::~FilesDeleteRequest() {}
net::URLFetcher::RequestType FilesDeleteRequest::GetRequestType() const {
return net::URLFetcher::DELETE_REQUEST;
}
GURL FilesDeleteRequest::GetURL() const {
return url_generator_.GetFilesDeleteUrl(file_id_);
}
std::vector<std::string> FilesDeleteRequest::GetExtraRequestHeaders() const {
std::vector<std::string> headers(
EntryActionRequest::GetExtraRequestHeaders());
headers.push_back(util::GenerateIfMatchHeader(etag_));
return headers;
}
//============================ FilesTrashRequest =============================
FilesTrashRequest::FilesTrashRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const FileResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<FileResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
FilesTrashRequest::~FilesTrashRequest() {}
net::URLFetcher::RequestType FilesTrashRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
GURL FilesTrashRequest::GetURLInternal() const {
return url_generator_.GetFilesTrashUrl(file_id_);
}
//============================== AboutGetRequest =============================
AboutGetRequest::AboutGetRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const AboutResourceCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<AboutResource>, callback)),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
AboutGetRequest::~AboutGetRequest() {}
GURL AboutGetRequest::GetURLInternal() const {
return url_generator_.GetAboutGetUrl();
}
//============================ ChangesListRequest ===========================
ChangesListRequest::ChangesListRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const ChangeListCallback& 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),
start_change_id_(0) {
DCHECK(!callback.is_null());
}
ChangesListRequest::~ChangesListRequest() {}
GURL ChangesListRequest::GetURLInternal() const {
return url_generator_.GetChangesListUrl(
include_deleted_, max_results_, page_token_, start_change_id_);
}
//======================== ChangesListNextPageRequest =========================
ChangesListNextPageRequest::ChangesListNextPageRequest(
RequestSender* sender,
const ChangeListCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonOnBlockingPoolAndRun<ChangeList>,
make_scoped_refptr(sender->blocking_task_runner()),
callback)) {
DCHECK(!callback.is_null());
}
ChangesListNextPageRequest::~ChangesListNextPageRequest() {
}
GURL ChangesListNextPageRequest::GetURLInternal() const {
return next_link_;
}
//============================== AppsListRequest ===========================
AppsListRequest::AppsListRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
bool use_internal_endpoint,
const AppListCallback& callback)
: DriveApiDataRequest(
sender,
base::Bind(&ParseJsonAndRun<AppList>, callback)),
url_generator_(url_generator),
use_internal_endpoint_(use_internal_endpoint) {
DCHECK(!callback.is_null());
}
AppsListRequest::~AppsListRequest() {}
GURL AppsListRequest::GetURLInternal() const {
return url_generator_.GetAppsListUrl(use_internal_endpoint_);
}
//============================== AppsDeleteRequest ===========================
AppsDeleteRequest::AppsDeleteRequest(RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const EntryActionCallback& callback)
: EntryActionRequest(sender, callback),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
AppsDeleteRequest::~AppsDeleteRequest() {}
net::URLFetcher::RequestType AppsDeleteRequest::GetRequestType() const {
return net::URLFetcher::DELETE_REQUEST;
}
GURL AppsDeleteRequest::GetURL() const {
return url_generator_.GetAppsDeleteUrl(app_id_);
}
//========================== ChildrenInsertRequest ============================
ChildrenInsertRequest::ChildrenInsertRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const EntryActionCallback& callback)
: EntryActionRequest(sender, callback),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
ChildrenInsertRequest::~ChildrenInsertRequest() {}
net::URLFetcher::RequestType ChildrenInsertRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
GURL ChildrenInsertRequest::GetURL() const {
return url_generator_.GetChildrenInsertUrl(folder_id_);
}
bool ChildrenInsertRequest::GetContentData(std::string* upload_content_type,
std::string* upload_content) {
*upload_content_type = kContentTypeApplicationJson;
base::DictionaryValue root;
root.SetString("id", id_);
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "InsertResource data: " << *upload_content_type << ", ["
<< *upload_content << "]";
return true;
}
//========================== ChildrenDeleteRequest ============================
ChildrenDeleteRequest::ChildrenDeleteRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const EntryActionCallback& callback)
: EntryActionRequest(sender, callback),
url_generator_(url_generator) {
DCHECK(!callback.is_null());
}
ChildrenDeleteRequest::~ChildrenDeleteRequest() {}
net::URLFetcher::RequestType ChildrenDeleteRequest::GetRequestType() const {
return net::URLFetcher::DELETE_REQUEST;
}
GURL ChildrenDeleteRequest::GetURL() const {
return url_generator_.GetChildrenDeleteUrl(child_id_, folder_id_);
}
//======================= InitiateUploadNewFileRequest =======================
InitiateUploadNewFileRequest::InitiateUploadNewFileRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const std::string& content_type,
int64 content_length,
const std::string& parent_resource_id,
const std::string& title,
const InitiateUploadCallback& callback)
: InitiateUploadRequestBase(sender,
callback,
content_type,
content_length),
url_generator_(url_generator),
parent_resource_id_(parent_resource_id),
title_(title) {
}
InitiateUploadNewFileRequest::~InitiateUploadNewFileRequest() {}
GURL InitiateUploadNewFileRequest::GetURL() const {
return url_generator_.GetInitiateUploadNewFileUrl(!modified_date_.is_null());
}
net::URLFetcher::RequestType
InitiateUploadNewFileRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
bool InitiateUploadNewFileRequest::GetContentData(
std::string* upload_content_type,
std::string* upload_content) {
*upload_content_type = kContentTypeApplicationJson;
base::DictionaryValue root;
root.SetString("title", title_);
// Fill parent link.
scoped_ptr<base::ListValue> parents(new base::ListValue);
parents->Append(CreateParentValue(parent_resource_id_).release());
root.Set("parents", parents.release());
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
if (!last_viewed_by_me_date_.is_null()) {
root.SetString("lastViewedByMeDate",
util::FormatTimeAsString(last_viewed_by_me_date_));
}
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "InitiateUploadNewFile data: " << *upload_content_type << ", ["
<< *upload_content << "]";
return true;
}
//===================== InitiateUploadExistingFileRequest ====================
InitiateUploadExistingFileRequest::InitiateUploadExistingFileRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const std::string& content_type,
int64 content_length,
const std::string& resource_id,
const std::string& etag,
const InitiateUploadCallback& callback)
: InitiateUploadRequestBase(sender,
callback,
content_type,
content_length),
url_generator_(url_generator),
resource_id_(resource_id),
etag_(etag) {
}
InitiateUploadExistingFileRequest::~InitiateUploadExistingFileRequest() {}
GURL InitiateUploadExistingFileRequest::GetURL() const {
return url_generator_.GetInitiateUploadExistingFileUrl(
resource_id_, !modified_date_.is_null());
}
net::URLFetcher::RequestType
InitiateUploadExistingFileRequest::GetRequestType() const {
return net::URLFetcher::PUT;
}
std::vector<std::string>
InitiateUploadExistingFileRequest::GetExtraRequestHeaders() const {
std::vector<std::string> headers(
InitiateUploadRequestBase::GetExtraRequestHeaders());
headers.push_back(util::GenerateIfMatchHeader(etag_));
return headers;
}
bool InitiateUploadExistingFileRequest::GetContentData(
std::string* upload_content_type,
std::string* upload_content) {
base::DictionaryValue root;
if (!parent_resource_id_.empty()) {
scoped_ptr<base::ListValue> parents(new base::ListValue);
parents->Append(CreateParentValue(parent_resource_id_).release());
root.Set("parents", parents.release());
}
if (!title_.empty())
root.SetString("title", title_);
if (!modified_date_.is_null())
root.SetString("modifiedDate", util::FormatTimeAsString(modified_date_));
if (!last_viewed_by_me_date_.is_null()) {
root.SetString("lastViewedByMeDate",
util::FormatTimeAsString(last_viewed_by_me_date_));
}
if (root.empty())
return false;
*upload_content_type = kContentTypeApplicationJson;
base::JSONWriter::Write(&root, upload_content);
DVLOG(1) << "InitiateUploadExistingFile data: " << *upload_content_type
<< ", [" << *upload_content << "]";
return true;
}
//============================ ResumeUploadRequest ===========================
ResumeUploadRequest::ResumeUploadRequest(
RequestSender* sender,
const GURL& upload_location,
int64 start_position,
int64 end_position,
int64 content_length,
const std::string& content_type,
const base::FilePath& local_file_path,
const UploadRangeCallback& callback,
const ProgressCallback& progress_callback)
: ResumeUploadRequestBase(sender,
upload_location,
start_position,
end_position,
content_length,
content_type,
local_file_path),
callback_(callback),
progress_callback_(progress_callback) {
DCHECK(!callback_.is_null());
}
ResumeUploadRequest::~ResumeUploadRequest() {}
void ResumeUploadRequest::OnRangeRequestComplete(
const UploadRangeResponse& response,
scoped_ptr<base::Value> value) {
DCHECK(CalledOnValidThread());
ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass());
}
void ResumeUploadRequest::OnURLFetchUploadProgress(
const net::URLFetcher* source, int64 current, int64 total) {
if (!progress_callback_.is_null())
progress_callback_.Run(current, total);
}
//========================== GetUploadStatusRequest ==========================
GetUploadStatusRequest::GetUploadStatusRequest(
RequestSender* sender,
const GURL& upload_url,
int64 content_length,
const UploadRangeCallback& callback)
: GetUploadStatusRequestBase(sender,
upload_url,
content_length),
callback_(callback) {
DCHECK(!callback.is_null());
}
GetUploadStatusRequest::~GetUploadStatusRequest() {}
void GetUploadStatusRequest::OnRangeRequestComplete(
const UploadRangeResponse& response,
scoped_ptr<base::Value> value) {
DCHECK(CalledOnValidThread());
ParseFileResourceWithUploadRangeAndRun(callback_, response, value.Pass());
}
//========================== DownloadFileRequest ==========================
DownloadFileRequest::DownloadFileRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const std::string& resource_id,
const base::FilePath& output_file_path,
const DownloadActionCallback& download_action_callback,
const GetContentCallback& get_content_callback,
const ProgressCallback& progress_callback)
: DownloadFileRequestBase(
sender,
download_action_callback,
get_content_callback,
progress_callback,
url_generator.GenerateDownloadFileUrl(resource_id),
output_file_path) {
}
DownloadFileRequest::~DownloadFileRequest() {
}
//========================== PermissionsInsertRequest ==========================
PermissionsInsertRequest::PermissionsInsertRequest(
RequestSender* sender,
const DriveApiUrlGenerator& url_generator,
const EntryActionCallback& callback)
: EntryActionRequest(sender, callback),
url_generator_(url_generator),
type_(PERMISSION_TYPE_USER),
role_(PERMISSION_ROLE_READER) {
}
PermissionsInsertRequest::~PermissionsInsertRequest() {
}
GURL PermissionsInsertRequest::GetURL() const {
return url_generator_.GetPermissionsInsertUrl(id_);
}
net::URLFetcher::RequestType
PermissionsInsertRequest::GetRequestType() const {
return net::URLFetcher::POST;
}
bool PermissionsInsertRequest::GetContentData(std::string* upload_content_type,
std::string* upload_content) {
*upload_content_type = kContentTypeApplicationJson;
base::DictionaryValue root;
switch (type_) {
case PERMISSION_TYPE_ANYONE:
root.SetString("type", "anyone");
break;
case PERMISSION_TYPE_DOMAIN:
root.SetString("type", "domain");
break;
case PERMISSION_TYPE_GROUP:
root.SetString("type", "group");
break;
case PERMISSION_TYPE_USER:
root.SetString("type", "user");
break;
}
switch (role_) {
case PERMISSION_ROLE_OWNER:
root.SetString("role", "owner");
break;
case PERMISSION_ROLE_READER:
root.SetString("role", "reader");
break;
case PERMISSION_ROLE_WRITER:
root.SetString("role", "writer");
break;
case PERMISSION_ROLE_COMMENTER:
root.SetString("role", "reader");
{
base::ListValue* list = new base::ListValue;
list->AppendString("commenter");
root.Set("additionalRoles", list);
}
break;
}
root.SetString("value", value_);
base::JSONWriter::Write(&root, upload_content);
return true;
}
} // namespace drive
} // namespace google_apis