1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.test.util;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29
30
31
32
33
34 class NodeDefinition {
35
36 static final String ID = "\\(([-_a-zA-Z0-9]+)\\)";
37
38 static final String IDREF = "\\^([-_a-zA-Z0-9]+)";
39
40 static final String COORDS = "([^: \\(]+):([^: ]+)(?::([^: ]*)(?::([^: ]+))?)?:([^: \\[\\(<]+)";
41
42 private static final String COORDS_NC = NodeDefinition.COORDS.replaceAll("\\((?=\\[)", "(?:");
43
44 private static final String RANGE_NC = "[\\(\\[][^\\(\\)\\[\\]]+[\\)\\]]";
45
46 static final String RANGE = "(" + RANGE_NC + ")";
47
48 static final String SCOPE = "(?:scope\\s*=\\s*)?((?!optional)[-_a-zA-Z0-9]+)(?:<([-_a-zA-Z0-9]+))?";
49
50 static final String OPTIONAL = "(!?optional)";
51
52 static final String RELOCATIONS = "relocations\\s*=\\s*(" + COORDS_NC + "(?:\\s*,\\s*" + COORDS_NC + ")*)";
53
54 static final String KEY_VAL = "(?:[-_a-zA-Z0-9]+)\\s*:\\s*(?:[-_a-zA-Z0-9]*)";
55
56 static final String PROPS = "props\\s*=\\s*(" + KEY_VAL + "(?:\\s*,\\s*" + KEY_VAL + ")*)";
57
58 static final String COORDSX = "(" + COORDS_NC + ")" + RANGE + "?(?:<((?:" + RANGE_NC + ")|\\S+))?";
59
60 static final String NODE = COORDSX + "(?:\\s+" + PROPS + ")?" + "(?:\\s+" + SCOPE + ")?" + "(?:\\s+" + OPTIONAL
61 + ")?" + "(?:\\s+" + RELOCATIONS + ")?" + "(?:\\s+" + ID + ")?";
62
63 static final String LINE = "(?:" + IDREF + ")|(?:" + NODE + ")";
64
65 private static final Pattern PATTERN = Pattern.compile(LINE);
66
67 private final String def;
68
69 String coords;
70
71 Map<String, String> properties;
72
73 String range;
74
75 String premanagedVersion;
76
77 String scope;
78
79 String premanagedScope;
80
81 Boolean optional;
82
83 List<String> relocations;
84
85 String id;
86
87 String reference;
88
89 NodeDefinition(String definition) {
90 def = definition.trim();
91
92 Matcher m = PATTERN.matcher(def);
93 if (!m.matches()) {
94 throw new IllegalArgumentException("bad syntax: " + def);
95 }
96
97 reference = m.group(1);
98 if (reference != null) {
99 return;
100 }
101
102 coords = m.group(2);
103 range = m.group(3);
104 premanagedVersion = m.group(4);
105
106 String props = m.group(5);
107 if (props != null) {
108 properties = new LinkedHashMap<>();
109 for (String prop : props.split("\\s*,\\s*")) {
110 int sep = prop.indexOf(':');
111 String key = prop.substring(0, sep);
112 String val = prop.substring(sep + 1);
113 properties.put(key, val);
114 }
115 }
116
117 scope = m.group(6);
118 premanagedScope = m.group(7);
119 optional = (m.group(8) != null) ? !m.group(8).startsWith("!") : Boolean.FALSE;
120
121 String relocs = m.group(9);
122 if (relocs != null) {
123 relocations = new ArrayList<>();
124 Collections.addAll(relocations, relocs.split("\\s*,\\s*"));
125 }
126
127 id = m.group(10);
128 }
129
130 @Override
131 public String toString() {
132 return def;
133 }
134 }