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.
5 #include "sync/api/sync_data.h"
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/api/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"
19 using syncer::Attachment
;
20 using syncer::AttachmentIdList
;
21 using syncer::AttachmentList
;
25 sync_pb::AttachmentIdProto
AttachmentToProto(
26 const syncer::Attachment
& attachment
) {
27 return attachment
.GetId().GetProto();
30 sync_pb::AttachmentIdProto
IdToProto(
31 const syncer::AttachmentId
& attachment_id
) {
32 return attachment_id
.GetProto();
35 syncer::AttachmentId
ProtoToId(const sync_pb::AttachmentIdProto
& proto
) {
36 return syncer::AttachmentId::CreateFromProto(proto
);
39 // Return true iff |attachments| contains one or more elements with the same
41 bool ContainsDuplicateAttachments(const syncer::AttachmentList
& attachments
) {
42 std::set
<syncer::AttachmentId
> id_set
;
43 AttachmentList::const_iterator iter
= attachments
.begin();
44 AttachmentList::const_iterator end
= attachments
.end();
45 for (; iter
!= end
; ++iter
) {
46 if (id_set
.find(iter
->GetId()) != id_set
.end()) {
49 id_set
.insert(iter
->GetId());
58 void SyncData::ImmutableSyncEntityTraits::InitializeWrapper(Wrapper
* wrapper
) {
59 *wrapper
= new sync_pb::SyncEntity();
62 void SyncData::ImmutableSyncEntityTraits::DestroyWrapper(Wrapper
* wrapper
) {
66 const sync_pb::SyncEntity
& SyncData::ImmutableSyncEntityTraits::Unwrap(
67 const Wrapper
& wrapper
) {
71 sync_pb::SyncEntity
* SyncData::ImmutableSyncEntityTraits::UnwrapMutable(
76 void SyncData::ImmutableSyncEntityTraits::Swap(sync_pb::SyncEntity
* t1
,
77 sync_pb::SyncEntity
* t2
) {
81 SyncData::SyncData() : id_(kInvalidId
), is_valid_(false) {}
83 SyncData::SyncData(int64 id
,
84 sync_pb::SyncEntity
* entity
,
85 AttachmentList
* attachments
,
86 const base::Time
& remote_modification_time
,
87 const syncer::AttachmentServiceProxy
& attachment_service
)
89 remote_modification_time_(remote_modification_time
),
90 immutable_entity_(entity
),
91 attachments_(attachments
),
92 attachment_service_(attachment_service
),
95 SyncData::~SyncData() {}
98 SyncData
SyncData::CreateLocalDelete(const std::string
& sync_tag
,
100 sync_pb::EntitySpecifics specifics
;
101 AddDefaultFieldValue(datatype
, &specifics
);
102 return CreateLocalData(sync_tag
, std::string(), specifics
);
106 SyncData
SyncData::CreateLocalData(const std::string
& sync_tag
,
107 const std::string
& non_unique_title
,
108 const sync_pb::EntitySpecifics
& specifics
) {
109 syncer::AttachmentList attachments
;
110 return CreateLocalDataWithAttachments(
111 sync_tag
, non_unique_title
, specifics
, attachments
);
115 SyncData
SyncData::CreateLocalDataWithAttachments(
116 const std::string
& sync_tag
,
117 const std::string
& non_unique_title
,
118 const sync_pb::EntitySpecifics
& specifics
,
119 const AttachmentList
& attachments
) {
120 DCHECK(!ContainsDuplicateAttachments(attachments
));
121 sync_pb::SyncEntity entity
;
122 entity
.set_client_defined_unique_tag(sync_tag
);
123 entity
.set_non_unique_name(non_unique_title
);
124 entity
.mutable_specifics()->CopyFrom(specifics
);
125 std::transform(attachments
.begin(),
127 RepeatedFieldBackInserter(entity
.mutable_attachment_id()),
129 AttachmentList
copy_of_attachments(attachments
);
130 return SyncData(kInvalidId
,
132 ©_of_attachments
,
134 AttachmentServiceProxy());
138 SyncData
SyncData::CreateRemoteData(
140 const sync_pb::EntitySpecifics
& specifics
,
141 const base::Time
& modification_time
,
142 const AttachmentIdList
& attachment_ids
,
143 const AttachmentServiceProxy
& attachment_service
) {
144 DCHECK_NE(id
, kInvalidId
);
145 sync_pb::SyncEntity entity
;
146 entity
.mutable_specifics()->CopyFrom(specifics
);
147 std::transform(attachment_ids
.begin(),
148 attachment_ids
.end(),
149 RepeatedFieldBackInserter(entity
.mutable_attachment_id()),
151 AttachmentList attachments
;
153 id
, &entity
, &attachments
, modification_time
, attachment_service
);
156 bool SyncData::IsValid() const { return is_valid_
; }
158 const sync_pb::EntitySpecifics
& SyncData::GetSpecifics() const {
159 return immutable_entity_
.Get().specifics();
162 ModelType
SyncData::GetDataType() const {
163 return GetModelTypeFromSpecifics(GetSpecifics());
166 const std::string
& SyncData::GetTitle() const {
167 // TODO(zea): set this for data coming from the syncer too.
168 DCHECK(immutable_entity_
.Get().has_non_unique_name());
169 return immutable_entity_
.Get().non_unique_name();
172 bool SyncData::IsLocal() const { return id_
== kInvalidId
; }
174 std::string
SyncData::ToString() const {
176 return "<Invalid SyncData>";
178 std::string type
= ModelTypeToString(GetDataType());
179 std::string specifics
;
180 scoped_ptr
<base::DictionaryValue
> value(
181 EntitySpecificsToValue(GetSpecifics()));
182 base::JSONWriter::WriteWithOptions(
183 value
.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT
, &specifics
);
186 SyncDataLocal
sync_data_local(*this);
187 return "{ isLocal: true, type: " + type
+ ", tag: " +
188 sync_data_local
.GetTag() + ", title: " + GetTitle() +
189 ", specifics: " + specifics
+ "}";
192 SyncDataRemote
sync_data_remote(*this);
193 std::string id
= base::Int64ToString(sync_data_remote
.GetId());
194 return "{ isLocal: false, type: " + type
+ ", specifics: " + specifics
+
198 void PrintTo(const SyncData
& sync_data
, std::ostream
* os
) {
199 *os
<< sync_data
.ToString();
202 AttachmentIdList
SyncData::GetAttachmentIds() const {
203 AttachmentIdList result
;
204 const sync_pb::SyncEntity
& entity
= immutable_entity_
.Get();
205 std::transform(entity
.attachment_id().begin(),
206 entity
.attachment_id().end(),
207 std::back_inserter(result
),
212 SyncDataLocal::SyncDataLocal(const SyncData
& sync_data
) : SyncData(sync_data
) {
213 DCHECK(sync_data
.IsLocal());
216 SyncDataLocal::~SyncDataLocal() {}
218 const AttachmentList
& SyncDataLocal::GetLocalAttachmentsForUpload() const {
219 return attachments_
.Get();
222 const std::string
& SyncDataLocal::GetTag() const {
223 return immutable_entity_
.Get().client_defined_unique_tag();
226 SyncDataRemote::SyncDataRemote(const SyncData
& sync_data
)
227 : SyncData(sync_data
) {
228 DCHECK(!sync_data
.IsLocal());
231 SyncDataRemote::~SyncDataRemote() {}
233 const base::Time
& SyncDataRemote::GetModifiedTime() const {
234 return remote_modification_time_
;
237 int64
SyncDataRemote::GetId() const {
241 void SyncDataRemote::GetOrDownloadAttachments(
242 const AttachmentIdList
& attachment_ids
,
243 const AttachmentService::GetOrDownloadCallback
& callback
) {
244 attachment_service_
.GetOrDownloadAttachments(attachment_ids
, callback
);
247 void SyncDataRemote::DropAttachments(
248 const AttachmentIdList
& attachment_ids
,
249 const AttachmentService::DropCallback
& callback
) {
250 attachment_service_
.DropAttachments(attachment_ids
, callback
);
253 } // namespace syncer