Add callback for delete operation.
[cyberduck.git] / source / ch / cyberduck / core / openstack / SwiftMultipleDeleteFeature.java
blob763c4d79d9094011886198a3996ba23cec0ec8b1
1 package ch.cyberduck.core.openstack;
3 /*
4 * Copyright (c) 2002-2013 David Kocher. All rights reserved.
5 * http://cyberduck.ch/
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * Bug fixes, suggestions and comments should be sent to:
18 * feedback@cyberduck.ch
21 import ch.cyberduck.core.DefaultIOExceptionMappingService;
22 import ch.cyberduck.core.LoginCallback;
23 import ch.cyberduck.core.Path;
24 import ch.cyberduck.core.PathContainerService;
25 import ch.cyberduck.core.collections.Partition;
26 import ch.cyberduck.core.exception.BackgroundException;
27 import ch.cyberduck.core.exception.InteroperabilityException;
28 import ch.cyberduck.core.features.Delete;
29 import ch.cyberduck.core.preferences.PreferencesFactory;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
37 import ch.iterate.openstack.swift.exception.GenericException;
38 import ch.iterate.openstack.swift.model.Region;
40 /**
41 * @version $Id$
43 public class SwiftMultipleDeleteFeature implements Delete {
45 private SwiftSession session;
47 private PathContainerService containerService
48 = new SwiftPathContainerService();
50 private SwiftSegmentService segmentService;
52 private SwiftRegionService regionService;
54 public SwiftMultipleDeleteFeature(final SwiftSession session) {
55 this(session, new SwiftSegmentService(session), new SwiftRegionService(session));
58 public SwiftMultipleDeleteFeature(final SwiftSession session, final SwiftSegmentService segmentService,
59 final SwiftRegionService regionService) {
60 this.segmentService = segmentService;
61 this.regionService = regionService;
62 this.session = session;
65 @Override
66 public void delete(final List<Path> files, final LoginCallback prompt, final Callback callback) throws BackgroundException {
67 if(files.size() == 1) {
68 new SwiftDeleteFeature(session).delete(files, prompt, callback);
70 else {
71 final Map<Path, List<String>> containers = new HashMap<Path, List<String>>();
72 for(Path file : files) {
73 if(containerService.isContainer(file)) {
74 continue;
76 callback.delete(file);
77 final Path container = containerService.getContainer(file);
78 if(containers.containsKey(container)) {
79 containers.get(container).add(containerService.getKey(file));
81 else {
82 final List<String> keys = new ArrayList<String>();
83 keys.add(containerService.getKey(file));
84 // Collect a list of existing segments. Must do this before deleting the manifest file.
85 for(Path segment : segmentService.list(file)) {
86 keys.add(containerService.getKey(segment));
88 containers.put(container, keys);
91 try {
92 for(Map.Entry<Path, List<String>> container : containers.entrySet()) {
93 final Region region = regionService.lookup(container.getKey());
94 final List<String> keys = container.getValue();
95 for(List<String> partition : new Partition<String>(keys, PreferencesFactory.get().getInteger("openstack.delete.multiple.partition"))) {
96 session.getClient().deleteObjects(region, container.getKey().getName(), partition);
100 catch(GenericException e) {
101 if(new SwiftExceptionMappingService().map(e) instanceof InteroperabilityException) {
102 new SwiftDeleteFeature(session).delete(files, prompt, callback);
103 return;
105 else {
106 throw new SwiftExceptionMappingService().map("Cannot delete {0}", e, files.iterator().next());
109 catch(IOException e) {
110 throw new DefaultIOExceptionMappingService().map("Cannot delete {0}", e, files.iterator().next());
112 for(Path file : files) {
113 if(containerService.isContainer(file)) {
114 callback.delete(file);
115 // Finally delete bucket itself
116 try {
117 session.getClient().deleteContainer(new SwiftRegionService(session).lookup(file),
118 containerService.getContainer(file).getName());
120 catch(GenericException e) {
121 throw new SwiftExceptionMappingService().map("Cannot delete {0}", e, file);
123 catch(IOException e) {
124 throw new DefaultIOExceptionMappingService().map("Cannot delete {0}", e, file);