Skip to content

Commit

Permalink
Add API to store multi-release class file.
Browse files Browse the repository at this point in the history
  • Loading branch information
raphw committed Sep 23, 2024
1 parent 2fe1efb commit 6f0b5ed
Showing 1 changed file with 73 additions and 19 deletions.
92 changes: 73 additions & 19 deletions byte-buddy-dep/src/main/java/net/bytebuddy/build/Plugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,11 @@ interface Engine {
*/
String PLUGIN_FILE = "META-INF/net.bytebuddy/build.plugins";

/**
* The prefix folder for {@code META-INF/versions/} which contains multi-release files.
*/
String META_INF_VERSIONS = "META-INF/versions/";

/**
* Defines a new Byte Buddy instance for usage for type creation.
*
Expand Down Expand Up @@ -3286,6 +3291,15 @@ interface Sink extends Closeable {
*/
void store(Map<TypeDescription, byte[]> binaryRepresentations) throws IOException;

/**
* Stores the supplied binary representation of types in this sink.
*
* @param version The version of the multi-release jar file.
* @param binaryRepresentations The binary representations to store.
* @throws IOException If an I/O error occurs.
*/
void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException;

/**
* Retains the supplied element in its original form.
*
Expand Down Expand Up @@ -3324,6 +3338,17 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) throws IOE
}
}

/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
for (Map.Entry<TypeDescription, byte[]> entry : binaryRepresentations.entrySet()) {
outputStream.putNextEntry(new JarEntry(META_INF_VERSIONS + version + "/" + entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
outputStream.write(entry.getValue());
outputStream.closeEntry();
}
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -3378,6 +3403,13 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) {
/* do nothing */
}

/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
/* do nothing */
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -3445,6 +3477,15 @@ public void store(Map<TypeDescription, byte[]> binaryRepresentations) {
}
}

/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
for (Map.Entry<TypeDescription, byte[]> entry : binaryRepresentations.entrySet()) {
storage.putIfAbsent(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
}
}

/**
* {@inheritDoc}
*/
Expand Down Expand Up @@ -3525,40 +3566,58 @@ public ForFolder(File folder) {
}

/**
* {@inheritDoc}
* Stores binary representations to a folder.
*
* @param folder The base folder.
* @param binaryRepresentations The binary representations to store.
* @throws IOException If an I/O exception occurs.
*/
public Sink write(@MaybeNull Manifest manifest) throws IOException {
if (manifest != null) {
File target = new File(folder, JarFile.MANIFEST_NAME);
private static void doStore(File folder, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
for (Map.Entry<TypeDescription, byte[]> entry : binaryRepresentations.entrySet()) {
File target = new File(folder, entry.getKey().getInternalName() + CLASS_FILE_EXTENSION);
if (!target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
throw new IOException("Could not create directory: " + target.getParent());
}
OutputStream outputStream = new FileOutputStream(target);
try {
manifest.write(outputStream);
outputStream.write(entry.getValue());
} finally {
outputStream.close();
}
}
return this;
}

/**
* {@inheritDoc}
*/
public void store(Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
for (Map.Entry<TypeDescription, byte[]> entry : binaryRepresentations.entrySet()) {
File target = new File(folder, entry.getKey().getInternalName() + CLASS_FILE_EXTENSION);
public Sink write(@MaybeNull Manifest manifest) throws IOException {
if (manifest != null) {
File target = new File(folder, JarFile.MANIFEST_NAME);
if (!target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
throw new IOException("Could not create directory: " + target.getParent());
}
OutputStream outputStream = new FileOutputStream(target);
try {
outputStream.write(entry.getValue());
manifest.write(outputStream);
} finally {
outputStream.close();
}
}
return this;
}

/**
* {@inheritDoc}
*/
public void store(Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
doStore(folder, binaryRepresentations);
}

/**
* {@inheritDoc}
*/
public void store(int version, Map<TypeDescription, byte[]> binaryRepresentations) throws IOException {
doStore(new File(folder, META_INF_VERSIONS + version), binaryRepresentations);
}

/**
Expand Down Expand Up @@ -3673,7 +3732,7 @@ interface Materializable {
void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException;

/**
Expand Down Expand Up @@ -3701,7 +3760,7 @@ protected ForTransformedElement(DynamicType dynamicType) {
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
sink.store(dynamicType.getAllTypes());
transformed.add(dynamicType.getTypeDescription());
Expand Down Expand Up @@ -3778,7 +3837,7 @@ protected ForFailedElement(Source.Element element, TypeDescription typeDescripti
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
sink.retain(element);
failed.put(typeDescription, errored);
Expand Down Expand Up @@ -3817,7 +3876,7 @@ protected ForUnresolvedElement(Source.Element element, String typeName) {
public void materialize(Target.Sink sink,
List<TypeDescription> transformed,
Map<TypeDescription,
List<Throwable>> failed,
List<Throwable>> failed,
List<String> unresolved) throws IOException {
sink.retain(element);
unresolved.add(typeName);
Expand Down Expand Up @@ -4364,11 +4423,6 @@ public Summary apply(Source source, Target target, Factory... factory) throws IO
@HashCodeAndEqualsPlugin.Enhance
class Default extends AbstractBase {

/**
* The prefix folder for {@code META-INF/versions/} which contains multi-release files.
*/
private static final String META_INF_VERSIONS = "META-INF/versions/";

/**
* The Byte Buddy instance to use.
*/
Expand Down

0 comments on commit 6f0b5ed

Please sign in to comment.