Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / sync / api / sync_data.cc
index d52e04e..35a21f9 100644 (file)
 #include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "sync/api/attachments/attachment_service_proxy.h"
 #include "sync/internal_api/public/base/model_type.h"
 #include "sync/internal_api/public/base_node.h"
 #include "sync/protocol/proto_value_conversions.h"
 #include "sync/protocol/sync.pb.h"
 
+using syncer::Attachment;
+using syncer::AttachmentIdList;
+using syncer::AttachmentList;
+
+namespace {
+
+sync_pb::AttachmentIdProto AttachmentToProto(
+    const syncer::Attachment& attachment) {
+  return attachment.GetId().GetProto();
+}
+
+sync_pb::AttachmentIdProto IdToProto(
+    const syncer::AttachmentId& attachment_id) {
+  return attachment_id.GetProto();
+}
+
+syncer::AttachmentId ProtoToId(const sync_pb::AttachmentIdProto& proto) {
+  return syncer::AttachmentId::CreateFromProto(proto);
+}
+
+// Return true iff |attachments| contains one or more elements with the same
+// AttachmentId.
+bool ContainsDuplicateAttachments(const syncer::AttachmentList& attachments) {
+  std::set<syncer::AttachmentId> id_set;
+  AttachmentList::const_iterator iter = attachments.begin();
+  AttachmentList::const_iterator end = attachments.end();
+  for (; iter != end; ++iter) {
+    if (id_set.find(iter->GetId()) != id_set.end()) {
+      return true;
+    }
+    id_set.insert(iter->GetId());
+  }
+  return false;
+}
+
+}  // namespace
+
 namespace syncer {
 
-void SyncData::ImmutableSyncEntityTraits::InitializeWrapper(
-    Wrapper* wrapper) {
+void SyncData::ImmutableSyncEntityTraits::InitializeWrapper(Wrapper* wrapper) {
   *wrapper = new sync_pb::SyncEntity();
 }
 
-void SyncData::ImmutableSyncEntityTraits::DestroyWrapper(
-    Wrapper* wrapper) {
+void SyncData::ImmutableSyncEntityTraits::DestroyWrapper(Wrapper* wrapper) {
   delete *wrapper;
 }
 
@@ -42,54 +78,82 @@ void SyncData::ImmutableSyncEntityTraits::Swap(sync_pb::SyncEntity* t1,
   t1->Swap(t2);
 }
 
-SyncData::SyncData()
-    : is_valid_(false),
-      id_(kInvalidId) {}
+SyncData::SyncData() : id_(kInvalidId), is_valid_(false) {}
 
 SyncData::SyncData(int64 id,
                    sync_pb::SyncEntity* entity,
-                   const base::Time& remote_modification_time)
-    : is_valid_(true),
-      id_(id),
+                   AttachmentList* attachments,
+                   const base::Time& remote_modification_time,
+                   const syncer::AttachmentServiceProxy& attachment_service)
+    : id_(id),
       remote_modification_time_(remote_modification_time),
-      immutable_entity_(entity) {}
+      immutable_entity_(entity),
+      attachments_(attachments),
+      attachment_service_(attachment_service),
+      is_valid_(true) {}
 
 SyncData::~SyncData() {}
 
 // Static.
-SyncData SyncData::CreateLocalDelete(
-    const std::string& sync_tag,
-    ModelType datatype) {
+SyncData SyncData::CreateLocalDelete(const std::string& sync_tag,
+                                     ModelType datatype) {
   sync_pb::EntitySpecifics specifics;
   AddDefaultFieldValue(datatype, &specifics);
   return CreateLocalData(sync_tag, std::string(), specifics);
 }
 
 // Static.
-SyncData SyncData::CreateLocalData(
+SyncData SyncData::CreateLocalData(const std::string& sync_tag,
+                                   const std::string& non_unique_title,
+                                   const sync_pb::EntitySpecifics& specifics) {
+  syncer::AttachmentList attachments;
+  return CreateLocalDataWithAttachments(
+      sync_tag, non_unique_title, specifics, attachments);
+}
+
+// Static.
+SyncData SyncData::CreateLocalDataWithAttachments(
     const std::string& sync_tag,
     const std::string& non_unique_title,
-    const sync_pb::EntitySpecifics& specifics) {
+    const sync_pb::EntitySpecifics& specifics,
+    const AttachmentList& attachments) {
+  DCHECK(!ContainsDuplicateAttachments(attachments));
   sync_pb::SyncEntity entity;
   entity.set_client_defined_unique_tag(sync_tag);
   entity.set_non_unique_name(non_unique_title);
   entity.mutable_specifics()->CopyFrom(specifics);
-  return SyncData(kInvalidId, &entity, base::Time());
+  std::transform(attachments.begin(),
+                 attachments.end(),
+                 RepeatedFieldBackInserter(entity.mutable_attachment_id()),
+                 AttachmentToProto);
+  AttachmentList copy_of_attachments(attachments);
+  return SyncData(kInvalidId,
+                  &entity,
+                  &copy_of_attachments,
+                  base::Time(),
+                  AttachmentServiceProxy());
 }
 
 // Static.
 SyncData SyncData::CreateRemoteData(
-    int64 id, const sync_pb::EntitySpecifics& specifics,
-    const base::Time& modification_time) {
+    int64 id,
+    const sync_pb::EntitySpecifics& specifics,
+    const base::Time& modification_time,
+    const AttachmentIdList& attachment_ids,
+    const AttachmentServiceProxy& attachment_service) {
   DCHECK_NE(id, kInvalidId);
   sync_pb::SyncEntity entity;
   entity.mutable_specifics()->CopyFrom(specifics);
-  return SyncData(id, &entity, modification_time);
+  std::transform(attachment_ids.begin(),
+                 attachment_ids.end(),
+                 RepeatedFieldBackInserter(entity.mutable_attachment_id()),
+                 IdToProto);
+  AttachmentList attachments;
+  return SyncData(
+      id, &entity, &attachments, modification_time, attachment_service);
 }
 
-bool SyncData::IsValid() const {
-  return is_valid_;
-}
+bool SyncData::IsValid() const { return is_valid_; }
 
 const sync_pb::EntitySpecifics& SyncData::GetSpecifics() const {
   return immutable_entity_.Get().specifics();
@@ -99,30 +163,13 @@ ModelType SyncData::GetDataType() const {
   return GetModelTypeFromSpecifics(GetSpecifics());
 }
 
-const std::string& SyncData::GetTag() const {
-  DCHECK(IsLocal());
-  return immutable_entity_.Get().client_defined_unique_tag();
-}
-
 const std::string& SyncData::GetTitle() const {
   // TODO(zea): set this for data coming from the syncer too.
   DCHECK(immutable_entity_.Get().has_non_unique_name());
   return immutable_entity_.Get().non_unique_name();
 }
 
-const base::Time& SyncData::GetRemoteModifiedTime() const {
-  DCHECK(!IsLocal());
-  return remote_modification_time_;
-}
-
-int64 SyncData::GetRemoteId() const {
-  DCHECK(!IsLocal());
-  return id_;
-}
-
-bool SyncData::IsLocal() const {
-  return id_ == kInvalidId;
-}
+bool SyncData::IsLocal() const { return id_ == kInvalidId; }
 
 std::string SyncData::ToString() const {
   if (!IsValid())
@@ -132,22 +179,75 @@ std::string SyncData::ToString() const {
   std::string specifics;
   scoped_ptr<base::DictionaryValue> value(
       EntitySpecificsToValue(GetSpecifics()));
-  base::JSONWriter::WriteWithOptions(value.get(),
-                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
-                                     &specifics);
+  base::JSONWriter::WriteWithOptions(
+      value.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &specifics);
 
   if (IsLocal()) {
-    return "{ isLocal: true, type: " + type + ", tag: " + GetTag() +
-        ", title: " + GetTitle() + ", specifics: " + specifics + "}";
+    SyncDataLocal sync_data_local(*this);
+    return "{ isLocal: true, type: " + type + ", tag: " +
+           sync_data_local.GetTag() + ", title: " + GetTitle() +
+           ", specifics: " + specifics + "}";
   }
 
-  std::string id = base::Int64ToString(GetRemoteId());
+  SyncDataRemote sync_data_remote(*this);
+  std::string id = base::Int64ToString(sync_data_remote.GetId());
   return "{ isLocal: false, type: " + type + ", specifics: " + specifics +
-      ", id: " + id + "}";
+         ", id: " + id + "}";
 }
 
 void PrintTo(const SyncData& sync_data, std::ostream* os) {
   *os << sync_data.ToString();
 }
 
+AttachmentIdList SyncData::GetAttachmentIds() const {
+  AttachmentIdList result;
+  const sync_pb::SyncEntity& entity = immutable_entity_.Get();
+  std::transform(entity.attachment_id().begin(),
+                 entity.attachment_id().end(),
+                 std::back_inserter(result),
+                 ProtoToId);
+  return result;
+}
+
+SyncDataLocal::SyncDataLocal(const SyncData& sync_data) : SyncData(sync_data) {
+  DCHECK(sync_data.IsLocal());
+}
+
+SyncDataLocal::~SyncDataLocal() {}
+
+const AttachmentList& SyncDataLocal::GetLocalAttachmentsForUpload() const {
+  return attachments_.Get();
+}
+
+const std::string& SyncDataLocal::GetTag() const {
+  return immutable_entity_.Get().client_defined_unique_tag();
+}
+
+SyncDataRemote::SyncDataRemote(const SyncData& sync_data)
+    : SyncData(sync_data) {
+  DCHECK(!sync_data.IsLocal());
+}
+
+SyncDataRemote::~SyncDataRemote() {}
+
+const base::Time& SyncDataRemote::GetModifiedTime() const {
+  return remote_modification_time_;
+}
+
+int64 SyncDataRemote::GetId() const {
+  return id_;
+}
+
+void SyncDataRemote::GetOrDownloadAttachments(
+    const AttachmentIdList& attachment_ids,
+    const AttachmentService::GetOrDownloadCallback& callback) {
+  attachment_service_.GetOrDownloadAttachments(attachment_ids, callback);
+}
+
+void SyncDataRemote::DropAttachments(
+    const AttachmentIdList& attachment_ids,
+    const AttachmentService::DropCallback& callback) {
+  attachment_service_.DropAttachments(attachment_ids, callback);
+}
+
 }  // namespace syncer