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#ifndef SYNC_SYNCABLE_ENTRY_H_
6#define SYNC_SYNCABLE_ENTRY_H_
7
8#include "sync/base/sync_export.h"
9#include "sync/syncable/entry_kernel.h"
10
11namespace syncer {
12class Cryptographer;
13class ReadNode;
14
15namespace syncable {
16
17class Directory;
18class BaseTransaction;
19
20// A read-only meta entry
21// Instead of:
22//   Entry e = transaction.GetById(id);
23// use:
24//   Entry e(transaction, GET_BY_ID, id);
25//
26// Why?  The former would require a copy constructor, and it would be difficult
27// to enforce that an entry never outlived its transaction if there were a copy
28// constructor.
29enum GetById {
30  GET_BY_ID
31};
32
33enum GetByClientTag {
34  GET_BY_CLIENT_TAG
35};
36
37enum GetByServerTag {
38  GET_BY_SERVER_TAG
39};
40
41enum GetByHandle {
42  GET_BY_HANDLE
43};
44
45class SYNC_EXPORT Entry {
46 public:
47  // After constructing, you must check good() to test whether the Get
48  // succeeded.
49  Entry(BaseTransaction* trans, GetByHandle, int64 handle);
50  Entry(BaseTransaction* trans, GetById, const Id& id);
51  Entry(BaseTransaction* trans, GetByServerTag, const std::string& tag);
52  Entry(BaseTransaction* trans, GetByClientTag, const std::string& tag);
53
54  bool good() const { return 0 != kernel_; }
55
56  BaseTransaction* trans() const { return basetrans_; }
57
58  // Field accessors.
59  int64 GetMetahandle() const {
60    DCHECK(kernel_);
61    return kernel_->ref(META_HANDLE);
62  }
63
64  int64 GetBaseVersion() const {
65    DCHECK(kernel_);
66    return kernel_->ref(BASE_VERSION);
67  }
68
69  int64 GetServerVersion() const {
70    DCHECK(kernel_);
71    return kernel_->ref(SERVER_VERSION);
72  }
73
74  int64 GetLocalExternalId() const {
75    DCHECK(kernel_);
76    return kernel_->ref(LOCAL_EXTERNAL_ID);
77  }
78
79  int64 GetTransactionVersion() const {
80    DCHECK(kernel_);
81    return kernel_->ref(TRANSACTION_VERSION);
82  }
83
84  const base::Time& GetMtime() const {
85    DCHECK(kernel_);
86    return kernel_->ref(MTIME);
87  }
88
89  const base::Time& GetServerMtime() const {
90    DCHECK(kernel_);
91    return kernel_->ref(SERVER_MTIME);
92  }
93
94  const base::Time& GetCtime() const {
95    DCHECK(kernel_);
96    return kernel_->ref(CTIME);
97  }
98
99  const base::Time& GetServerCtime() const {
100    DCHECK(kernel_);
101    return kernel_->ref(SERVER_CTIME);
102  }
103
104  Id GetId() const {
105    DCHECK(kernel_);
106    return kernel_->ref(ID);
107  }
108
109  Id GetParentId() const {
110    DCHECK(kernel_);
111    return kernel_->ref(PARENT_ID);
112  }
113
114  Id GetServerParentId() const {
115    DCHECK(kernel_);
116    return kernel_->ref(SERVER_PARENT_ID);
117  }
118
119  bool GetIsUnsynced() const {
120    DCHECK(kernel_);
121    return kernel_->ref(IS_UNSYNCED);
122  }
123
124  bool GetIsUnappliedUpdate() const {
125    DCHECK(kernel_);
126    return kernel_->ref(IS_UNAPPLIED_UPDATE);
127  }
128
129  bool GetIsDel() const {
130    DCHECK(kernel_);
131    return kernel_->ref(IS_DEL);
132  }
133
134  bool GetIsDir() const {
135    DCHECK(kernel_);
136    return kernel_->ref(IS_DIR);
137  }
138
139  bool GetServerIsDir() const {
140    DCHECK(kernel_);
141    return kernel_->ref(SERVER_IS_DIR);
142  }
143
144  bool GetServerIsDel() const {
145    DCHECK(kernel_);
146    return kernel_->ref(SERVER_IS_DEL);
147  }
148
149  const std::string& GetNonUniqueName() const {
150    DCHECK(kernel_);
151    return kernel_->ref(NON_UNIQUE_NAME);
152  }
153
154  const std::string& GetServerNonUniqueName() const {
155    DCHECK(kernel_);
156    return kernel_->ref(SERVER_NON_UNIQUE_NAME);
157  }
158
159  const std::string& GetUniqueServerTag() const {
160    DCHECK(kernel_);
161    return kernel_->ref(UNIQUE_SERVER_TAG);
162  }
163
164  const std::string& GetUniqueClientTag() const {
165    DCHECK(kernel_);
166    return kernel_->ref(UNIQUE_CLIENT_TAG);
167  }
168
169  const std::string& GetUniqueBookmarkTag() const {
170    DCHECK(kernel_);
171    return kernel_->ref(UNIQUE_BOOKMARK_TAG);
172  }
173
174  const sync_pb::EntitySpecifics& GetSpecifics() const {
175    DCHECK(kernel_);
176    return kernel_->ref(SPECIFICS);
177  }
178
179  const sync_pb::EntitySpecifics& GetServerSpecifics() const {
180    DCHECK(kernel_);
181    return kernel_->ref(SERVER_SPECIFICS);
182  }
183
184  const sync_pb::EntitySpecifics& GetBaseServerSpecifics() const {
185    DCHECK(kernel_);
186    return kernel_->ref(BASE_SERVER_SPECIFICS);
187  }
188
189  const UniquePosition& GetServerUniquePosition() const {
190    DCHECK(kernel_);
191    return kernel_->ref(SERVER_UNIQUE_POSITION);
192  }
193
194  const UniquePosition& GetUniquePosition() const {
195    DCHECK(kernel_);
196    return kernel_->ref(UNIQUE_POSITION);
197  }
198
199  bool GetSyncing() const {
200    DCHECK(kernel_);
201    return kernel_->ref(SYNCING);
202  }
203
204  ModelType GetServerModelType() const;
205  ModelType GetModelType() const;
206
207  Id GetPredecessorId() const;
208  Id GetSuccessorId() const;
209  Id GetFirstChildId() const;
210  int GetTotalNodeCount() const;
211
212  int GetPositionIndex() const;
213
214  // Returns a vector of this node's children's handles.
215  // Clears |result| if there are no children.  If this node is of a type that
216  // supports user-defined ordering then the resulting vector will be in the
217  // proper order.
218  void GetChildHandles(std::vector<int64>* result) const;
219
220  inline bool ExistsOnClientBecauseNameIsNonEmpty() const {
221    DCHECK(kernel_);
222    return !kernel_->ref(NON_UNIQUE_NAME).empty();
223  }
224
225  inline bool IsRoot() const {
226    DCHECK(kernel_);
227    return kernel_->ref(ID).IsRoot();
228  }
229
230  // Returns true if this is an entry that is expected to maintain a certain
231  // sort ordering relative to its siblings under the same parent.
232  bool ShouldMaintainPosition() const;
233
234  Directory* dir() const;
235
236  const EntryKernel GetKernelCopy() const {
237    return *kernel_;
238  }
239
240  // Dumps all entry info into a DictionaryValue and returns it.
241  // Transfers ownership of the DictionaryValue to the caller.
242  base::DictionaryValue* ToValue(Cryptographer* cryptographer) const;
243
244 protected:  // Don't allow creation on heap, except by sync API wrappers.
245  void* operator new(size_t size) { return (::operator new)(size); }
246
247  inline explicit Entry(BaseTransaction* trans)
248      : basetrans_(trans),
249        kernel_(NULL) { }
250
251 protected:
252  BaseTransaction* const basetrans_;
253
254  EntryKernel* kernel_;
255
256 private:
257  friend class Directory;
258  friend class syncer::ReadNode;
259  friend std::ostream& operator << (std::ostream& s, const Entry& e);
260
261  DISALLOW_COPY_AND_ASSIGN(Entry);
262};
263
264std::ostream& operator<<(std::ostream& os, const Entry& entry);
265
266}  // namespace syncable
267}  // namespace syncer
268
269#endif  // SYNC_SYNCABLE_ENTRY_H_
270