1 package ch
.cyberduck
.core
;
4 * Copyright (c) 2008 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 * dkocher@cyberduck.ch
21 import ch
.cyberduck
.core
.preferences
.Preferences
;
22 import ch
.cyberduck
.core
.preferences
.PreferencesFactory
;
24 import org
.apache
.commons
.lang3
.StringUtils
;
25 import org
.apache
.log4j
.Logger
;
27 import java
.text
.MessageFormat
;
28 import java
.util
.ArrayList
;
29 import java
.util
.EnumSet
;
30 import java
.util
.List
;
31 import java
.util
.Locale
;
34 * Description of an archive format
38 public abstract class Archive
{
39 private static final Logger log
= Logger
.getLogger(Archive
.class);
41 private Preferences preferences
42 = PreferencesFactory
.get();
44 public static final Archive TAR
45 = new Archive("tar") {
47 public String
getDescription() {
48 return LocaleFactory
.localizedString("tar archive", "Archive");
52 public static final Archive TARGZ
53 = new Archive("tar.gz") {
55 public String
getDescription() {
56 return LocaleFactory
.localizedString("gzip compressed tar archive", "Archive");
60 public String
[] getExtensions() {
61 return new String
[]{this.getIdentifier(), "tgz"};
65 public static final Archive TARBZ2
66 = new Archive("tar.bz2") {
68 public String
getDescription() {
69 return LocaleFactory
.localizedString("bzip2 compressed tar archive", "Archive");
73 public String
[] getExtensions() {
74 return new String
[]{this.getIdentifier(), "tbz", "tbz2"};
78 public static final Archive ZIP
79 = new Archive("zip") {
81 public String
getDescription() {
82 return LocaleFactory
.localizedString("ZIP archive", "Archive");
86 public static final Archive GZIP
89 public String
getDescription() {
90 return LocaleFactory
.localizedString("gzip compressed tar archive", "Archive");
94 public String
[] getExtensions() {
95 return new String
[]{this.getIdentifier(), "gzip"};
99 public static final Archive BZ2
100 = new Archive("bz2") {
102 public String
getDescription() {
103 return LocaleFactory
.localizedString("bzip2 compressed archive", "Archive");
107 public String
[] getExtensions() {
108 return new String
[]{this.getIdentifier(), "bz", "bzip2"};
113 * @return The default archiver set in the Preferences
115 public static Archive
getDefault() {
116 return Archive
.forName(PreferencesFactory
.get().getProperty("archive.default"));
120 * @return List of archive types
122 public static Archive
[] getKnownArchives() {
123 return new Archive
[]{TAR
, TARGZ
, TARBZ2
, ZIP
};
129 * @param name Identifier
130 * @return Archive description
132 public static Archive
forName(final String name
) {
133 if(StringUtils
.isNotBlank(name
)) {
134 for(Archive archive
: getKnownArchives()) {
135 for(String extension
: archive
.getExtensions()) {
136 if(name
.toLowerCase(Locale
.ROOT
).endsWith(extension
.toLowerCase(Locale
.ROOT
))) {
142 log
.fatal(String
.format("Unknown archive %s", name
));
147 * Typical filename extension. The default
149 private String identifier
;
152 * @param extension Filename extension for archive format
154 private Archive(final String extension
) {
155 this.identifier
= extension
;
159 * @return Known filename extensions for archive format
161 public String
[] getExtensions() {
162 return new String
[]{this.getIdentifier()};
166 * @return Archive identifier
168 public String
getIdentifier() {
172 public abstract String
getDescription();
176 * @return Archived path for files
178 public Path
getArchive(final List
<Path
> files
) {
179 if(files
.size() == 0) {
182 if(files
.size() == 1) {
183 return new Path(files
.get(0).getParent(),
184 String
.format("%s.%s", files
.get(0).getName(), this.getIdentifier()),
185 EnumSet
.of(Path
.Type
.file
));
187 return new Path(files
.get(0).getParent(),
188 String
.format("%s.%s", LocaleFactory
.localizedString("Archive", "Archive"), this.getIdentifier()),
189 EnumSet
.of(Path
.Type
.file
));
194 * @return Expanded filenames
196 public List
<Path
> getExpanded(final List
<Path
> files
) {
197 final List
<Path
> expanded
= new ArrayList
<Path
>();
198 for(Path file
: files
) {
199 expanded
.add(new Path(file
.getParent(),
200 StringUtils
.remove(file
.getName(), String
.format(".%s", this.getIdentifier())), EnumSet
.of(Path
.Type
.file
)));
206 * @param files Files to archive
207 * @return Name of archive
209 public String
getTitle(final List
<Path
> files
) {
210 final Path archive
= this.getArchive(files
);
211 if(null == archive
) {
212 return this.getIdentifier();
214 return archive
.getName();
218 * @param workdir Working directory
219 * @param files Files to archive
220 * @return Archive command
222 public String
getCompressCommand(final Path workdir
, final List
<Path
> files
) {
223 final StringBuilder archive
= new StringBuilder();
224 if(files
.size() == 1) {
225 archive
.append(this.escape(files
.get(0).getAbsolute()));
228 // Use default filename
229 archive
.append(this.escape(files
.get(0).getParent().getAbsolute())).append(Path
.DELIMITER
).append("Archive");
231 final List
<String
> command
= new ArrayList
<String
>();
232 for(Path path
: files
) {
233 command
.add(this.escape(PathRelativizer
.relativize(workdir
.getAbsolute(), path
.getAbsolute())));
235 return MessageFormat
.format(preferences
.getProperty(String
.format("archive.command.create.%s", this.getIdentifier())),
236 archive
.toString(), StringUtils
.join(command
, " "), this.escape(workdir
.getAbsolute()));
240 * @param path Filename
241 * @return Unarchive command
243 public String
getDecompressCommand(final Path path
) {
244 return MessageFormat
.format(preferences
.getProperty(String
.format("archive.command.expand.%s", this.getIdentifier())),
245 this.escape(path
.getAbsolute()), this.escape(path
.getParent().getAbsolute()));
251 * @param path Filename
252 * @return Escaped whitespace in path
254 protected String
escape(final String path
) {
255 final StringBuilder escaped
= new StringBuilder();
256 for(char c
: path
.toCharArray()) {
257 if(StringUtils
.isAlphanumeric(String
.valueOf(c
))
258 || c
== Path
.DELIMITER
) {
262 escaped
.append("\\").append(c
);
265 return escaped
.toString();
269 * @param filename File extension to match with archive format
270 * @return True if a known file extension for compressed archives
272 public static boolean isArchive(final String filename
) {
273 if(StringUtils
.isNotBlank(filename
)) {
274 for(Archive archive
: getKnownArchives()) {
275 for(String extension
: archive
.getExtensions()) {
276 if(filename
.endsWith(extension
)) {