blob: 12eba4f95d7334e7f649211f4c21c29512c7a6bf [file] [log] [blame]
Stuart McCullochbb014372012-06-07 21:57:32 +00001package aQute.libg.clauses;
2
3import java.util.*;
4
5import aQute.libg.log.*;
6import aQute.libg.qtokens.*;
7
8public class Clauses extends LinkedHashMap<String,Map<String,String>>{
9 private static final long serialVersionUID = 1L;
10
11 /**
12 * Standard OSGi header parser. This parser can handle the format clauses
13 * ::= clause ( ',' clause ) + clause ::= name ( ';' name ) (';' key '='
14 * value )
15 *
16 * This is mapped to a Map { name => Map { attr|directive => value } }
17 *
18 * @param value
19 * @return
20 * @throws MojoExecutionException
21 */
22 static public Clauses parse(String value, Logger logger) {
23 if (value == null || value.trim().length() == 0)
24 return new Clauses();
25
26 Clauses result = new Clauses();
27 QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
28 char del;
29 do {
30 boolean hadAttribute = false;
31 Clause clause = new Clause();
32 List<String> aliases = new ArrayList<String>();
33 aliases.add(qt.nextToken());
34 del = qt.getSeparator();
35 while (del == ';') {
36 String adname = qt.nextToken();
37 if ((del = qt.getSeparator()) != '=') {
38 if (hadAttribute)
39 throw new IllegalArgumentException(
40 "Header contains name field after attribute or directive: "
41 + adname + " from " + value);
42 aliases.add(adname);
43 } else {
44 String advalue = qt.nextToken();
45 clause.put(adname, advalue);
46 del = qt.getSeparator();
47 hadAttribute = true;
48 }
49 }
50 for (Iterator<String> i = aliases.iterator(); i.hasNext();) {
51 String packageName = i.next();
52 if (result.containsKey(packageName)) {
53 if (logger != null)
54 logger
55 .warning("Duplicate package name in header: "
56 + packageName
57 + ". Multiple package names in one clause not supported in Bnd.");
58 } else
59 result.put(packageName, clause);
60 }
61 } while (del == ',');
62 return result;
63 }
64
65}