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.
5 #include "components/drive/file_system/move_operation.h"
7 #include "base/sequenced_task_runner.h"
8 #include "components/drive/drive.pb.h"
9 #include "components/drive/file_change.h"
10 #include "components/drive/file_system/operation_delegate.h"
11 #include "components/drive/job_scheduler.h"
12 #include "components/drive/resource_metadata.h"
15 namespace file_system
{
18 // Looks up ResourceEntry for source entry and the destination directory.
19 FileError
UpdateLocalState(internal::ResourceMetadata
* metadata
,
20 const base::FilePath
& src_path
,
21 const base::FilePath
& dest_path
,
22 FileChange
* changed_files
,
23 std::string
* local_id
) {
25 FileError error
= metadata
->GetResourceEntryByPath(src_path
, &entry
);
26 if (error
!= FILE_ERROR_OK
)
28 *local_id
= entry
.local_id();
30 ResourceEntry parent_entry
;
31 error
= metadata
->GetResourceEntryByPath(dest_path
.DirName(), &parent_entry
);
32 if (error
!= FILE_ERROR_OK
)
35 // The parent must be a directory.
36 if (!parent_entry
.file_info().is_directory())
37 return FILE_ERROR_NOT_A_DIRECTORY
;
39 changed_files
->Update(src_path
, entry
, FileChange::CHANGE_TYPE_DELETE
);
41 // Strip the extension for a hosted document if necessary.
42 const std::string new_extension
=
43 base::FilePath(dest_path
.Extension()).AsUTF8Unsafe();
44 const bool has_hosted_document_extension
=
45 entry
.has_file_specific_info() &&
46 entry
.file_specific_info().is_hosted_document() &&
47 new_extension
== entry
.file_specific_info().document_extension();
48 const std::string new_title
=
49 has_hosted_document_extension
?
50 dest_path
.BaseName().RemoveExtension().AsUTF8Unsafe() :
51 dest_path
.BaseName().AsUTF8Unsafe();
53 entry
.set_title(new_title
);
54 entry
.set_parent_local_id(parent_entry
.local_id());
55 entry
.set_metadata_edit_state(ResourceEntry::DIRTY
);
56 entry
.set_modification_date(base::Time::Now().ToInternalValue());
57 error
= metadata
->RefreshEntry(entry
);
58 if (error
!= FILE_ERROR_OK
)
61 changed_files
->Update(dest_path
, entry
,
62 FileChange::CHANGE_TYPE_ADD_OR_UPDATE
);
68 MoveOperation::MoveOperation(base::SequencedTaskRunner
* blocking_task_runner
,
69 OperationDelegate
* delegate
,
70 internal::ResourceMetadata
* metadata
)
71 : blocking_task_runner_(blocking_task_runner
),
74 weak_ptr_factory_(this) {
77 MoveOperation::~MoveOperation() {
78 DCHECK(thread_checker_
.CalledOnValidThread());
81 void MoveOperation::Move(const base::FilePath
& src_file_path
,
82 const base::FilePath
& dest_file_path
,
83 const FileOperationCallback
& callback
) {
84 DCHECK(thread_checker_
.CalledOnValidThread());
85 DCHECK(!callback
.is_null());
87 FileChange
* changed_files
= new FileChange
;
88 std::string
* local_id
= new std::string
;
89 base::PostTaskAndReplyWithResult(
90 blocking_task_runner_
.get(),
92 base::Bind(&UpdateLocalState
,
98 base::Bind(&MoveOperation::MoveAfterUpdateLocalState
,
99 weak_ptr_factory_
.GetWeakPtr(),
101 base::Owned(changed_files
),
102 base::Owned(local_id
)));
105 void MoveOperation::MoveAfterUpdateLocalState(
106 const FileOperationCallback
& callback
,
107 const FileChange
* changed_files
,
108 const std::string
* local_id
,
110 DCHECK(thread_checker_
.CalledOnValidThread());
111 if (error
== FILE_ERROR_OK
) {
112 // Notify the change of directory.
113 delegate_
->OnFileChangedByOperation(*changed_files
);
114 delegate_
->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED
),
120 } // namespace file_system