Home | History | Annotate | Download | only in api
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sync/api/sync_data.h"
      6 
      7 #include <ostream>
      8 
      9 #include "base/json/json_writer.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "base/values.h"
     13 #include "sync/internal_api/public/attachments/attachment_service_proxy.h"
     14 #include "sync/internal_api/public/base/model_type.h"
     15 #include "sync/internal_api/public/base_node.h"
     16 #include "sync/protocol/proto_value_conversions.h"
     17 #include "sync/protocol/sync.pb.h"
     18 
     19 namespace {
     20 
     21 sync_pb::AttachmentIdProto IdToProto(
     22     const syncer::AttachmentId& attachment_id) {
     23   return attachment_id.GetProto();
     24 }
     25 
     26 syncer::AttachmentId ProtoToId(const sync_pb::AttachmentIdProto& proto) {
     27   return syncer::AttachmentId::CreateFromProto(proto);
     28 }
     29 
     30 // Return true iff |attachment_ids| contains duplicates.
     31 bool ContainsDuplicateAttachments(
     32     const syncer::AttachmentIdList& attachment_ids) {
     33   syncer::AttachmentIdSet id_set;
     34   id_set.insert(attachment_ids.begin(), attachment_ids.end());
     35   return id_set.size() != attachment_ids.size();
     36 }
     37 
     38 }  // namespace
     39 
     40 namespace syncer {
     41 
     42 void SyncData::ImmutableSyncEntityTraits::InitializeWrapper(Wrapper* wrapper) {
     43   *wrapper = new sync_pb::SyncEntity();
     44 }
     45 
     46 void SyncData::ImmutableSyncEntityTraits::DestroyWrapper(Wrapper* wrapper) {
     47   delete *wrapper;
     48 }
     49 
     50 const sync_pb::SyncEntity& SyncData::ImmutableSyncEntityTraits::Unwrap(
     51     const Wrapper& wrapper) {
     52   return *wrapper;
     53 }
     54 
     55 sync_pb::SyncEntity* SyncData::ImmutableSyncEntityTraits::UnwrapMutable(
     56     Wrapper* wrapper) {
     57   return *wrapper;
     58 }
     59 
     60 void SyncData::ImmutableSyncEntityTraits::Swap(sync_pb::SyncEntity* t1,
     61                                                sync_pb::SyncEntity* t2) {
     62   t1->Swap(t2);
     63 }
     64 
     65 SyncData::SyncData() : id_(kInvalidId), is_valid_(false) {}
     66 
     67 SyncData::SyncData(int64 id,
     68                    sync_pb::SyncEntity* entity,
     69                    const base::Time& remote_modification_time,
     70                    const syncer::AttachmentServiceProxy& attachment_service)
     71     : id_(id),
     72       remote_modification_time_(remote_modification_time),
     73       immutable_entity_(entity),
     74       attachment_service_(attachment_service),
     75       is_valid_(true) {}
     76 
     77 SyncData::~SyncData() {}
     78 
     79 // Static.
     80 SyncData SyncData::CreateLocalDelete(const std::string& sync_tag,
     81                                      ModelType datatype) {
     82   sync_pb::EntitySpecifics specifics;
     83   AddDefaultFieldValue(datatype, &specifics);
     84   return CreateLocalData(sync_tag, std::string(), specifics);
     85 }
     86 
     87 // Static.
     88 SyncData SyncData::CreateLocalData(const std::string& sync_tag,
     89                                    const std::string& non_unique_title,
     90                                    const sync_pb::EntitySpecifics& specifics) {
     91   syncer::AttachmentIdList attachment_ids;
     92   return CreateLocalDataWithAttachments(
     93       sync_tag, non_unique_title, specifics, attachment_ids);
     94 }
     95 
     96 // Static.
     97 SyncData SyncData::CreateLocalDataWithAttachments(
     98     const std::string& sync_tag,
     99     const std::string& non_unique_title,
    100     const sync_pb::EntitySpecifics& specifics,
    101     const AttachmentIdList& attachment_ids) {
    102   DCHECK(!ContainsDuplicateAttachments(attachment_ids));
    103   sync_pb::SyncEntity entity;
    104   entity.set_client_defined_unique_tag(sync_tag);
    105   entity.set_non_unique_name(non_unique_title);
    106   entity.mutable_specifics()->CopyFrom(specifics);
    107   std::transform(attachment_ids.begin(),
    108                  attachment_ids.end(),
    109                  RepeatedFieldBackInserter(entity.mutable_attachment_id()),
    110                  IdToProto);
    111   return SyncData(kInvalidId,
    112                   &entity,
    113                   base::Time(),
    114                   AttachmentServiceProxy());
    115 }
    116 
    117 // Static.
    118 SyncData SyncData::CreateRemoteData(
    119     int64 id,
    120     const sync_pb::EntitySpecifics& specifics,
    121     const base::Time& modification_time,
    122     const AttachmentIdList& attachment_ids,
    123     const AttachmentServiceProxy& attachment_service) {
    124   DCHECK_NE(id, kInvalidId);
    125   sync_pb::SyncEntity entity;
    126   entity.mutable_specifics()->CopyFrom(specifics);
    127   std::transform(attachment_ids.begin(),
    128                  attachment_ids.end(),
    129                  RepeatedFieldBackInserter(entity.mutable_attachment_id()),
    130                  IdToProto);
    131   return SyncData(id, &entity, modification_time, attachment_service);
    132 }
    133 
    134 bool SyncData::IsValid() const { return is_valid_; }
    135 
    136 const sync_pb::EntitySpecifics& SyncData::GetSpecifics() const {
    137   return immutable_entity_.Get().specifics();
    138 }
    139 
    140 ModelType SyncData::GetDataType() const {
    141   return GetModelTypeFromSpecifics(GetSpecifics());
    142 }
    143 
    144 const std::string& SyncData::GetTitle() const {
    145   // TODO(zea): set this for data coming from the syncer too.
    146   DCHECK(immutable_entity_.Get().has_non_unique_name());
    147   return immutable_entity_.Get().non_unique_name();
    148 }
    149 
    150 bool SyncData::IsLocal() const { return id_ == kInvalidId; }
    151 
    152 std::string SyncData::ToString() const {
    153   if (!IsValid())
    154     return "<Invalid SyncData>";
    155 
    156   std::string type = ModelTypeToString(GetDataType());
    157   std::string specifics;
    158   scoped_ptr<base::DictionaryValue> value(
    159       EntitySpecificsToValue(GetSpecifics()));
    160   base::JSONWriter::WriteWithOptions(
    161       value.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &specifics);
    162 
    163   if (IsLocal()) {
    164     SyncDataLocal sync_data_local(*this);
    165     return "{ isLocal: true, type: " + type + ", tag: " +
    166            sync_data_local.GetTag() + ", title: " + GetTitle() +
    167            ", specifics: " + specifics + "}";
    168   }
    169 
    170   SyncDataRemote sync_data_remote(*this);
    171   std::string id = base::Int64ToString(sync_data_remote.GetId());
    172   return "{ isLocal: false, type: " + type + ", specifics: " + specifics +
    173          ", id: " + id + "}";
    174 }
    175 
    176 void PrintTo(const SyncData& sync_data, std::ostream* os) {
    177   *os << sync_data.ToString();
    178 }
    179 
    180 AttachmentIdList SyncData::GetAttachmentIds() const {
    181   AttachmentIdList result;
    182   const sync_pb::SyncEntity& entity = immutable_entity_.Get();
    183   std::transform(entity.attachment_id().begin(),
    184                  entity.attachment_id().end(),
    185                  std::back_inserter(result),
    186                  ProtoToId);
    187   return result;
    188 }
    189 
    190 SyncDataLocal::SyncDataLocal(const SyncData& sync_data) : SyncData(sync_data) {
    191   DCHECK(sync_data.IsLocal());
    192 }
    193 
    194 SyncDataLocal::~SyncDataLocal() {}
    195 
    196 const std::string& SyncDataLocal::GetTag() const {
    197   return immutable_entity_.Get().client_defined_unique_tag();
    198 }
    199 
    200 SyncDataRemote::SyncDataRemote(const SyncData& sync_data)
    201     : SyncData(sync_data) {
    202   DCHECK(!sync_data.IsLocal());
    203 }
    204 
    205 SyncDataRemote::~SyncDataRemote() {}
    206 
    207 const base::Time& SyncDataRemote::GetModifiedTime() const {
    208   return remote_modification_time_;
    209 }
    210 
    211 int64 SyncDataRemote::GetId() const {
    212   return id_;
    213 }
    214 
    215 void SyncDataRemote::GetOrDownloadAttachments(
    216     const AttachmentIdList& attachment_ids,
    217     const AttachmentService::GetOrDownloadCallback& callback) {
    218   attachment_service_.GetOrDownloadAttachments(attachment_ids, callback);
    219 }
    220 
    221 void SyncDataRemote::DropAttachments(
    222     const AttachmentIdList& attachment_ids,
    223     const AttachmentService::DropCallback& callback) {
    224   attachment_service_.DropAttachments(attachment_ids, callback);
    225 }
    226 
    227 }  // namespace syncer
    228