2020
2121import io .github .ascopes .jct .ex .JctIllegalInputException ;
2222import io .github .ascopes .jct .filemanagers .ModuleLocation ;
23+ import io .github .ascopes .jct .utils .IoExceptionUtils ;
24+ import io .github .ascopes .jct .utils .ToStringBuilder ;
2325import io .github .ascopes .jct .workspaces .ManagedDirectory ;
2426import io .github .ascopes .jct .workspaces .PathRoot ;
2527import io .github .ascopes .jct .workspaces .PathStrategy ;
2628import io .github .ascopes .jct .workspaces .Workspace ;
29+ import java .io .IOException ;
30+ import java .nio .file .FileVisitResult ;
2731import java .nio .file .Files ;
2832import java .nio .file .Path ;
33+ import java .nio .file .SimpleFileVisitor ;
34+ import java .nio .file .attribute .BasicFileAttributes ;
2935import java .util .ArrayList ;
3036import java .util .HashMap ;
3137import java .util .List ;
4753public final class WorkspaceImpl implements Workspace {
4854
4955 private volatile boolean closed ;
56+ private final String id ;
5057 private final PathStrategy pathStrategy ;
51- private final Map <Location , List <PathRoot >> paths ;
58+ private final Map <Location , List <PathRoot >> locations ;
5259
5360 /**
5461 * Initialise this workspace.
5562 *
5663 * @param pathStrategy the path strategy to use for creating source and target paths.
5764 */
5865 public WorkspaceImpl (PathStrategy pathStrategy ) {
66+ id = UUID .randomUUID ().toString ();
5967 closed = false ;
6068 this .pathStrategy = requireNonNull (pathStrategy , "pathStrategy" );
61- paths = new HashMap <>();
69+ locations = new HashMap <>();
6270 }
6371
6472 @ Override
@@ -67,7 +75,7 @@ public void close() {
6775 // Close everything in a best-effort fashion.
6876 var exceptions = new ArrayList <Throwable >();
6977
70- for (var list : paths .values ()) {
78+ for (var list : locations .values ()) {
7179 for (var path : list ) {
7280 if (path instanceof AbstractManagedDirectory dir ) {
7381 try {
@@ -90,6 +98,64 @@ public void close() {
9098 }
9199 }
92100
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+
93159 @ Override
94160 public boolean isClosed () {
95161 return closed ;
@@ -109,7 +175,7 @@ public void addPackage(Location location, Path path) {
109175 }
110176
111177 var dir = new WrappingDirectoryImpl (path );
112- paths .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
178+ locations .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
113179 }
114180
115181 @ Override
@@ -139,13 +205,12 @@ public ManagedDirectory createPackage(Location location) {
139205 throw new JctIllegalInputException ("Location must not be module-oriented" );
140206 }
141207
142- // Needs to be unique, and JIMFS cannot hold a file system name containing stuff like
143- // underscores.
208+ // Needs to be unique.
144209 var fsName = location .getName ().replaceAll ("[^A-Za-z0-9]" , "" )
145210 + UUID .randomUUID ();
146211
147212 var dir = pathStrategy .newInstance (fsName );
148- paths .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
213+ locations .computeIfAbsent (location , unused -> new ArrayList <>()).add (dir );
149214 return dir ;
150215 }
151216
@@ -170,9 +235,9 @@ public ManagedDirectory createModule(Location location, String moduleName) {
170235 @ Override
171236 public Map <Location , List <? extends PathRoot >> getAllPaths () {
172237 // 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 );
176241 }
177242
178243 @ Override
@@ -205,7 +270,7 @@ public Map<String, List<? extends PathRoot>> getModules(Location location) {
205270
206271 var results = new HashMap <String , List <PathRoot >>();
207272
208- paths .forEach ((pathLocation , pathRoots ) -> {
273+ locations .forEach ((pathLocation , pathRoots ) -> {
209274 if (pathLocation instanceof ModuleLocation modulePathLocation ) {
210275 if (modulePathLocation .getParent ().equals (location )) {
211276 results .computeIfAbsent (modulePathLocation .getModuleName (), name -> new ArrayList <>())
@@ -233,9 +298,19 @@ public List<? extends PathRoot> getPackages(Location location) {
233298 );
234299 }
235300
236- var roots = paths .get (location );
301+ var roots = locations .get (location );
237302 return roots == null
238303 ? List .of ()
239304 : List .copyOf (roots );
240305 }
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+ }
241316}
0 commit comments