Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / sync / api / sync_data.cc
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