1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.vafer.jdeb.mapping;
17
18 import java.io.BufferedReader;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27 import org.apache.tools.tar.TarEntry;
28
29
30
31
32
33
34
35 public final class LsMapper implements Mapper {
36
37 private final Map mapping;
38
39
40 public final static class ParseError extends Exception {
41
42 private static final long serialVersionUID = 1L;
43
44 public ParseError() {
45 super();
46 }
47
48 public ParseError(String message, Throwable cause) {
49 super(message, cause);
50 }
51
52 public ParseError(String message) {
53 super(message);
54 }
55
56 public ParseError(Throwable cause) {
57 super(cause);
58 }
59
60 };
61
62 public LsMapper( final InputStream pInput ) throws IOException, ParseError {
63 mapping = parse(pInput);
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 final private Pattern basePattern = Pattern.compile("^\\./(.*):$");
80 final private Pattern totalPattern = Pattern.compile("^total ([0-9]+)$");
81 final private Pattern dirPattern = Pattern.compile("^d([rwx-]{9})\\s+([0-9]+)\\s+(\\S*)\\s+(\\S*)\\s+([0-9]+)\\s+(.*)\\s+[\\.]{1,2}$");
82 final private Pattern filePattern = Pattern.compile("^([d-])([rwx-]{9})\\s+([0-9]+)\\s+(\\S*)\\s+(\\S*)\\s+([0-9]+)\\s+(.*)\\s+(.*)$");
83 final private Pattern newlinePattern = Pattern.compile("$");
84
85 private String readBase( final BufferedReader reader ) throws IOException, ParseError {
86 final String line = reader.readLine();
87 if (line == null) {
88 return null;
89 }
90 final Matcher matcher = basePattern.matcher(line);
91 if (!matcher.matches()) {
92 throw new ParseError("expected base line but got \"" + line + "\"");
93 }
94 return matcher.group(1);
95 }
96
97 private String readTotal( final BufferedReader reader ) throws IOException, ParseError {
98 final String line = reader.readLine();
99 final Matcher matcher = totalPattern.matcher(line);
100 if (!matcher.matches()) {
101 throw new ParseError("expected total line but got \"" + line + "\"");
102 }
103 return matcher.group(1);
104 }
105
106 private TarEntry readDir( final BufferedReader reader, final String base ) throws IOException, ParseError {
107 final String current = reader.readLine();
108 final Matcher currentMatcher = dirPattern.matcher(current);
109 if (!currentMatcher.matches()) {
110 throw new ParseError("expected dirline but got \"" + current + "\"");
111 }
112
113 final String parent = reader.readLine();
114 final Matcher parentMatcher = dirPattern.matcher(parent);
115 if (!parentMatcher.matches()) {
116 throw new ParseError("expected dirline but got \"" + parent + "\"");
117 }
118
119 final TarEntry entry = new TarEntry(base);
120
121 entry.setMode(convertModeFromString(currentMatcher.group(1)));
122 entry.setUserName(currentMatcher.group(3));
123 entry.setGroupName(currentMatcher.group(4));
124
125 return entry;
126 }
127
128
129 private int convertModeFromString( final String mode ) {
130
131 final char[] m = mode.toCharArray();
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 int sum = 0;
150 int bit = 1;
151 for(int i=m.length-1; i>=0 ; i--) {
152 if (m[i] != '-') {
153 sum += bit;
154 }
155 bit += bit;
156 }
157 return sum;
158 }
159
160 private TarEntry readFile( final BufferedReader reader, final String base ) throws IOException, ParseError {
161
162 while(true) {
163 final String line = reader.readLine();
164
165 if (line == null) {
166 return null;
167 }
168
169 final Matcher currentMatcher = filePattern.matcher(line);
170 if (!currentMatcher.matches()) {
171 final Matcher newlineMatcher = newlinePattern.matcher(line);
172 if (newlineMatcher.matches()) {
173 return null;
174 }
175 throw new ParseError("expected file line but got \"" + line + "\"");
176 }
177
178 final String type = currentMatcher.group(1);
179 if (type.startsWith("-")) {
180 final TarEntry entry = new TarEntry(base + "/" + currentMatcher.group(8));
181
182 entry.setMode(convertModeFromString(currentMatcher.group(2)));
183 entry.setUserName(currentMatcher.group(4));
184 entry.setGroupName(currentMatcher.group(5));
185
186 return entry;
187 }
188 }
189
190 }
191
192 private Map parse( final InputStream pInput ) throws IOException, ParseError {
193 final Map mapping = new HashMap();
194
195 final BufferedReader reader = new BufferedReader(new InputStreamReader(pInput));
196
197 boolean first = true;
198 while(true) {
199
200 final String base;
201 if (first) {
202 base = "";
203 first = false;
204 } else {
205 base = readBase(reader);
206 if (base == null) {
207 break;
208 }
209 }
210
211 readTotal(reader);
212 final TarEntry dir = readDir(reader, base);
213 mapping.put(dir.getName(), dir);
214
215 while(true) {
216 final TarEntry file = readFile(reader, base);
217
218 if (file == null) {
219 break;
220 }
221
222 mapping.put(file.getName(), file);
223 }
224 }
225
226 return mapping;
227 }
228
229 public TarEntry map( final TarEntry pEntry ) {
230
231 final TarEntry entry = (TarEntry) mapping.get(pEntry.getName());
232
233 if (entry != null) {
234
235 final TarEntry newEntry = new TarEntry(entry.getName());
236 newEntry.setUserId(entry.getUserId());
237 newEntry.setGroupId(entry.getGroupId());
238 newEntry.setUserName(entry.getUserName());
239 newEntry.setGroupName(entry.getGroupName());
240 newEntry.setMode(entry.getMode());
241 newEntry.setSize(entry.getSize());
242
243 return newEntry;
244 }
245
246 return pEntry;
247 }
248
249 }