1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // Multi-Phasic Applications: SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.plugin
.multivm
;
12 import cc
.squirreljme
.plugin
.multivm
.csv
.SharedCsvEntry
;
13 import cc
.squirreljme
.plugin
.multivm
.ident
.SourceTargetClassifier
;
14 import com
.opencsv
.bean
.CsvToBean
;
15 import com
.opencsv
.bean
.CsvToBeanBuilder
;
16 import java
.io
.IOException
;
17 import java
.io
.InputStream
;
18 import java
.io
.InputStreamReader
;
19 import java
.io
.Reader
;
20 import java
.nio
.file
.Files
;
21 import java
.nio
.file
.OpenOption
;
22 import java
.nio
.file
.Path
;
23 import java
.nio
.file
.StandardOpenOption
;
24 import java
.util
.Collections
;
25 import java
.util
.LinkedHashSet
;
28 import java
.util
.TreeMap
;
29 import java
.util
.TreeSet
;
30 import java
.util
.stream
.Collectors
;
31 import java
.util
.stream
.Stream
;
32 import org
.gradle
.api
.Action
;
33 import org
.gradle
.api
.Task
;
34 import org
.gradle
.api
.provider
.Provider
;
37 * Performs the actual cleaning of the NanoCoat Built-In ROM generated sources.
39 * This task is a bit more complicated because it will only clean up for a
40 * given ROM's output, while using workarounds for the shared directory.
44 public class NanoCoatBuiltInCleanTaskAction
45 implements Action
<Task
>
47 /** The classifier for the cleaning. */
48 protected final SourceTargetClassifier classifier
;
50 /** The ROM base path. */
51 private final Provider
<Path
> _romBasePath
;
53 /** The shared path. */
54 private final Provider
<Path
> _sharedPath
;
56 /** The specific path. */
57 private final Provider
<Path
> _specificPath
;
60 * Initializes the cleaning action.
62 * @param __classifier The classifier of what this is cleaning for.
63 * @param __romBasePath The base ROM path.
64 * @param __specificPath The specific module path.
65 * @param __sharedPath The shared path.
66 * @throws NullPointerException On null arguments.
69 public NanoCoatBuiltInCleanTaskAction(SourceTargetClassifier __classifier
,
70 Provider
<Path
> __romBasePath
, Provider
<Path
> __specificPath
,
71 Provider
<Path
> __sharedPath
)
72 throws NullPointerException
74 if (__classifier
== null || __romBasePath
== null ||
75 __specificPath
== null || __sharedPath
== null)
76 throw new NullPointerException("NARG");
78 this.classifier
= __classifier
;
79 this._romBasePath
= __romBasePath
;
80 this._specificPath
= __specificPath
;
81 this._sharedPath
= __sharedPath
;
89 public void execute(Task __task
)
93 // Determine our specific ROM being used
94 Path ourSpecificPath
= this._specificPath
.get();
95 String ourSpecific
= ourSpecificPath
.getFileName().toString();
97 // Get all the specifics that have been found
98 Map
<String
, Path
> specifics
= this.__specifics();
100 // Nothing to actually delete?
101 if (specifics
.isEmpty())
104 // There are two sets of shared, the ones that are in our share
105 // set and the ones that are in the other share set... we can only
106 // remove ones that they do not use at all
107 Set
<SharedCsvEntry
> ourShared
= new LinkedHashSet
<>();
108 Set
<SharedCsvEntry
> otherShared
= new LinkedHashSet
<>();
110 // Load in all the shared entries
111 for (Map
.Entry
<String
, Path
> entry
: specifics
.entrySet())
113 String specific
= entry
.getKey();
114 Path specificPath
= entry
.getValue();
116 // Which one are we loading into?
117 Set
<SharedCsvEntry
> into
;
118 if (specific
.equals(ourSpecific
))
124 this.__load(into
, specificPath
);
127 // By removing everything from ours that is used by others, we
128 // have a set of shared entries which are not used elsewhere
129 ourShared
.removeAll(otherShared
);
131 // Go through everything and remove accordingly
132 Path root
= this._romBasePath
.get();
133 for (SharedCsvEntry entry
: ourShared
)
135 // Delete source and header file
136 Files
.deleteIfExists(root
.resolve(
137 VMHelpers
.stringToPath(entry
.getHeader())));
138 Files
.deleteIfExists(root
.resolve(
139 VMHelpers
.stringToPath(entry
.getSource())));
142 // Delete our own specific set
143 __task
.getProject().delete(ourSpecificPath
);
145 catch (IOException __e
)
147 throw new RuntimeException(__e
);
152 * Determines all the specific ROMs.
154 * @return The specific ROMs.
155 * @throws IOException On read errors.
158 private Map
<String
, Path
> __specifics()
161 // If the build is clean, this will always return nothing
162 Path root
= this._romBasePath
.get();
163 Path specificRoot
= root
.resolve("specific");
164 if (!Files
.exists(root
) || !Files
.exists(specificRoot
))
165 return Collections
.emptyMap();
167 // Determine all specifics available
168 Map
<String
, Path
> result
= new TreeMap
<>();
169 try (Stream
<Path
> stream
= Files
.list(specificRoot
))
171 for (Path path
: stream
.collect(Collectors
.toList()))
172 if (Files
.exists(path
.resolve("shared.csv")))
173 result
.put(path
.getFileName().toString(), path
);
176 return Collections
.unmodifiableMap(result
);
180 * Loads the shared entry lists.
182 * @param __into Which is this being loaded into?
183 * @param __base The base.
184 * @return {@code __into}.
185 * @throws IOException On read errors.
186 * @throws NullPointerException On null arguments.
189 private static Set
<SharedCsvEntry
> __load(Set
<SharedCsvEntry
> __into
,
191 throws IOException
, NullPointerException
193 if (__into
== null || __base
== null)
194 throw new NullPointerException("NARG");
196 // Make sure the target exists first
197 Path sharedPath
= __base
.resolve("shared.csv");
198 if (!Files
.exists(sharedPath
))
201 // Read in everything
202 try (InputStream in
= Files
.newInputStream(sharedPath
,
203 StandardOpenOption
.READ
);
204 Reader reader
= new InputStreamReader(in
, "utf-8"))
207 CsvToBean
<SharedCsvEntry
> parser
=
208 new CsvToBeanBuilder
<SharedCsvEntry
>(reader
)
209 .withType(SharedCsvEntry
.class)
210 .withIgnoreEmptyLine(true)
211 .withIgnoreLeadingWhiteSpace(true)
214 // Read in all entries
215 for (SharedCsvEntry entry
: parser
)