1 package ch
.cyberduck
.core
.openstack
;
4 * Copyright (c) 2002-2014 David Kocher. All rights reserved.
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
;
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
;
69 public PathAttributes
find(final Path file
) throws BackgroundException
{
70 final Region region
= regionService
.lookup(file
);
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());
81 final PathAttributes attributes
= new PathAttributes();
83 final ObjectMetadata metadata
= session
.getClient().getObjectMetaData(region
,
84 containerService
.getContainer(file
).getName(), containerService
.getKey(file
));
85 attributes
.setSize(Long
.valueOf(metadata
.getContentLength()));
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);
101 attributes
.setChecksum(Checksum
.parse(etag
));
106 if(log
.isDebugEnabled()) {
107 log
.debug(String
.format("Return blank attributes for directory delimiter %s", file
));
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
);
126 public Attributes
withCache(final PathCache cache
) {