create_directory_operation.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2013 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_FILE_SYSTEM_CREATE_DIRECTORY_OPERATION_H_
6#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_CREATE_DIRECTORY_OPERATION_H_
7
8#include "base/basictypes.h"
9#include "base/files/file_path.h"
10#include "base/gtest_prod_util.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "chrome/browser/chromeos/drive/drive_file_error.h"
14#include "chrome/browser/google_apis/gdata_errorcode.h"
15#include "googleurl/src/gurl.h"
16
17namespace google_apis {
18
19class ResourceEntry;
20
21}  // namespace google_apis
22
23namespace drive {
24
25class DriveEntryProto;
26class DriveResourceMetadata;
27class DriveScheduler;
28
29namespace file_system {
30
31class OperationObserver;
32
33// This class encapsulates the drive Create Directory function.  It is
34// responsible for sending the request to the drive API, then updating the
35// local state and metadata to reflect the new state.
36class CreateDirectoryOperation {
37 public:
38  CreateDirectoryOperation(DriveScheduler* drive_scheduler,
39                           DriveResourceMetadata* metadata,
40                           OperationObserver* observer);
41  ~CreateDirectoryOperation();
42
43  // Creates a new directory at |directory_path|.
44  // If |is_exclusive| is true, an error is raised in case a directory exists
45  // already at the |directory_path|.
46  // If |is_recursive| is true, the invocation creates parent directories as
47  // needed just like mkdir -p does.
48  // Invokes |callback| when finished with the result of the operation.
49  // |callback| must not be null.
50  void CreateDirectory(const base::FilePath& directory_path,
51                       bool is_exclusive,
52                       bool is_recursive,
53                       const FileOperationCallback& callback);
54 private:
55  friend class CreateDirectoryOperationTest;
56  FRIEND_TEST_ALL_PREFIXES(CreateDirectoryOperationTest,
57                           FindFirstMissingParentDirectory);
58
59  // Defines set of parameters passes to intermediate callbacks during
60  // execution of CreateDirectory() method.
61  struct CreateDirectoryParams;
62
63  // Defines possible search results of FindFirstMissingParentDirectory().
64  enum FindFirstMissingParentDirectoryError {
65    // Target directory found, it's not a directory.
66    FIND_FIRST_FOUND_INVALID,
67    // Found missing directory segment while searching for given directory.
68    FIND_FIRST_FOUND_MISSING,
69    // Found target directory, it already exists.
70    FIND_FIRST_DIRECTORY_ALREADY_PRESENT,
71  };
72
73  // The result struct for FindFirstMissingParentDirectory().
74  struct FindFirstMissingParentDirectoryResult {
75    FindFirstMissingParentDirectoryResult();
76    ~FindFirstMissingParentDirectoryResult();
77
78    // Initializes the struct.
79    void Init(FindFirstMissingParentDirectoryError error,
80              base::FilePath first_missing_parent_path,
81              const std::string& last_dir_resource_id);
82
83    FindFirstMissingParentDirectoryError error;
84    // The following two fields are provided when |error| is set to
85    // FIND_FIRST_FOUND_MISSING. Otherwise, the two fields are undefined.
86
87    // Suppose "drive/foo/bar/baz/qux" is being checked, and only
88    // "drive/foo/bar" is present, "drive/foo/bar/baz" is the first missing
89    // parent path.
90    base::FilePath first_missing_parent_path;
91
92    // The resource id of the last found directory. In the above example, the
93    // resource id of "drive/foo/bar".
94    std::string last_dir_resource_id;
95  };
96
97  // Callback for FindFirstMissingParentDirectory().
98  typedef base::Callback<void(
99      const FindFirstMissingParentDirectoryResult& result)>
100      FindFirstMissingParentDirectoryCallback;
101
102  // Params for FindFirstMissingParentDirectory().
103  struct FindFirstMissingParentDirectoryParams;
104
105  // Part of CreateDirectory(). Called after
106  // FindFirstMissingParentDirectory() is complete.
107  // |callback| must not be null.
108  void CreateDirectoryAfterFindFirstMissingPath(
109      scoped_ptr<CreateDirectoryParams> params,
110      const FindFirstMissingParentDirectoryResult& result);
111
112  // Callback for handling directory create requests. Adds the directory
113  // represented by |entry| to the local filesystem.
114  void AddNewDirectory(scoped_ptr<CreateDirectoryParams> params,
115                       const base::FilePath& created_directory_path,
116                       google_apis::GDataErrorCode status,
117                       scoped_ptr<google_apis::ResourceEntry> entry);
118
119  // Callback for DriveResourceMetadata::AddEntryToDirectory. Continues the
120  // recursive creation of a directory path by calling CreateDirectory again.
121  void ContinueCreateDirectory(scoped_ptr<CreateDirectoryParams> params,
122                               const base::FilePath& created_directory_path,
123                               DriveFileError error,
124                               const base::FilePath& moved_file_path);
125
126  // Finds the first missing parent directory of |directory_path|.
127  // |callback| must not be null.
128  void FindFirstMissingParentDirectory(
129      const base::FilePath& directory_path,
130      const FindFirstMissingParentDirectoryCallback& callback);
131
132  // Helper function for FindFirstMissingParentDirectory, for recursive search
133  // for first missing parent.
134  void FindFirstMissingParentDirectoryInternal(
135      scoped_ptr<FindFirstMissingParentDirectoryParams> params);
136
137  // Callback for ResourceMetadata::GetEntryInfoByPath from
138  // FindFirstMissingParentDirectory.
139  void ContinueFindFirstMissingParentDirectory(
140      scoped_ptr<FindFirstMissingParentDirectoryParams> params,
141      DriveFileError error,
142      scoped_ptr<DriveEntryProto> entry_proto);
143
144  DriveScheduler* drive_scheduler_;
145  DriveResourceMetadata* metadata_;
146  OperationObserver* observer_;
147
148  // WeakPtrFactory bound to the UI thread.
149  // Note: This should remain the last member so it'll be destroyed and
150  // invalidate the weak pointers before any other members are destroyed.
151  base::WeakPtrFactory<CreateDirectoryOperation> weak_ptr_factory_;
152
153  DISALLOW_COPY_AND_ASSIGN(CreateDirectoryOperation);
154};
155
156}  // namespace file_system
157}  // namespace drive
158
159#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_CREATE_DIRECTORY_OPERATION_H_
160