View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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   * A definition of a dependency node via a single line of text.
31   *
32   * @see DependencyGraphParser
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 }