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_ENGINE_PROCESS_COMMIT_RESPONSE_COMMAND_H_
6#define SYNC_ENGINE_PROCESS_COMMIT_RESPONSE_COMMAND_H_
7
8#include <set>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "sync/base/sync_export.h"
14#include "sync/engine/model_changing_syncer_command.h"
15#include "sync/protocol/sync.pb.h"
16
17namespace syncer {
18
19namespace sessions {
20class OrderedCommitSet;
21}
22
23namespace syncable {
24class Id;
25class WriteTransaction;
26class MutableEntry;
27class Directory;
28}
29
30// A class that processes the server's response to our commmit attempt.  Note
31// that some of the preliminary processing is performed in
32// PostClientToServerMessage command.
33//
34// As part of processing the commit response, this command will modify sync
35// entries.  It can rename items, update their versions, etc.
36//
37// This command will return a non-SYNCER_OK value if an error occurred while
38// processing the response, or if the server's response indicates that it had
39// trouble processing the request.
40//
41// See SyncerCommand documentation for more info.
42class SYNC_EXPORT_PRIVATE ProcessCommitResponseCommand
43    : public ModelChangingSyncerCommand {
44 public:
45
46  // The commit_set parameter contains references to all the items which were
47  // to be committed in this batch.
48  //
49  // The commmit_message parameter contains the message that was sent to the
50  // server.
51  //
52  // The commit_response parameter contains the response received from the
53  // server.  This may be uninitialized if we were unable to contact the server
54  // or a serious error was encountered.
55  ProcessCommitResponseCommand(
56      const sessions::OrderedCommitSet& commit_set,
57      const sync_pb::ClientToServerMessage& commit_message,
58      const sync_pb::ClientToServerResponse& commit_response);
59  virtual ~ProcessCommitResponseCommand();
60
61 protected:
62  // ModelChangingSyncerCommand implementation.
63  virtual std::set<ModelSafeGroup> GetGroupsToChange(
64      const sessions::SyncSession& session) const OVERRIDE;
65  virtual SyncerError ModelChangingExecuteImpl(
66      sessions::SyncSession* session) OVERRIDE;
67
68 private:
69  sync_pb::CommitResponse::ResponseType ProcessSingleCommitResponse(
70      syncable::WriteTransaction* trans,
71      const sync_pb::CommitResponse_EntryResponse& pb_commit_response,
72      const sync_pb::SyncEntity& pb_committed_entry,
73      const syncable::Id& pre_commit_id,
74      std::set<syncable::Id>* deleted_folders);
75
76  void ProcessSuccessfulCommitResponse(
77      const sync_pb::SyncEntity& committed_entry,
78      const sync_pb::CommitResponse_EntryResponse& entry_response,
79      const syncable::Id& pre_commit_id, syncable::MutableEntry* local_entry,
80      bool syncing_was_set, std::set<syncable::Id>* deleted_folders);
81
82  // Update the BASE_VERSION and SERVER_VERSION, post-commit.
83  // Helper for ProcessSuccessfulCommitResponse.
84  bool UpdateVersionAfterCommit(
85      const sync_pb::SyncEntity& committed_entry,
86      const sync_pb::CommitResponse_EntryResponse& entry_response,
87      const syncable::Id& pre_commit_id,
88      syncable::MutableEntry* local_entry);
89
90  // If the server generated an ID for us during a commit, apply the new ID.
91  // Helper for ProcessSuccessfulCommitResponse.
92  bool ChangeIdAfterCommit(
93      const sync_pb::CommitResponse_EntryResponse& entry_response,
94      const syncable::Id& pre_commit_id,
95      syncable::MutableEntry* local_entry);
96
97  // Update the SERVER_ fields to reflect the server state after committing.
98  // Helper for ProcessSuccessfulCommitResponse.
99  void UpdateServerFieldsAfterCommit(
100      const sync_pb::SyncEntity& committed_entry,
101      const sync_pb::CommitResponse_EntryResponse& entry_response,
102      syncable::MutableEntry* local_entry);
103
104  // The server can override some values during a commit; the overridden values
105  // are returned as fields in the CommitResponse_EntryResponse.  This method
106  // stores the fields back in the client-visible (i.e. not the SERVER_* fields)
107  // fields of the entry.  This should only be done if the item did not change
108  // locally while the commit was in flight.
109  // Helper for ProcessSuccessfulCommitResponse.
110  void OverrideClientFieldsAfterCommit(
111      const sync_pb::SyncEntity& committed_entry,
112      const sync_pb::CommitResponse_EntryResponse& entry_response,
113      syncable::MutableEntry* local_entry);
114
115  // Helper to extract the final name from the protobufs.
116  const std::string& GetResultingPostCommitName(
117      const sync_pb::SyncEntity& committed_entry,
118      const sync_pb::CommitResponse_EntryResponse& entry_response);
119
120  // Helper to clean up in case of failure.
121  void ClearSyncingBits(
122      syncable::Directory *dir,
123      const std::vector<syncable::Id>& commit_ids);
124
125  const sessions::OrderedCommitSet& commit_set_;
126  const sync_pb::ClientToServerMessage& commit_message_;
127  const sync_pb::ClientToServerResponse& commit_response_;
128
129  DISALLOW_COPY_AND_ASSIGN(ProcessCommitResponseCommand);
130};
131
132}  // namespace syncer
133
134#endif  // SYNC_ENGINE_PROCESS_COMMIT_RESPONSE_COMMAND_H_
135