package com.prezi.haxe.gradle;
import com.google.common.base.Throwables;
import groovy.lang.Closure;
import org.apache.commons.io.IOUtils;
import org.gradle.api.Action;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.internal.file.FileResolver;
import org.gradle.api.internal.file.copy.CopySpecInternal;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.api.java.archives.Manifest;
import org.gradle.api.java.archives.internal.DefaultManifest;
import org.gradle.api.tasks.bundling.Zip;
import org.gradle.util.ConfigureUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Callable;
public class Har extends Zip {
public static final String DEFAULT_EXTENSION = "har";
public static final String MANIFEST_ATTR_LIBRARY_VERSION = "Library-Version";
public static final String MANIFEST_ATTR_EMBEDDED_RESOURCES = "Embedded-Resources";
private Manifest manifest;
private Map<String, File> embeddedResources = new LinkedHashMap<String, File>();
private final CopySpecInternal metaInf;
public Har() {
this.setExtension(DEFAULT_EXTENSION);
this.manifest = new DefaultManifest(getServices().get(FileResolver.class));
this.metaInf = getRootSpec().addFirst();
this.metaInf.into("META-INF");
this.metaInf.addChild().from(new Callable<File>() {
@Override
public File call() throws Exception {
File manifestFile = new File(getTemporaryDir(), "MANIFEST.MF");
FileOutputStream output = null;
try {
output = new FileOutputStream(manifestFile);
Manifest manifest = getManifest();
if (manifest == null) {
manifest = new DefaultManifest(null);
}
manifest.writeTo(new OutputStreamWriter(output));
} catch (FileNotFoundException e) {
throw Throwables.propagate(e);
} finally {
IOUtils.closeQuietly(output);
}
return manifestFile;
}
});
getMainSpec().eachFile(new Action<FileCopyDetails>() {
@Override
public void execute(FileCopyDetails details) {
if (details.getPath().equalsIgnoreCase("META-INF/MANIFEST.MF")) {
details.exclude();
}
}
});
}
/**
* Returns the manifest for this JAR archive.
*
* @return The manifest
*/
public Manifest getManifest() {
return manifest;
}
/**
* Sets the manifest for this JAR archive.
*
* @param manifest The manifest. May be null.
*/
public void setManifest(Manifest manifest) {
this.manifest = manifest;
}
/**
* Configures the manifest for this JAR archive.
*
* <p>The given closure is executed to configure the manifest. The {@link org.gradle.api.java.archives.Manifest}
* is passed to the closure as its delegate.</p>
*
* @param configureClosure The closure.
* @return This.
*/
public Har manifest(Closure configureClosure) {
if (getManifest() == null) {
manifest = new DefaultManifest(((ProjectInternal) getProject()).getFileResolver());
}
ConfigureUtil.configure(configureClosure, getManifest());
return this;
}
public CopySpec getMetaInf() {
return metaInf.addChild();
}
/**
* Adds content to this JAR archive's META-INF directory.
*
* <p>The given closure is executed to configure a {@code CopySpec}. The {@link CopySpec} is passed to the closure
* as its delegate.</p>
*
* @param configureClosure The closure.
* @return The created {@code CopySpec}
*/
public CopySpec metaInf(Closure configureClosure) {
return ConfigureUtil.configure(configureClosure, getMetaInf());
}
@Override
protected void copy() {
getManifest().getAttributes().put(MANIFEST_ATTR_LIBRARY_VERSION, "1.0");
Map<String, File> embeddedResources = getEmbeddedResources();
if (!embeddedResources.isEmpty()) {
getManifest().getAttributes().put(MANIFEST_ATTR_EMBEDDED_RESOURCES, EmbeddedResourceEncoding.encode(embeddedResources));
}
super.copy();
}
public Map<String, File> getEmbeddedResources() {
return embeddedResources;
}
public void setEmbeddedResources(Map<String, File> embeddedResources) {
this.embeddedResources = embeddedResources;
}
}