1 // Copyright 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/syncable/entry.h"
6
7 #include <iomanip>
8
9 #include "base/json/string_escape.h"
10 #include "base/strings/string_util.h"
11 #include "sync/syncable/blob.h"
12 #include "sync/syncable/directory.h"
13 #include "sync/syncable/syncable_base_transaction.h"
14 #include "sync/syncable/syncable_columns.h"
15
16 using std::string;
17
18 namespace syncer {
19 namespace syncable {
20
Entry(BaseTransaction * trans,GetById,const Id & id)21 Entry::Entry(BaseTransaction* trans, GetById, const Id& id)
22 : basetrans_(trans) {
23 kernel_ = trans->directory()->GetEntryById(id);
24 }
25
Entry(BaseTransaction * trans,GetByClientTag,const string & tag)26 Entry::Entry(BaseTransaction* trans, GetByClientTag, const string& tag)
27 : basetrans_(trans) {
28 kernel_ = trans->directory()->GetEntryByClientTag(tag);
29 }
30
Entry(BaseTransaction * trans,GetByServerTag,const string & tag)31 Entry::Entry(BaseTransaction* trans, GetByServerTag, const string& tag)
32 : basetrans_(trans) {
33 kernel_ = trans->directory()->GetEntryByServerTag(tag);
34 }
35
Entry(BaseTransaction * trans,GetByHandle,int64 metahandle)36 Entry::Entry(BaseTransaction* trans, GetByHandle, int64 metahandle)
37 : basetrans_(trans) {
38 kernel_ = trans->directory()->GetEntryByHandle(metahandle);
39 }
40
dir() const41 Directory* Entry::dir() const {
42 return basetrans_->directory();
43 }
44
ToValue(Cryptographer * cryptographer) const45 base::DictionaryValue* Entry::ToValue(Cryptographer* cryptographer) const {
46 base::DictionaryValue* entry_info = new base::DictionaryValue();
47 entry_info->SetBoolean("good", good());
48 if (good()) {
49 entry_info->Set("kernel", kernel_->ToValue(cryptographer));
50 entry_info->Set("modelType",
51 ModelTypeToValue(GetModelType()));
52 entry_info->SetBoolean("existsOnClientBecauseNameIsNonEmpty",
53 ExistsOnClientBecauseNameIsNonEmpty());
54 entry_info->SetBoolean("isRoot", IsRoot());
55 }
56 return entry_info;
57 }
58
GetServerModelType() const59 ModelType Entry::GetServerModelType() const {
60 ModelType specifics_type = kernel_->GetServerModelType();
61 if (specifics_type != UNSPECIFIED)
62 return specifics_type;
63
64 // Otherwise, we don't have a server type yet. That should only happen
65 // if the item is an uncommitted locally created item.
66 // It's possible we'll need to relax these checks in the future; they're
67 // just here for now as a safety measure.
68 DCHECK(GetIsUnsynced());
69 DCHECK_EQ(GetServerVersion(), 0);
70 DCHECK(GetServerIsDel());
71 // Note: can't enforce !GetId().ServerKnows() here because that could
72 // actually happen if we hit AttemptReuniteLostCommitResponses.
73 return UNSPECIFIED;
74 }
75
GetModelType() const76 ModelType Entry::GetModelType() const {
77 ModelType specifics_type = GetModelTypeFromSpecifics(GetSpecifics());
78 if (specifics_type != UNSPECIFIED)
79 return specifics_type;
80 if (IsRoot())
81 return TOP_LEVEL_FOLDER;
82 // Loose check for server-created top-level folders that aren't
83 // bound to a particular model type.
84 if (!GetUniqueServerTag().empty() && GetIsDir())
85 return TOP_LEVEL_FOLDER;
86
87 return UNSPECIFIED;
88 }
89
GetPredecessorId() const90 Id Entry::GetPredecessorId() const {
91 return dir()->GetPredecessorId(kernel_);
92 }
93
GetSuccessorId() const94 Id Entry::GetSuccessorId() const {
95 return dir()->GetSuccessorId(kernel_);
96 }
97
GetFirstChildId() const98 Id Entry::GetFirstChildId() const {
99 return dir()->GetFirstChildId(basetrans_, kernel_);
100 }
101
GetChildHandles(std::vector<int64> * result) const102 void Entry::GetChildHandles(std::vector<int64>* result) const {
103 dir()->GetChildHandlesById(basetrans_, GetId(), result);
104 }
105
GetTotalNodeCount() const106 int Entry::GetTotalNodeCount() const {
107 return dir()->GetTotalNodeCount(basetrans_, kernel_);
108 }
109
GetPositionIndex() const110 int Entry::GetPositionIndex() const {
111 return dir()->GetPositionIndex(basetrans_, kernel_);
112 }
113
ShouldMaintainPosition() const114 bool Entry::ShouldMaintainPosition() const {
115 return kernel_->ShouldMaintainPosition();
116 }
117
operator <<(std::ostream & s,const Blob & blob)118 std::ostream& operator<<(std::ostream& s, const Blob& blob) {
119 for (Blob::const_iterator i = blob.begin(); i != blob.end(); ++i)
120 s << std::hex << std::setw(2)
121 << std::setfill('0') << static_cast<unsigned int>(*i);
122 return s << std::dec;
123 }
124
operator <<(std::ostream & os,const Entry & entry)125 std::ostream& operator<<(std::ostream& os, const Entry& entry) {
126 int i;
127 EntryKernel* const kernel = entry.kernel_;
128 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) {
129 os << g_metas_columns[i].name << ": "
130 << kernel->ref(static_cast<Int64Field>(i)) << ", ";
131 }
132 for ( ; i < TIME_FIELDS_END; ++i) {
133 os << g_metas_columns[i].name << ": "
134 << GetTimeDebugString(kernel->ref(static_cast<TimeField>(i))) << ", ";
135 }
136 for ( ; i < ID_FIELDS_END; ++i) {
137 os << g_metas_columns[i].name << ": "
138 << kernel->ref(static_cast<IdField>(i)) << ", ";
139 }
140 os << "Flags: ";
141 for ( ; i < BIT_FIELDS_END; ++i) {
142 if (kernel->ref(static_cast<BitField>(i)))
143 os << g_metas_columns[i].name << ", ";
144 }
145 for ( ; i < STRING_FIELDS_END; ++i) {
146 const std::string& field = kernel->ref(static_cast<StringField>(i));
147 os << g_metas_columns[i].name << ": " << field << ", ";
148 }
149 for ( ; i < PROTO_FIELDS_END; ++i) {
150 std::string escaped_str = base::EscapeBytesAsInvalidJSONString(
151 kernel->ref(static_cast<ProtoField>(i)).SerializeAsString(),
152 false);
153 os << g_metas_columns[i].name << ": " << escaped_str << ", ";
154 }
155 for ( ; i < UNIQUE_POSITION_FIELDS_END; ++i) {
156 os << g_metas_columns[i].name << ": "
157 << kernel->ref(static_cast<UniquePositionField>(i)).ToDebugString()
158 << ", ";
159 }
160 os << "TempFlags: ";
161 for ( ; i < BIT_TEMPS_END; ++i) {
162 if (kernel->ref(static_cast<BitTemp>(i)))
163 os << "#" << i - BIT_TEMPS_BEGIN << ", ";
164 }
165 return os;
166 }
167
168 } // namespace syncable
169 } // namespace syncer
170