Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / sync / internal_api / public / base_node.h
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_INTERNAL_API_PUBLIC_BASE_NODE_H_
6 #define SYNC_INTERNAL_API_PUBLIC_BASE_NODE_H_
7
8 #include <string>
9 #include <vector>
10
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "sync/api/attachments/attachment.h"
16 #include "sync/base/sync_export.h"
17 #include "sync/internal_api/public/base/model_type.h"
18 #include "sync/protocol/sync.pb.h"
19 #include "url/gurl.h"
20
21 // Forward declarations of internal class types so that sync API objects
22 // may have opaque pointers to these types.
23 namespace base {
24 class DictionaryValue;
25 }
26
27 namespace sync_pb {
28 class AppSpecifics;
29 class AutofillSpecifics;
30 class AutofillProfileSpecifics;
31 class BookmarkSpecifics;
32 class EntitySpecifics;
33 class ExtensionSpecifics;
34 class SessionSpecifics;
35 class NigoriSpecifics;
36 class PreferenceSpecifics;
37 class PasswordSpecificsData;
38 class ThemeSpecifics;
39 class TypedUrlSpecifics;
40 }
41
42 namespace syncer {
43
44 class BaseTransaction;
45
46 namespace syncable {
47 class BaseTransaction;
48 class Entry;
49 }
50
51 // A valid BaseNode will never have an ID of zero.
52 static const int64 kInvalidId = 0;
53
54 // BaseNode wraps syncable::Entry, and corresponds to a single object's state.
55 // This, like syncable::Entry, is intended for use on the stack.  A valid
56 // transaction is necessary to create a BaseNode or any of its children.
57 // Unlike syncable::Entry, a sync API BaseNode is identified primarily by its
58 // int64 metahandle, which we call an ID here.
59 class SYNC_EXPORT BaseNode {
60  public:
61   // Enumerates the possible outcomes of trying to initialize a sync node.
62   enum InitByLookupResult {
63     INIT_OK,
64     // Could not find an entry matching the lookup criteria.
65     INIT_FAILED_ENTRY_NOT_GOOD,
66     // Found an entry, but it is already deleted.
67     INIT_FAILED_ENTRY_IS_DEL,
68     // Found an entry, but was unable to decrypt.
69     INIT_FAILED_DECRYPT_IF_NECESSARY,
70     // A precondition was not met for calling init, such as legal input
71     // arguments.
72     INIT_FAILED_PRECONDITION,
73   };
74
75   // All subclasses of BaseNode must provide a way to initialize themselves by
76   // doing an ID lookup.  Returns false on failure.  An invalid or deleted
77   // ID will result in failure.
78   virtual InitByLookupResult InitByIdLookup(int64 id) = 0;
79
80   // All subclasses of BaseNode must also provide a way to initialize themselves
81   // by doing a client tag lookup. Returns false on failure. A deleted node
82   // will return FALSE.
83   virtual InitByLookupResult InitByClientTagLookup(
84       ModelType model_type,
85       const std::string& tag) = 0;
86
87   // Each object is identified by a 64-bit id (internally, the syncable
88   // metahandle).  These ids are strictly local handles.  They will persist
89   // on this client, but the same object on a different client may have a
90   // different ID value.
91   virtual int64 GetId() const;
92
93   // Returns the modification time of the object.
94   base::Time GetModificationTime() const;
95
96   // Nodes are hierarchically arranged into a single-rooted tree.
97   // InitByRootLookup on ReadNode allows access to the root. GetParentId is
98   // how you find a node's parent.
99   int64 GetParentId() const;
100
101   // Nodes are either folders or not.  This corresponds to the IS_DIR property
102   // of syncable::Entry.
103   bool GetIsFolder() const;
104
105   // Returns the title of the object.
106   // Uniqueness of the title is not enforced on siblings -- it is not an error
107   // for two children to share a title.
108   std::string GetTitle() const;
109
110   // Returns the model type of this object.  The model type is set at node
111   // creation time and is expected never to change.
112   ModelType GetModelType() const;
113
114   // Getter specific to the BOOKMARK datatype.  Returns protobuf
115   // data.  Can only be called if GetModelType() == BOOKMARK.
116   const sync_pb::BookmarkSpecifics& GetBookmarkSpecifics() const;
117
118   // Getter specific to the APPS datatype.  Returns protobuf
119   // data.  Can only be called if GetModelType() == APPS.
120   const sync_pb::AppSpecifics& GetAppSpecifics() const;
121
122   // Getter specific to the AUTOFILL datatype.  Returns protobuf
123   // data.  Can only be called if GetModelType() == AUTOFILL.
124   const sync_pb::AutofillSpecifics& GetAutofillSpecifics() const;
125
126   virtual const sync_pb::AutofillProfileSpecifics&
127       GetAutofillProfileSpecifics() const;
128
129   // Getter specific to the NIGORI datatype.  Returns protobuf
130   // data.  Can only be called if GetModelType() == NIGORI.
131   const sync_pb::NigoriSpecifics& GetNigoriSpecifics() const;
132
133   // Getter specific to the PASSWORD datatype.  Returns protobuf
134   // data.  Can only be called if GetModelType() == PASSWORD.
135   const sync_pb::PasswordSpecificsData& GetPasswordSpecifics() const;
136
137   // Getter specific to the PREFERENCE datatype.  Returns protobuf
138   // data.  Can only be called if GetModelType() == PREFERENCE.
139   const sync_pb::PreferenceSpecifics& GetPreferenceSpecifics() const;
140
141   // Getter specific to the THEME datatype.  Returns protobuf
142   // data.  Can only be called if GetModelType() == THEME.
143   const sync_pb::ThemeSpecifics& GetThemeSpecifics() const;
144
145   // Getter specific to the TYPED_URLS datatype.  Returns protobuf
146   // data.  Can only be called if GetModelType() == TYPED_URLS.
147   const sync_pb::TypedUrlSpecifics& GetTypedUrlSpecifics() const;
148
149   // Getter specific to the EXTENSIONS datatype.  Returns protobuf
150   // data.  Can only be called if GetModelType() == EXTENSIONS.
151   const sync_pb::ExtensionSpecifics& GetExtensionSpecifics() const;
152
153   // Getter specific to the SESSIONS datatype.  Returns protobuf
154   // data.  Can only be called if GetModelType() == SESSIONS.
155   const sync_pb::SessionSpecifics& GetSessionSpecifics() const;
156
157   // Getter specific to the DEVICE_INFO datatype.  Returns protobuf
158   // data.  Can only be called if GetModelType() == DEVICE_INFO.
159   const sync_pb::DeviceInfoSpecifics& GetDeviceInfoSpecifics() const;
160
161   // Getter specific to the EXPERIMENTS datatype.  Returns protobuf
162   // data.  Can only be called if GetModelType() == EXPERIMENTS.
163   const sync_pb::ExperimentsSpecifics& GetExperimentsSpecifics() const;
164
165   // Getter specific to the PRIORITY_PREFERENCE datatype. Returns protobuf
166   // data.  Can only be called if GetModelType() == PRIORITY_PREFERENCE.
167   const sync_pb::PriorityPreferenceSpecifics&
168       GetPriorityPreferenceSpecifics() const;
169
170   const sync_pb::EntitySpecifics& GetEntitySpecifics() const;
171
172   // Returns the local external ID associated with the node.
173   int64 GetExternalId() const;
174
175   // Returns true iff this node has children.
176   bool HasChildren() const;
177
178   // Return the ID of the node immediately before this in the sibling order.
179   // For the first node in the ordering, return 0.
180   int64 GetPredecessorId() const;
181
182   // Return the ID of the node immediately after this in the sibling order.
183   // For the last node in the ordering, return 0.
184   int64 GetSuccessorId() const;
185
186   // Return the ID of the first child of this node.  If this node has no
187   // children, return 0.
188   int64 GetFirstChildId() const;
189
190   // Returns the IDs of the children of this node.
191   // If this type supports user-defined positions the returned IDs will be in
192   // the correct order.
193   void GetChildIds(std::vector<int64>* result) const;
194
195   // Returns the total number of nodes including and beneath this node.
196   // Recursively iterates through all children.
197   int GetTotalNodeCount() const;
198
199   // Returns this item's position within its parent.
200   // Do not call this function on items that do not support positioning
201   // (ie. non-bookmarks).
202   int GetPositionIndex() const;
203
204   // Returns this item's attachment ids.
205   const syncer::AttachmentIdList GetAttachmentIds() const;
206
207   // These virtual accessors provide access to data members of derived classes.
208   virtual const syncable::Entry* GetEntry() const = 0;
209   virtual const BaseTransaction* GetTransaction() const = 0;
210
211   // Returns a base::DictionaryValue serialization of this node.
212   base::DictionaryValue* ToValue() const;
213
214  protected:
215   BaseNode();
216   virtual ~BaseNode();
217
218   // Determines whether part of the entry is encrypted, and if so attempts to
219   // decrypt it. Unless decryption is necessary and fails, this will always
220   // return |true|. If the contents are encrypted, the decrypted data will be
221   // stored in |unencrypted_data_|.
222   // This method is invoked once when the BaseNode is initialized.
223   bool DecryptIfNecessary();
224
225   // Returns the unencrypted specifics associated with |entry|. If |entry| was
226   // not encrypted, it directly returns |entry|'s EntitySpecifics. Otherwise,
227   // returns |unencrypted_data_|.
228   const sync_pb::EntitySpecifics& GetUnencryptedSpecifics(
229       const syncable::Entry* entry) const;
230
231   // Copy |specifics| into |unencrypted_data_|.
232   void SetUnencryptedSpecifics(const sync_pb::EntitySpecifics& specifics);
233
234  private:
235   // Have to friend the test class as well to allow member functions to access
236   // protected/private BaseNode methods.
237   friend class SyncManagerTest;
238   FRIEND_TEST_ALL_PREFIXES(SyncApiTest, GenerateSyncableHash);
239   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdateEntryWithEncryption);
240   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest,
241                            UpdatePasswordSetEntitySpecificsNoChange);
242   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdatePasswordSetPasswordSpecifics);
243   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdatePasswordNewPassphrase);
244   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdatePasswordReencryptEverything);
245   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetBookmarkTitle);
246   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetBookmarkTitleWithEncryption);
247   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetNonBookmarkTitle);
248   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetNonBookmarkTitleWithEncryption);
249   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetPreviouslyEncryptedSpecifics);
250   FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, IncrementTransactionVersion);
251
252   void* operator new(size_t size);  // Node is meant for stack use only.
253
254   // A holder for the unencrypted data stored in an encrypted node.
255   sync_pb::EntitySpecifics unencrypted_data_;
256
257   // Same as |unencrypted_data_|, but for legacy password encryption.
258   scoped_ptr<sync_pb::PasswordSpecificsData> password_data_;
259
260   DISALLOW_COPY_AND_ASSIGN(BaseNode);
261 };
262
263 }  // namespace syncer
264
265 #endif  // SYNC_INTERNAL_API_PUBLIC_BASE_NODE_H_