1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.javadpkg.impl;
20
21 import java.io.BufferedReader;
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.util.List;
26
27 import net.sourceforge.javadpkg.Context;
28 import net.sourceforge.javadpkg.GlobalConstants;
29 import net.sourceforge.javadpkg.ParseException;
30 import net.sourceforge.javadpkg.Symbols;
31 import net.sourceforge.javadpkg.SymbolsParser;
32 import net.sourceforge.javadpkg.control.PackageDependency;
33 import net.sourceforge.javadpkg.control.PackageDependencyParser;
34 import net.sourceforge.javadpkg.control.PackageVersion;
35 import net.sourceforge.javadpkg.control.PackageVersionParser;
36 import net.sourceforge.javadpkg.control.impl.PackageDependencyParserImpl;
37 import net.sourceforge.javadpkg.control.impl.PackageNameParserImpl;
38 import net.sourceforge.javadpkg.control.impl.PackageVersionParserImpl;
39 import net.sourceforge.javadpkg.control.impl.PackageVersionRelationOperatorParserImpl;
40 import net.sourceforge.javadpkg.field.Field;
41 import net.sourceforge.javadpkg.field.FieldParser;
42 import net.sourceforge.javadpkg.field.impl.FieldParserImpl;
43 import net.sourceforge.javadpkg.io.DataSource;
44 import net.sourceforge.javadpkg.io.impl.DataStreamSource;
45
46
47
48
49
50
51
52
53
54
55 public class SymbolsParserImpl implements SymbolsParser, GlobalConstants {
56
57
58
59 private PackageVersionParser packageVersionParser;
60
61 private PackageDependencyParser packageDependencyParser;
62
63 private FieldParser fieldParser;
64
65
66
67
68
69
70
71 public SymbolsParserImpl() {
72 super();
73
74 this.packageVersionParser = new PackageVersionParserImpl();
75 this.packageDependencyParser = new PackageDependencyParserImpl(new PackageNameParserImpl(),
76 new PackageVersionRelationOperatorParserImpl(), this.packageVersionParser);
77 this.fieldParser = new FieldParserImpl(false, false, false);
78 }
79
80
81 @Override
82 public Symbols parseSymbols(DataSource source, Context context) throws IOException, ParseException {
83 SymbolsImpl symbols = null;
84 String line;
85 boolean contentParsed = false;
86 SymbolsEntryImpl entry = null;
87
88
89 if (source == null)
90 throw new IllegalArgumentException("Argument source is null.");
91 if (context == null)
92 throw new IllegalArgumentException("Argument context is null.");
93
94 symbols = new SymbolsImpl();
95 try {
96 try (BufferedReader reader = new BufferedReader(new InputStreamReader(source.getInputStream(), UTF_8_CHARSET))) {
97 while ((line = reader.readLine()) != null) {
98
99 if (line.startsWith("| ")) {
100 if (entry == null)
101 throw new ParseException("Symbol line |" + line + "| of symbols from source |" + source.getName()
102 + "| contains an alternative dependency template also no initial line of an entry has been read.");
103 if (contentParsed)
104 throw new ParseException("Symbol line |" + line + "| of symbols from source |" + source.getName()
105 + "| contains an alternative dependency template also symbols have been already read.");
106 this.parseAlternativeDependencyTemplate(source, entry, line);
107 }
108
109 else if (line.startsWith(" ")) {
110 if (entry == null)
111 throw new ParseException("Symbol line |" + line + "| of symbols from source |" + source.getName()
112 + "| contains a symbol also no initial line of an entry has been read.");
113 this.parseSymbol(source, context, entry, line);
114 contentParsed = true;
115 }
116
117 else if (line.startsWith("* ")) {
118 if (entry == null)
119 throw new ParseException("Symbol line |" + line + "| of symbols from source |" + source.getName()
120 + "| contains a meta data field also no initial line of an entry has been read.");
121 this.parseMetaData(source, context, entry, line);
122 contentParsed = true;
123 }
124
125 else {
126 entry = this.parseInitialLine(source, context, line);
127 symbols.addEntry(entry);
128 contentParsed = false;
129 }
130 }
131 }
132 } catch (IOException e) {
133 throw new IOException(
134 "Couldn't read the shared libraries from source |" + source.getName() + "|: " + e.getMessage());
135 }
136 if (entry == null)
137 throw new ParseException("The shared libraries from source |" + source.getName() + "| were empty.");
138 return symbols;
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 private SymbolsEntryImpl parseInitialLine(DataSource source, Context context, String line) throws ParseException {
158 SymbolsEntryImpl entry;
159 String[] parts;
160 String libraryName, dependencyTemplate;
161 PackageDependency dependency = null;
162
163
164 parts = line.split(" ", 2);
165 if (parts.length != 2)
166 throw new ParseException("Couldn't split line |" + line + "| of symbols from source |" + source.getName()
167 + "| into 3 parts. Got " + parts.length);
168 libraryName = parts[0];
169 dependencyTemplate = parts[1];
170 if (!dependencyTemplate.endsWith("#MINVER#")) {
171 try {
172 dependency = this.packageDependencyParser.parsePackageDependency(dependencyTemplate, context);
173 } catch (ParseException e) {
174 throw new ParseException("Couldn't parse dependency |" + dependencyTemplate + "| from |" + line
175 + "| of symbols from source |" + source.getName() + "| into 3 parts. Got " + parts.length);
176 }
177 }
178
179 if (dependency == null) {
180 entry = new SymbolsEntryImpl(libraryName, dependencyTemplate);
181 } else {
182 entry = new SymbolsEntryImpl(libraryName, dependency);
183 }
184 return entry;
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 private void parseAlternativeDependencyTemplate(DataSource source, SymbolsEntryImpl entry, String line)
203 throws ParseException {
204
205 String alternativeDependencyTemplate;
206
207
208 alternativeDependencyTemplate = line.substring(2);
209 entry.setAlternativeDependencyValue(alternativeDependencyTemplate);
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 private void parseSymbol(DataSource source, Context context, SymbolsEntryImpl entry, String line) throws ParseException {
230 String[] parts;
231 PackageVersion version;
232 String symbolName, symbolVersion;
233
234
235 parts = line.trim().split(" ", 3);
236 if ((parts.length < 2) || (parts.length > 3))
237 throw new ParseException("Couldn't split line |" + line + "| of symbols from source |" + source.getName()
238 + "| into 2 or 3 parts. Got " + parts.length);
239
240 try {
241 version = this.packageVersionParser.parsePackageVersion(parts[1], context);
242 } catch (ParseException e) {
243 throw new ParseException("Couldn't parse version |" + parts[1] + "| from |" + line + "| of symbols from source |"
244 + source.getName() + "|: " + e.getMessage(), e);
245 }
246 parts = parts[0].split("@", 2);
247 if (parts.length != 2)
248 throw new ParseException("Couldn't split |" + line + "| of symbols from source |" + source.getName()
249 + "| into 2 parts. Got " + parts.length);
250 symbolName = parts[0];
251 symbolVersion = parts[1];
252
253 entry.addSymbol(symbolName, symbolVersion, version);
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 private void parseMetaData(DataSource source, Context context, SymbolsEntryImpl entry, String line) throws ParseException {
274 String trimmedLine;
275 List<Field> fields;
276 Field field;
277 PackageDependency dependency;
278
279
280 trimmedLine = line.substring(2);
281 try {
282 try (DataSource fieldSource = new DataStreamSource(new ByteArrayInputStream(trimmedLine.getBytes()), "field",
283 false)) {
284 fields = this.fieldParser.parseFieldsAsList(fieldSource, context);
285 }
286 } catch (IOException | ParseException e) {
287 throw new ParseException("Couldn't parse meta data field in line |" + line + "| of symbols from source |"
288 + source.getName() + "|: " + e.getMessage(), e);
289 }
290 if (fields.isEmpty())
291 throw new ParseException("Couldn't parse meta data field in line |" + line + "| of symbols from source |"
292 + source.getName() + "|: Didn't find any field.");
293 field = fields.get(0);
294 switch (field.getName().toLowerCase()) {
295 case "build-depends-package":
296
297 try {
298 dependency = this.packageDependencyParser.parsePackageDependency(field.getValue(), context);
299 } catch (ParseException e) {
300 throw new ParseException("Couldn't parse meta data field |" + field.getName() + "| in line |" + line
301 + "| of symbols from source |" + source.getName() + "|: " + e.getMessage(), e);
302 }
303 entry.setBuildDependsPackage(dependency);
304 break;
305
306 default:
307 throw new ParseException("Found unsupported meta data field |" + field.getName() + "| in line |" + line
308 + "| of symbols from source |" + source.getName() + "|.");
309 }
310 }
311
312
313 }