20
20
21
21
import io .github .ascopes .jct .ex .JctIllegalInputException ;
22
22
import io .github .ascopes .jct .filemanagers .ModuleLocation ;
23
+ import io .github .ascopes .jct .utils .IoExceptionUtils ;
24
+ import io .github .ascopes .jct .utils .ToStringBuilder ;
23
25
import io .github .ascopes .jct .workspaces .ManagedDirectory ;
24
26
import io .github .ascopes .jct .workspaces .PathRoot ;
25
27
import io .github .ascopes .jct .workspaces .PathStrategy ;
26
28
import io .github .ascopes .jct .workspaces .Workspace ;
29
+ import java .io .IOException ;
30
+ import java .nio .file .FileVisitResult ;
27
31
import java .nio .file .Files ;
28
32
import java .nio .file .Path ;
33
+ import java .nio .file .SimpleFileVisitor ;
34
+ import java .nio .file .attribute .BasicFileAttributes ;
29
35
import java .util .ArrayList ;
30
36
import java .util .HashMap ;
31
37
import java .util .List ;
47
53
public final class WorkspaceImpl implements Workspace {
48
54
49
55
private volatile boolean closed ;
56
+ private final String id ;
50
57
private final PathStrategy pathStrategy ;
51
- private final Map <Location , List <PathRoot >> paths ;
58
+ private final Map <Location , List <PathRoot >> locations ;
52
59
53
60
/**
54
61
* Initialise this workspace.
55
62
*
56
63
* @param pathStrategy the path strategy to use for creating source and target paths.
57
64
*/
58
65
public WorkspaceImpl (PathStrategy pathStrategy ) {
66
+ id = UUID .randomUUID ().toString ();
59
67
closed = false ;
60
68
this .pathStrategy = requireNonNull (pathStrategy , "pathStrategy" );
61
- paths = new HashMap <>();
69
+ locations = new HashMap <>();
62
70
}
63
71
64
72
@ Override
@@ -67,7 +75,7 @@ public void close() {
67
75
// Close everything in a best-effort fashion.
68
76
var exceptions = new ArrayList <Throwable >();
69
77
70
- for (var list : paths .values ()) {
78
+ for (var list : locations .values ()) {
71
79
for (var path : list ) {
72
80
if (path instanceof AbstractManagedDirectory dir ) {
73
81
try {
@@ -90,6 +98,64 @@ public void close() {
90
98
}
91
99
}
92
100
101
+ @ Override
102
+ public void dump (Appendable appendable ) {
103
+ IoExceptionUtils .uncheckedIo (() -> {
104
+ appendable .append (toString ()).append ("\n " );
105
+ for (var location : locations .keySet ().stream ().sorted ().toList ()) {
106
+ appendable .append (" Location " ).append (location .toString ()).append (": \n " );
107
+
108
+ for (var pathRoot : locations .get (location )) {
109
+ appendable .append (" - " ).append (pathRoot .getUri ().toString ()).append (" contents:\n " );
110
+
111
+ var baseIndent = 8 ;
112
+ var basePath = pathRoot .getPath ();
113
+
114
+ Files .walkFileTree (basePath , new SimpleFileVisitor <>() {
115
+ private int indent = 0 ;
116
+
117
+ @ Override
118
+ public FileVisitResult preVisitDirectory (
119
+ Path dir ,
120
+ BasicFileAttributes attrs
121
+ ) throws IOException {
122
+ if (!dir .equals (basePath )) {
123
+ appendIndent ();
124
+ appendable .append (dir .getFileName ().toString ()).append ("/\n " );
125
+ indent += 2 ;
126
+ }
127
+
128
+ return FileVisitResult .CONTINUE ;
129
+ }
130
+
131
+ @ Override
132
+ public FileVisitResult postVisitDirectory (Path dir , IOException exc ) {
133
+ indent -= 2 ;
134
+ return FileVisitResult .CONTINUE ;
135
+ }
136
+
137
+ @ Override
138
+ public FileVisitResult visitFile (
139
+ Path file ,
140
+ BasicFileAttributes attrs
141
+ ) throws IOException {
142
+ appendIndent ();
143
+ appendable .append (file .getFileName ().toString ()).append ("\n " );
144
+ return FileVisitResult .CONTINUE ;
145
+ }
146
+
147
+ private void appendIndent () throws IOException {
148
+ appendable .append (" " .repeat (baseIndent ))
149
+ .append ("·" .repeat (indent ));
150
+ }
151
+ });
152
+ }
153
+
154
+ appendable .append ("\n " );
155
+ }
156
+ });
157
+ }
158
+
93
159
@ Override
94
160
public boolean isClosed () {
95
161
return closed ;
@@ -109,7 +175,7 @@ public void addPackage(Location location, Path path) {
109
175
}
110
176
111
177
var dir = new WrappingDirectoryImpl (path );
112
- paths .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
178
+ locations .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
113
179
}
114
180
115
181
@ Override
@@ -139,13 +205,12 @@ public ManagedDirectory createPackage(Location location) {
139
205
throw new JctIllegalInputException ("Location must not be module-oriented" );
140
206
}
141
207
142
- // Needs to be unique, and JIMFS cannot hold a file system name containing stuff like
143
- // underscores.
208
+ // Needs to be unique.
144
209
var fsName = location .getName ().replaceAll ("[^A-Za-z0-9]" , "" )
145
210
+ UUID .randomUUID ();
146
211
147
212
var dir = pathStrategy .newInstance (fsName );
148
- paths .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
213
+ locations .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
149
214
return dir ;
150
215
}
151
216
@@ -170,9 +235,9 @@ public ManagedDirectory createModule(Location location, String moduleName) {
170
235
@ Override
171
236
public Map <Location , List <? extends PathRoot >> getAllPaths () {
172
237
// Create an immutable copy.
173
- var pathsCopy = new HashMap <Location , List <PathRoot >>();
174
- paths .forEach ((location , list ) -> pathsCopy .put (location , List .copyOf (list )));
175
- return unmodifiableMap (pathsCopy );
238
+ var locationsCopy = new HashMap <Location , List <PathRoot >>();
239
+ locations .forEach ((location , list ) -> locationsCopy .put (location , List .copyOf (list )));
240
+ return unmodifiableMap (locationsCopy );
176
241
}
177
242
178
243
@ Override
@@ -205,7 +270,7 @@ public Map<String, List<? extends PathRoot>> getModules(Location location) {
205
270
206
271
var results = new HashMap <String , List <PathRoot >>();
207
272
208
- paths .forEach ((pathLocation , pathRoots ) -> {
273
+ locations .forEach ((pathLocation , pathRoots ) -> {
209
274
if (pathLocation instanceof ModuleLocation modulePathLocation ) {
210
275
if (modulePathLocation .getParent ().equals (location )) {
211
276
results .computeIfAbsent (modulePathLocation .getModuleName (), name -> new ArrayList <>())
@@ -233,9 +298,19 @@ public List<? extends PathRoot> getPackages(Location location) {
233
298
);
234
299
}
235
300
236
- var roots = paths .get (location );
301
+ var roots = locations .get (location );
237
302
return roots == null
238
303
? List .of ()
239
304
: List .copyOf (roots );
240
305
}
306
+
307
+ @ Override
308
+ public String toString () {
309
+ return new ToStringBuilder (this )
310
+ .attribute ("id" , id )
311
+ .attribute ("pathStrategy" , pathStrategy )
312
+ .attribute ("closed" , closed )
313
+ .attribute ("numberOfLocations" , locations .size ())
314
+ .toString ();
315
+ }
241
316
}
0 commit comments