Merge pull request #64 in ITERATE/cyberduck from feature/windows/9074 to master
[cyberduck.git] / source / ch / cyberduck / core / openstack / SwiftAttributesFeature.java
bloba44d8756ca0c7ce447b1d38bd896b905ea892701
1 package ch.cyberduck.core.openstack;
3 /*
4 * Copyright (c) 2002-2014 David Kocher. All rights reserved.
5 * http://cyberduck.io/
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.io
21 import ch.cyberduck.core.DefaultIOExceptionMappingService;
22 import ch.cyberduck.core.Path;
23 import ch.cyberduck.core.PathAttributes;
24 import ch.cyberduck.core.PathCache;
25 import ch.cyberduck.core.PathContainerService;
26 import ch.cyberduck.core.date.InvalidDateException;
27 import ch.cyberduck.core.date.RFC1123DateFormatter;
28 import ch.cyberduck.core.exception.BackgroundException;
29 import ch.cyberduck.core.features.Attributes;
30 import ch.cyberduck.core.io.Checksum;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.log4j.Logger;
35 import java.io.IOException;
37 import ch.iterate.openstack.swift.Constants;
38 import ch.iterate.openstack.swift.exception.GenericException;
39 import ch.iterate.openstack.swift.model.ContainerInfo;
40 import ch.iterate.openstack.swift.model.ObjectMetadata;
41 import ch.iterate.openstack.swift.model.Region;
43 /**
44 * @version $Id$
46 public class SwiftAttributesFeature implements Attributes {
47 private static final Logger log = Logger.getLogger(SwiftAttributesFeature.class);
49 private SwiftSession session;
51 private PathContainerService containerService
52 = new SwiftPathContainerService();
54 private RFC1123DateFormatter dateParser
55 = new RFC1123DateFormatter();
57 private SwiftRegionService regionService;
59 public SwiftAttributesFeature(SwiftSession session) {
60 this(session, new SwiftRegionService(session));
63 public SwiftAttributesFeature(final SwiftSession session, final SwiftRegionService regionService) {
64 this.session = session;
65 this.regionService = regionService;
68 @Override
69 public PathAttributes find(final Path file) throws BackgroundException {
70 final Region region = regionService.lookup(file);
71 try {
72 if(containerService.isContainer(file)) {
73 final ContainerInfo info = session.getClient().getContainerInfo(region,
74 containerService.getContainer(file).getName());
75 final PathAttributes attributes = new PathAttributes();
76 attributes.setSize(info.getTotalSize());
77 attributes.setRegion(info.getRegion().getRegionId());
78 return attributes;
80 if(file.isFile()) {
81 final PathAttributes attributes = new PathAttributes();
82 if(file.isFile()) {
83 final ObjectMetadata metadata = session.getClient().getObjectMetaData(region,
84 containerService.getContainer(file).getName(), containerService.getKey(file));
85 attributes.setSize(Long.valueOf(metadata.getContentLength()));
86 try {
87 attributes.setModificationDate(dateParser.parse(metadata.getLastModified()).getTime());
89 catch(InvalidDateException e) {
90 log.warn(String.format("%s is not RFC 1123 format %s", metadata.getLastModified(), e.getMessage()));
92 if(StringUtils.isNotBlank(metadata.getETag())) {
93 final String etag = StringUtils.removePattern(metadata.getETag(), "\"");
94 attributes.setETag(etag);
95 if(metadata.getMetaData().containsKey(Constants.X_STATIC_LARGE_OBJECT)) {
96 // For manifest files, the ETag in the response for a GET or HEAD on the manifest file is the MD5 sum of
97 // the concatenated string of ETags for each of the segments in the manifest.
98 attributes.setChecksum(null);
100 else {
101 attributes.setChecksum(Checksum.parse(etag));
105 else {
106 if(log.isDebugEnabled()) {
107 log.debug(String.format("Return blank attributes for directory delimiter %s", file));
110 return attributes;
112 if(log.isDebugEnabled()) {
113 log.debug(String.format("Return blank attributes for directory delimiter %s", file));
115 return new PathAttributes();
117 catch(GenericException e) {
118 throw new SwiftExceptionMappingService().map("Failure to read attributes of {0}", e, file);
120 catch(IOException e) {
121 throw new DefaultIOExceptionMappingService().map("Failure to read attributes of {0}", e, file);
125 @Override
126 public Attributes withCache(final PathCache cache) {
127 return this;