change_list_processor.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 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 CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_PROCESSOR_H_
6#define CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_PROCESSOR_H_
7
8#include <map>
9#include <set>
10#include <string>
11
12#include "base/callback.h"
13#include "base/files/file_path.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/scoped_vector.h"
16#include "base/memory/weak_ptr.h"
17#include "chrome/browser/chromeos/drive/drive_file_error.h"
18#include "chrome/browser/google_apis/drive_api_parser.h"
19#include "googleurl/src/gurl.h"
20
21namespace google_apis {
22class ResourceList;
23}  // google_apis
24
25namespace drive {
26
27class DriveEntryProto;
28class DriveResourceMetadata;
29
30// ChangeListProcessor is used to process feeds from WAPI (codename for
31// Documents List API) or Google Drive API.
32class ChangeListProcessor {
33 public:
34  typedef std::map<std::string /* resource_id */, DriveEntryProto>
35      DriveEntryProtoMap;
36
37  // Class used to record UMA stats with FeedToEntryProtoMap().
38  class ChangeListToEntryProtoMapUMAStats;
39
40  explicit ChangeListProcessor(DriveResourceMetadata* resource_metadata);
41  ~ChangeListProcessor();
42
43  // Applies the documents feeds to the file system using |resource_metadata_|.
44  //
45  // |is_delta_feed| determines the type of feed to process, whether it is a
46  // root feed (false) or a delta feed (true).
47  //
48  // In the case of processing the root feeds |root_feed_changestamp| is used
49  // as its initial changestamp value. The value comes from
50  // google_apis::AccountMetadata.
51  // |on_complete_callback| is run after the feed is applied.
52  // |on_complete_callback| must not be null.
53  // TODO(achuith): Change the type of on_complete_callback to
54  // FileOperationCallback instead.
55  void ApplyFeeds(
56      scoped_ptr<google_apis::AboutResource> about_resource,
57      const ScopedVector<google_apis::ResourceList>& feed_list,
58      bool is_delta_feed,
59      const base::Closure& on_complete_callback);
60
61  // Converts list of document feeds from collected feeds into a
62  // DriveEntryProtoMap. |feed_changestamp| and/or |uma_stats| may be NULL.
63  // entry_proto_map_ and root_upload_url_ are updated as side effects.
64  void FeedToEntryProtoMap(
65      const ScopedVector<google_apis::ResourceList>& feed_list,
66      int64* feed_changestamp,
67      ChangeListToEntryProtoMapUMAStats* uma_stats);
68
69  // A map of DriveEntryProto's representing a feed.
70  const DriveEntryProtoMap& entry_proto_map() const { return entry_proto_map_; }
71
72  // The set of changed directories as a result of feed processing.
73  const std::set<base::FilePath>& changed_dirs() const { return changed_dirs_; }
74
75 private:
76  // Applies the pre-processed feed from entry_proto_map_ onto the filesystem.
77  void ApplyEntryProtoMap(bool is_delta_feed);
78
79  // Apply the next item from entry_proto_map_ to the file system. The async
80  // version posts to the message loop to avoid recursive stack-overflow.
81  void ApplyNextEntryProto();
82  void ApplyNextEntryProtoAsync();
83
84  // Apply |entry_proto| to resource_metadata_.
85  void ApplyEntryProto(const DriveEntryProto& entry_proto);
86
87  // Continue ApplyEntryProto. This is a callback for
88  // DriveResourceMetadata::GetEntryInfoByResourceId.
89  void ContinueApplyEntryProto(
90      const DriveEntryProto& entry_proto,
91      DriveFileError error,
92      const base::FilePath& file_path,
93      scoped_ptr<DriveEntryProto> old_entry_proto);
94
95  // Apply the DriveEntryProto pointed to by |it| to resource_metadata_.
96  void ApplyNextByIterator(DriveEntryProtoMap::iterator it);
97
98  // Helper function to add |entry_proto| to its parent. Updates changed_dirs_
99  // as a side effect.
100  void AddEntry(const DriveEntryProto& entry_proto);
101
102  // Callback for DriveResourceMetadata::AddEntry.
103  void NotifyForAddEntry(bool is_directory,
104                         DriveFileError error,
105                         const base::FilePath& file_path);
106
107  // Removes entry pointed to by |resource_id| from its parent. Updates
108  // changed_dirs_ as a side effect.
109  void RemoveEntryFromParent(
110      const DriveEntryProto& entry_proto,
111      const base::FilePath& file_path);
112
113  // Continues RemoveEntryFromParent after
114  // DriveResourceMetadata::GetChildDirectories.
115  void OnGetChildrenForRemove(
116      const DriveEntryProto& entry_proto,
117      const base::FilePath& file_path,
118      const std::set<base::FilePath>& child_directories);
119
120  // Callback for DriveResourceMetadata::RemoveEntryFromParent.
121  void NotifyForRemoveEntryFromParent(
122      bool is_directory,
123      const base::FilePath& file_path,
124      const std::set<base::FilePath>& child_directories,
125      DriveFileError error,
126      const base::FilePath& parent_path);
127
128  // Refreshes DriveResourceMetadata entry that has the same resource_id as
129  // |entry_proto| with |entry_proto|. Updates changed_dirs_ as a side effect.
130  void RefreshEntry(const DriveEntryProto& entry_proto,
131                    const base::FilePath& file_path);
132
133  // Callback for DriveResourceMetadata::RefreshEntry.
134  void NotifyForRefreshEntry(
135      const base::FilePath& old_file_path,
136      DriveFileError error,
137      const base::FilePath& file_path,
138      scoped_ptr<DriveEntryProto> entry_proto);
139
140  // Updates the root directory entry. upload_url and changestamp will be
141  // updated. Calls |closure| upon completion regardless of whether the
142  // update was successful or not.  |closure| must not be null.
143  void UpdateRootEntry(const base::Closure& closure);
144
145  // Part of UpdateRootEntry(). Called after
146  // DriveResourceMetadata::GetEntryInfoByPath is complete. Updates the root
147  // proto, and refreshes the root entry with the proto.
148  void UpdateRootEntryAfterGetEntry(const base::Closure& closure,
149                                    DriveFileError error,
150                                    scoped_ptr<DriveEntryProto> root_proto);
151
152  // Part of UpdateRootEntry(). Called after
153  // DriveResourceMetadata::RefreshEntry() is complete. Calls OnComplete() to
154  // finish the change list processing.
155  void UpdateRootEntryAfterRefreshEntry(const base::Closure& closure,
156                                        DriveFileError error,
157                                        const base::FilePath& root_path,
158                                        scoped_ptr<DriveEntryProto> root_proto);
159
160  // Runs after all entries have been processed.
161  void OnComplete();
162
163  // Reset the state of this object.
164  void Clear();
165
166  DriveResourceMetadata* resource_metadata_;  // Not owned.
167
168  DriveEntryProtoMap entry_proto_map_;
169  std::set<base::FilePath> changed_dirs_;
170  GURL root_upload_url_;
171  int64 largest_changestamp_;
172  base::Closure on_complete_callback_;
173
174  // Note: This should remain the last member so it'll be destroyed and
175  // invalidate its weak pointers before any other members are destroyed.
176  base::WeakPtrFactory<ChangeListProcessor> weak_ptr_factory_;
177  DISALLOW_COPY_AND_ASSIGN(ChangeListProcessor);
178};
179
180}  // namespace drive
181
182#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_PROCESSOR_H_
183