Skip to content

Instantly share code, notes, and snippets.

@josefbetancourt
Created December 15, 2012 00:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josefbetancourt/4289876 to your computer and use it in GitHub Desktop.
Save josefbetancourt/4289876 to your computer and use it in GitHub Desktop.
Source code from blog post "Java Generics Example: Jar Manifest" at [http://octodecillion.com/blog/java-generics-manifest/]
/**
*
*/
package com.octodecillion.utils;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
/**
* Utility to access Jar manifest information.
*
* @author josef betancourt
* @since Dec 10, 2012
*/
public class JarInfo {
/**
* Get value of a main attribute in jar manifest.
*
* @param filePath
* of jar file
* @param attributeName
* of main attribute
* @return value of attribute
* @throws IOException
*/
public static String getValue(final String filePath,
final String attributeName) throws IOException {
return new JarFile(filePath).getManifest().getMainAttributes()
.getValue(attributeName);
}
/**
*
* Find an attribute whose key matches a regular expression.
*
* @param filePath
* @param regex
* should match the full key string
* @return matched attribute entry
* @throws IOException
*/
public static Entry<Object, Object> find(final String filePath,
final String regex) throws IOException {
MatchingFilter filter = new MatchingFilter(regex);
scan(filePath, filter);
return filter.getResult();
}
/**
* Get the manifest as a String.
*
* The pecularities of the manifest format are not maintained, such as the
* 72 character line width.
*
* @param filePath
* of jar file
* @return string representation of MANIFEST.MF
* @throws IOException
*/
public static String getManifest(final String filePath) throws IOException {
CollectingFilter filter = new CollectingFilter();
scan(filePath, filter);
return filter.getResult().toString();
}
/**
* Iterate thru the main attributes.
*
* For each entry an accept method is invoked.
*
* @param filePath
* @param filter
* @throws IOException
*/
private static <T> void scan(final String filePath,
final Filter<Entry<Object, Object>, T> filter) throws IOException {
Attributes attributes = new JarFile(filePath).getManifest()
.getMainAttributes();
Iterator<Entry<Object, Object>> iterator = attributes.entrySet()
.iterator();
while (iterator.hasNext()) {
Entry<Object, Object> entry = iterator.next();
try {
boolean result = filter.accept(entry);
if (result) {
break;
}
} catch (Exception e) {
throw new IOException(e);
}
}
}
/**
* Filter that collects entries into a String buffer.
*
* @author jbetancourt
*
*/
private static class CollectingFilter implements
Filter<Entry<Object, Object>, StringBuffer> {
private StringBuffer result;
public CollectingFilter() {
setResult(new StringBuffer());
}
@Override
public boolean accept(final Entry<Object, Object> entry,
final Object... args) throws Exception {
getResult().append(entry + "\n");
return false;
}
@Override
public void setResult(final StringBuffer result) {
this.result = result;
}
@Override
public StringBuffer getResult() {
return result;
}
}
/**
* Filter that accepts entry whose key matches a regex.
*
* @author jbetancourt
*
*/
private static class MatchingFilter implements
Filter<Entry<Object, Object>, Entry<Object, Object>> {
private final String regex;
private Entry<Object, Object> result;
public MatchingFilter(final String regex) {
this.regex = regex;
}
@Override
public boolean accept(final Entry<Object, Object> entry,
final Object... args) throws Exception {
boolean flag = false;
if (entry.getKey().toString().matches(regex)) {
setResult(entry);
flag = true;
}
return flag;
}
@Override
public void setResult(final Entry<Object, Object> result) {
this.result = result;
}
@Override
public Entry<Object, Object> getResult() {
return result;
}
}
/**
* Generic filter support base type.
*
* @author jbetancourt
*
* @param <T>
* type argument to accept method
* @param <R>
* type of result
*/
private static interface Filter<T, R> {
/**
*
* Evaluate acceptance of Object.
*
* @param obj
* object to use for evaluation
* @param args
* zero or more Object arguments
* @return true if accepted
* @throws Exception
*/
public boolean accept(final T obj, Object... args) throws Exception;
/**
* setter
*
* @param result
*/
public void setResult(final R result);
/**
* getter
*
* @return the result
*/
public R getResult();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment