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_WRITE_NODE_H_
6#define SYNC_INTERNAL_API_PUBLIC_WRITE_NODE_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "sync/base/sync_export.h"
14#include "sync/internal_api/public/base/model_type.h"
15#include "sync/internal_api/public/base_node.h"
16
17namespace sync_pb {
18class AppSpecifics;
19class AutofillSpecifics;
20class AutofillProfileSpecifics;
21class BookmarkSpecifics;
22class EntitySpecifics;
23class ExtensionSpecifics;
24class SessionSpecifics;
25class NigoriSpecifics;
26class PasswordSpecificsData;
27class ThemeSpecifics;
28class TypedUrlSpecifics;
29}
30
31namespace syncer {
32
33class Cryptographer;
34class WriteTransaction;
35
36namespace syncable {
37class Entry;
38class MutableEntry;
39}
40
41// WriteNode extends BaseNode to add mutation, and wraps
42// syncable::MutableEntry. A WriteTransaction is needed to create a WriteNode.
43class SYNC_EXPORT WriteNode : public BaseNode {
44 public:
45  enum InitUniqueByCreationResult {
46    INIT_SUCCESS,
47    // The tag passed into this method was empty.
48    INIT_FAILED_EMPTY_TAG,
49    // An entry with this tag already exists.
50    INIT_FAILED_ENTRY_ALREADY_EXISTS,
51    // The constructor for a new MutableEntry with the specified data failed.
52    INIT_FAILED_COULD_NOT_CREATE_ENTRY,
53    // Setting the predecessor failed
54    INIT_FAILED_SET_PREDECESSOR,
55  };
56
57  // Create a WriteNode using the given transaction.
58  explicit WriteNode(WriteTransaction* transaction);
59  virtual ~WriteNode();
60
61  // A client must use one (and only one) of the following Init variants to
62  // populate the node.
63
64  // BaseNode implementation.
65  virtual InitByLookupResult InitByIdLookup(int64 id) OVERRIDE;
66  virtual InitByLookupResult InitByClientTagLookup(
67      ModelType model_type,
68      const std::string& tag) OVERRIDE;
69
70  // Create a new bookmark node with the specified parent and predecessor.  Use
71  // a NULL |predecessor| to indicate that this is to be the first child.
72  // |predecessor| must be a child of |new_parent| or NULL. Returns false on
73  // failure.
74  bool InitBookmarkByCreation(const BaseNode& parent,
75                              const BaseNode* predecessor);
76
77  // Create nodes using this function if they're unique items that
78  // you want to fetch using client_tag. Note that the behavior of these
79  // items is slightly different than that of normal items.
80  // Most importantly, if it exists locally, this function will
81  // actually undelete it
82  // Client unique tagged nodes must NOT be folders.
83  InitUniqueByCreationResult InitUniqueByCreation(
84      ModelType model_type,
85      const BaseNode& parent,
86      const std::string& client_tag);
87
88  // Each server-created permanent node is tagged with a unique string.
89  // Look up the node with the particular tag.  If it does not exist,
90  // return false.
91  InitByLookupResult InitByTagLookup(const std::string& tag);
92
93  // These Set() functions correspond to the Get() functions of BaseNode.
94  void SetIsFolder(bool folder);
95  void SetTitle(const std::wstring& title);
96
97  // External ID is a client-only field, so setting it doesn't cause the item to
98  // be synced again.
99  void SetExternalId(int64 external_id);
100
101  // Remove this node and its children and sync deletion to server.
102  void Tombstone();
103
104  // If the node is known by server, remove it and its children but don't sync
105  // deletion to server. Do nothing if the node is not known by server so that
106  // server can have a record of the node.
107  void Drop();
108
109  // Set a new parent and position.  Position is specified by |predecessor|; if
110  // it is NULL, the node is moved to the first position.  |predecessor| must
111  // be a child of |new_parent| or NULL.  Returns false on failure..
112  bool SetPosition(const BaseNode& new_parent, const BaseNode* predecessor);
113
114  // Set the bookmark specifics (url and favicon).
115  // Should only be called if GetModelType() == BOOKMARK.
116  void SetBookmarkSpecifics(const sync_pb::BookmarkSpecifics& specifics);
117
118  // Generic set specifics method. Will extract the model type from |specifics|.
119  void SetEntitySpecifics(const sync_pb::EntitySpecifics& specifics);
120
121  // Resets the EntitySpecifics for this node based on the unencrypted data.
122  // Will encrypt if necessary.
123  void ResetFromSpecifics();
124
125  // TODO(sync): Remove the setters below when the corresponding data
126  // types are ported to the new sync service API.
127
128  // Set the app specifics (id, update url, enabled state, etc).
129  // Should only be called if GetModelType() == APPS.
130  void SetAppSpecifics(const sync_pb::AppSpecifics& specifics);
131
132  // Set the autofill specifics (name and value).
133  // Should only be called if GetModelType() == AUTOFILL.
134  void SetAutofillSpecifics(const sync_pb::AutofillSpecifics& specifics);
135
136  void SetAutofillProfileSpecifics(
137      const sync_pb::AutofillProfileSpecifics& specifics);
138
139  // Set the nigori specifics.
140  // Should only be called if GetModelType() == NIGORI.
141  void SetNigoriSpecifics(const sync_pb::NigoriSpecifics& specifics);
142
143  // Set the password specifics.
144  // Should only be called if GetModelType() == PASSWORD.
145  void SetPasswordSpecifics(const sync_pb::PasswordSpecificsData& specifics);
146
147  // Set the theme specifics (name and value).
148  // Should only be called if GetModelType() == THEME.
149  void SetThemeSpecifics(const sync_pb::ThemeSpecifics& specifics);
150
151  // Set the typed_url specifics (url, title, typed_count, etc).
152  // Should only be called if GetModelType() == TYPED_URLS.
153  void SetTypedUrlSpecifics(const sync_pb::TypedUrlSpecifics& specifics);
154
155  // Set the extension specifics (id, update url, enabled state, etc).
156  // Should only be called if GetModelType() == EXTENSIONS.
157  void SetExtensionSpecifics(const sync_pb::ExtensionSpecifics& specifics);
158
159  // Set the session specifics (windows, tabs, navigations etc.).
160  // Should only be called if GetModelType() == SESSIONS.
161  void SetSessionSpecifics(const sync_pb::SessionSpecifics& specifics);
162
163  // Set the managed user setting specifics (name and value).
164  // Should only be called if GetModelType() == MANAGED_USER_SETTINGS.
165  void SetManagedUserSettingSpecifics(
166      const sync_pb::ManagedUserSettingSpecifics& specifics);
167
168  // Set the managed user setting specifics (name and value).
169  // Should only be called if GetModelType() == MANAGED_USERS.
170  void SetManagedUserSpecifics(const sync_pb::ManagedUserSpecifics& specifics);
171
172  // Set the device info specifics.
173  // Should only be called if GetModelType() == DEVICE_INFO.
174  void SetDeviceInfoSpecifics(const sync_pb::DeviceInfoSpecifics& specifics);
175
176  // Set the experiments specifics.
177  // Should only be called if GetModelType() == EXPERIMENTS.
178  void SetExperimentsSpecifics(const sync_pb::ExperimentsSpecifics& specifics);
179
180  // Set the priority preference specifics.
181  // Should only be called if GetModelType() == PRIORITY_PREFERENCE.
182  void SetPriorityPreferenceSpecifics(
183      const sync_pb::PriorityPreferenceSpecifics& specifics);
184
185  // Implementation of BaseNode's abstract virtual accessors.
186  virtual const syncable::Entry* GetEntry() const OVERRIDE;
187
188  virtual const BaseTransaction* GetTransaction() const OVERRIDE;
189
190  syncable::MutableEntry* GetMutableEntryForTest();
191
192 private:
193  FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, EncryptBookmarksWithLegacyData);
194
195  void* operator new(size_t size);  // Node is meant for stack use only.
196
197  // Helper to set the previous node.
198  bool PutPredecessor(const BaseNode* predecessor) WARN_UNUSED_RESULT;
199
200  // Sets IS_UNSYNCED and SYNCING to ensure this entry is considered in an
201  // upcoming commit pass.
202  void MarkForSyncing();
203
204  // The underlying syncable object which this class wraps.
205  syncable::MutableEntry* entry_;
206
207  // The sync API transaction that is the parent of this node.
208  WriteTransaction* transaction_;
209
210  DISALLOW_COPY_AND_ASSIGN(WriteNode);
211};
212
213}  // namespace syncer
214
215#endif  // SYNC_INTERNAL_API_PUBLIC_WRITE_NODE_H_
216