1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.booter;
20
21 import javax.annotation.Nonnull;
22
23 import java.io.File;
24 import java.net.MalformedURLException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.LinkedHashSet;
30 import java.util.List;
31
32 import static java.io.File.pathSeparatorChar;
33
34
35
36
37
38
39
40
41
42
43 public final class Classpath implements Iterable<String>, Cloneable {
44 private final List<String> unmodifiableElements;
45
46 public static Classpath join(Classpath firstClasspath, Classpath secondClasspath) {
47 LinkedHashSet<String> accumulated = new LinkedHashSet<>();
48 if (firstClasspath != null) {
49 firstClasspath.addTo(accumulated);
50 }
51 if (secondClasspath != null) {
52 secondClasspath.addTo(accumulated);
53 }
54 return new Classpath(accumulated);
55 }
56
57 private void addTo(@Nonnull Collection<String> c) {
58 c.addAll(unmodifiableElements);
59 }
60
61 private Classpath() {
62 unmodifiableElements = Collections.emptyList();
63 }
64
65 public Classpath(@Nonnull Classpath other, @Nonnull String additionalElement) {
66 ArrayList<String> elems = new ArrayList<>(other.unmodifiableElements);
67 elems.add(additionalElement);
68 unmodifiableElements = Collections.unmodifiableList(elems);
69 }
70
71 public Classpath(@Nonnull Collection<String> elements) {
72 List<String> newCp = new ArrayList<>(elements.size());
73 for (String element : elements) {
74 element = element.trim();
75 if (!element.isEmpty()) {
76 newCp.add(element);
77 }
78 }
79 unmodifiableElements = Collections.unmodifiableList(newCp);
80 }
81
82 public static Classpath emptyClasspath() {
83 return new Classpath();
84 }
85
86 public Classpath addClassPathElementUrl(String path) {
87 if (path == null) {
88 throw new IllegalArgumentException("Null is not a valid class path element url.");
89 }
90 return unmodifiableElements.contains(path) ? this : new Classpath(this, path);
91 }
92
93 @Nonnull
94 public List<String> getClassPath() {
95 return unmodifiableElements;
96 }
97
98 public void writeToSystemProperty(@Nonnull String propertyName) {
99 System.setProperty(propertyName, String.join(String.valueOf(pathSeparatorChar), unmodifiableElements));
100 }
101
102 @Override
103 public boolean equals(Object o) {
104 if (this == o) {
105 return true;
106 }
107 if (o == null || getClass() != o.getClass()) {
108 return false;
109 }
110
111 Classpath classpath = (Classpath) o;
112
113 return unmodifiableElements.equals(classpath.unmodifiableElements);
114 }
115
116 public ClassLoader createClassLoader(boolean childDelegation, boolean enableAssertions, @Nonnull String roleName)
117 throws SurefireExecutionException {
118 try {
119 ClassLoader parent = SystemUtils.platformClassLoader();
120 IsolatedClassLoader classLoader = new IsolatedClassLoader(parent, childDelegation, roleName);
121 for (String classPathElement : unmodifiableElements) {
122 classLoader.addURL(new File(classPathElement).toURI().toURL());
123 }
124 if (parent != null) {
125 parent.setDefaultAssertionStatus(enableAssertions);
126 }
127 classLoader.setDefaultAssertionStatus(enableAssertions);
128 return classLoader;
129 } catch (MalformedURLException e) {
130 throw new SurefireExecutionException("When creating classloader", e);
131 }
132 }
133
134 @Override
135 public int hashCode() {
136 return unmodifiableElements.hashCode();
137 }
138
139 public String getLogMessage(@Nonnull String descriptor) {
140 StringBuilder result = new StringBuilder(descriptor);
141 for (String element : unmodifiableElements) {
142 result.append(" ").append(element);
143 }
144 return result.toString();
145 }
146
147 public String getCompactLogMessage(@Nonnull String descriptor) {
148 StringBuilder result = new StringBuilder(descriptor);
149 for (String element : unmodifiableElements) {
150 result.append(" ");
151 int pos = element.lastIndexOf(File.separatorChar);
152 result.append(pos == -1 ? element : element.substring(pos + 1));
153 }
154 return result.toString();
155 }
156
157 @Override
158 public Iterator<String> iterator() {
159 return unmodifiableElements.iterator();
160 }
161
162 @Override
163 public Classpath clone() {
164 return new Classpath(unmodifiableElements);
165 }
166 }