1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.archive;
44
45 import static java.nio.charset.StandardCharsets.UTF_8;
46
47 import java.io.IOException;
48 import java.io.OutputStream;
49 import java.text.MessageFormat;
50 import java.util.Arrays;
51 import java.util.Collections;
52 import java.util.List;
53 import java.util.Map;
54
55 import org.apache.commons.compress.archivers.ArchiveOutputStream;
56 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
57 import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
58 import org.apache.commons.compress.archivers.tar.TarConstants;
59 import org.eclipse.jgit.api.ArchiveCommand;
60 import org.eclipse.jgit.archive.internal.ArchiveText;
61 import org.eclipse.jgit.lib.FileMode;
62 import org.eclipse.jgit.lib.ObjectId;
63 import org.eclipse.jgit.lib.ObjectLoader;
64 import org.eclipse.jgit.revwalk.RevCommit;
65
66
67
68
69
70 public final class TarFormat extends BaseFormat implements
71 ArchiveCommand.Format<ArchiveOutputStream> {
72 private static final List<String> SUFFIXES = Collections
73 .unmodifiableList(Arrays.asList(".tar"));
74
75
76 @Override
77 public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
78 throws IOException {
79 return createArchiveOutputStream(s,
80 Collections.<String, Object> emptyMap());
81 }
82
83
84 @Override
85 public ArchiveOutputStream createArchiveOutputStream(OutputStream s,
86 Map<String, Object> o) throws IOException {
87 TarArchiveOutputStream out = new TarArchiveOutputStream(s,
88 UTF_8.name());
89 out.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
90 out.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
91 return applyFormatOptions(out, o);
92 }
93
94
95 @Override
96 public void putEntry(ArchiveOutputStream out,
97 ObjectId tree, String path, FileMode mode, ObjectLoader loader)
98 throws IOException {
99 if (mode == FileMode.SYMLINK) {
100 final TarArchiveEntry entry = new TarArchiveEntry(
101 path, TarConstants.LF_SYMLINK);
102 entry.setLinkName(new String(loader.getCachedBytes(100), UTF_8));
103 out.putArchiveEntry(entry);
104 out.closeArchiveEntry();
105 return;
106 }
107
108
109
110 if (path.endsWith("/") && mode != FileMode.TREE)
111 throw new IllegalArgumentException(MessageFormat.format(
112 ArchiveText.get().pathDoesNotMatchMode, path, mode));
113 if (!path.endsWith("/") && mode == FileMode.TREE)
114 path = path + "/";
115
116 final TarArchiveEntry entry = new TarArchiveEntry(path);
117
118 if (tree instanceof RevCommit) {
119 long t = ((RevCommit) tree).getCommitTime() * 1000L;
120 entry.setModTime(t);
121 }
122
123 if (mode == FileMode.TREE) {
124 out.putArchiveEntry(entry);
125 out.closeArchiveEntry();
126 return;
127 }
128
129 if (mode == FileMode.REGULAR_FILE) {
130
131 } else if (mode == FileMode.EXECUTABLE_FILE) {
132 entry.setMode(mode.getBits());
133 } else {
134
135 throw new IllegalArgumentException(MessageFormat.format(
136 ArchiveText.get().unsupportedMode, mode));
137 }
138 entry.setSize(loader.getSize());
139 out.putArchiveEntry(entry);
140 loader.copyTo(out);
141 out.closeArchiveEntry();
142 }
143
144
145 @Override
146 public Iterable<String> suffixes() {
147 return SUFFIXES;
148 }
149
150
151 @Override
152 public boolean equals(Object other) {
153 return (other instanceof TarFormat);
154 }
155
156
157 @Override
158 public int hashCode() {
159 return getClass().hashCode();
160 }
161 }