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
.general
;
12 import cc
.squirreljme
.plugin
.multivm
.VMHelpers
;
13 import java
.io
.ByteArrayOutputStream
;
14 import java
.io
.DataOutput
;
15 import java
.io
.DataOutputStream
;
17 import java
.io
.IOException
;
18 import java
.io
.InputStream
;
19 import java
.io
.OutputStream
;
20 import java
.nio
.file
.Files
;
21 import java
.nio
.file
.Path
;
22 import java
.nio
.file
.StandardOpenOption
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Arrays
;
25 import java
.util
.Collections
;
26 import java
.util
.LinkedHashSet
;
27 import java
.util
.List
;
29 import java
.util
.stream
.Stream
;
30 import java
.util
.zip
.ZipEntry
;
31 import java
.util
.zip
.ZipInputStream
;
32 import org
.gradle
.api
.Action
;
33 import org
.gradle
.api
.Task
;
34 import org
.gradle
.language
.jvm
.tasks
.ProcessResources
;
37 * Performs the task action of {@link CollateResourceJarsTask}.
41 public class CollateResourceJarsTaskAction
42 implements Action
<Task
>
44 /** The resource processing task. */
45 protected final ProcessResources processResources
;
47 /** The output root for the Jar. */
48 protected final String jarRoot
;
51 * Initializes the task action.
53 * @param __processResources The resource processing task.
54 * @param __jarRoot The Jar Root used.
55 * @throws NullPointerException On null arguments.
58 public CollateResourceJarsTaskAction(ProcessResources __processResources
,
60 throws NullPointerException
62 if (__processResources
== null ||
64 throw new NullPointerException("NARG");
66 this.processResources
= __processResources
;
67 this.jarRoot
= __jarRoot
;
75 public void execute(Task __task
)
79 this.executeMayFail(__task
);
81 catch (IOException __e
)
83 throw new RuntimeException(__e
);
88 * Executes task that may fail.
90 * @param __task The task to execute within.
91 * @throws IOException On write errors.
94 public void executeMayFail(Task __task
)
97 Path outBase
= this.processResources
.getOutputs().
98 getFiles().getSingleFile().toPath().resolve(this.jarRoot
);
100 // Delete old directory set first since it will have a bunch of
101 // old files in it and such...
102 VMHelpers
.deleteDirTree(__task
, outBase
);
104 // Make sure it exists
105 Files
.createDirectories(outBase
);
108 List
<String
> suiteList
= new ArrayList
<>();
110 // Go through all the files
111 byte[] buf
= new byte[524288];
112 for (File jarFile
: __task
.getInputs().getFiles())
114 // Where is everything?
115 Path jarPath
= jarFile
.toPath();
116 Path jarName
= jarPath
.getFileName();
118 // Add to the suite list for later
119 suiteList
.add(jarName
.toString());
121 // Where does the exploded JAR content go?
122 Path jarOut
= outBase
.resolve(jarName
);
125 Files
.createDirectories(jarOut
);
127 // Read the ZIP and process
128 List
<String
> jarContent
= new ArrayList
<>();
129 try (InputStream jarIn
= Files
.newInputStream(jarPath
,
130 StandardOpenOption
.READ
);
131 ZipInputStream jar
= new ZipInputStream(jarIn
))
134 ZipEntry entry
= jar
.getNextEntry();
138 if (entry
.isDirectory())
142 String name
= entry
.getName();
143 jarContent
.add(name
);
145 // Find where it goes
146 Path diskFile
= CollateResourceJarsTaskAction
147 .nameToDiskFile(jarOut
, name
);
150 Files
.createDirectories(diskFile
.getParent());
153 __task
.getLogger().lifecycle(
154 String
.format("Adding %s...",
155 outBase
.relativize(diskFile
)));
158 try (OutputStream out
= Files
.newOutputStream(diskFile
,
159 StandardOpenOption
.WRITE
,
160 StandardOpenOption
.TRUNCATE_EXISTING
,
161 StandardOpenOption
.CREATE
))
165 int rc
= jar
.read(buf
);
170 out
.write(buf
, 0, rc
);
176 // Write resource list
178 jarOut
.resolve("META-INF").resolve("squirreljme");
180 rcListBase
.resolve("resources.list");
181 Files
.createDirectories(rcListBase
);
182 CollateResourceJarsTaskAction
.writeList(rcListPath
, jarContent
);
185 // Write the suite list
186 CollateResourceJarsTaskAction
.writeList(
187 outBase
.resolve("suites.list"), suiteList
);
191 * Converts a name to a file on the disk.
193 * @param __jarOut The output Jar.
194 * @param __name The name of the entry.
195 * @return The resultant path for the file.
198 public static Path
nameToDiskFile(Path __jarOut
, String __name
)
200 Path diskFile
= __jarOut
;
202 for (String splice
: __name
.split("[\\\\/]"))
203 diskFile
= diskFile
.resolve(splice
);
209 * Writes a list file.
211 * @param __target The target file.
212 * @param __input The input string list.
213 * @throws IOException On write errors.
216 public static void writeList(Path __target
, List
<String
> __input
)
219 if (__target
== null || __input
== null)
220 throw new NullPointerException("NARG");
224 try (ByteArrayOutputStream baos
= new ByteArrayOutputStream();
225 DataOutputStream dos
= new DataOutputStream(baos
))
227 dos
.writeInt(__input
.size());
228 for (int i
= 0, n
= __input
.size(); i
< n
; i
++)
229 dos
.writeUTF(__input
.get(i
));
232 data
= baos
.toByteArray();
235 Files
.write(__target
, data
,
236 StandardOpenOption
.WRITE
, StandardOpenOption
.TRUNCATE_EXISTING
,
237 StandardOpenOption
.CREATE
);