下面列出了java.util.jar.Manifest#getEntries ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Copy all the files in a manifest from input to output. We set
* the modification times in the output to a fixed time, so as to
* reduce variation in the output file and make incremental OTAs
* more efficient.
*/
private void copyFiles(Manifest manifest, Map<String, ZioEntry> input, ZipOutput output, long timestamp)
throws IOException {
Map<String, Attributes> entries = manifest.getEntries();
List<String> names = new ArrayList<String>(entries.keySet());
Collections.sort(names);
int i = 1;
for (String name : names) {
if (canceled) break;
progressHelper.progress(ProgressEvent.PRORITY_NORMAL, resourceAdapter.getString(ResourceAdapter.Item.COPYING_ZIP_ENTRY, i, names.size()));
i += 1;
ZioEntry inEntry = input.get(name);
inEntry.setTime(timestamp);
output.write(inEntry);
}
}
/**
* Gets all signed files from the manifest.
* <p>
* It scans all manifest entries and their attributes. If there is an attribute
* name which ends with "-DIGEST" we are assuming that manifest entry name is a
* signed file name.
*
* @param manifest JAR file manifest.
* @return Either empty set if none found or set of signed file names.
*/
private static Set<String> getSignedFiles(Manifest manifest) {
Set<String> fileNames = new HashSet<>();
Map<String, Attributes> entries = manifest.getEntries();
if (entries != null && entries.size() > 0) {
for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
Attributes attrs = entry.getValue();
for (Map.Entry<Object, Object> attrEntry : attrs.entrySet()) {
if (attrEntry.getKey().toString().toUpperCase().endsWith("-DIGEST")) {
fileNames.add(entry.getKey());
break;
}
}
}
}
return fileNames;
}
private Manifest merge(Manifest ownManifest, List<Manifest> otherManifests) {
Manifest mergedManifest= new Manifest(ownManifest);
Map<String, Attributes> mergedEntries= mergedManifest.getEntries();
for (Iterator<Manifest> iter= otherManifests.iterator(); iter.hasNext();) {
Manifest otherManifest= iter.next();
Map<String, Attributes> otherEntries= otherManifest.getEntries();
for (Iterator<String> iterator= otherEntries.keySet().iterator(); iterator.hasNext();) {
String attributeName= iterator.next();
if (mergedEntries.containsKey(attributeName)) {
// TODO: WARNING
} else {
mergedEntries.put(attributeName, otherEntries.get(attributeName));
}
}
}
return mergedManifest;
}
/**
* Copy all the files in a manifest from input to output. We set
* the modification times in the output to a fixed time, so as to
* reduce variation in the output file and make incremental OTAs
* more efficient.
*/
private void copyFiles(Manifest manifest, Map<String, ZioEntry> input, ZipOutput output, long timestamp)
throws IOException {
Map<String, Attributes> entries = manifest.getEntries();
List<String> names = new ArrayList<String>(entries.keySet());
Collections.sort(names);
int i = 1;
for (String name : names) {
if (canceled) break;
progressHelper.progress(ProgressEvent.PRORITY_NORMAL, resourceAdapter.getString(ResourceAdapter.Item.COPYING_ZIP_ENTRY, i, names.size()));
i += 1;
ZioEntry inEntry = input.get(name);
inEntry.setTime(timestamp);
output.write(inEntry);
}
}
public String getPigVersion() {
if (pigVersion == null) {
String findContainingJar = JarManager
.findContainingJar(ScriptState.class);
if (findContainingJar != null) {
try {
JarFile jar = new JarFile(findContainingJar);
final Manifest manifest = jar.getManifest();
final Map<String, Attributes> attrs = manifest.getEntries();
Attributes attr = attrs.get("org/apache/pig");
pigVersion = attr.getValue("Implementation-Version");
} catch (Exception e) {
LOG.warn("unable to read pigs manifest file");
}
} else {
LOG.warn("unable to read pigs manifest file. Not running from the Pig jar");
}
}
return (pigVersion == null) ? "" : pigVersion;
}
/**
* Write the signature file to the given output stream.
*/
private void generateSignatureFile(Manifest manifest, OutputStream out)
throws IOException, GeneralSecurityException {
out.write(("Signature-Version: 1.0\r\n").getBytes());
out.write(("Created-By: 1.0 (Android SignApk)\r\n").getBytes());
// BASE64Encoder base64 = new BASE64Encoder();
MessageDigest md = MessageDigest.getInstance("SHA1");
PrintStream print = new PrintStream(
new DigestOutputStream(new ByteArrayOutputStream(), md),
true, "UTF-8");
// Digest of the entire manifest
manifest.write(print);
print.flush();
out.write(("SHA1-Digest-Manifest: " + Base64.encode(md.digest()) + "\r\n\r\n").getBytes());
Map<String, Attributes> entries = manifest.getEntries();
for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
if (canceled) break;
progressHelper.progress(ProgressEvent.PRORITY_NORMAL, resourceAdapter.getString(ResourceAdapter.Item.GENERATING_SIGNATURE_FILE));
// Digest of the manifest stanza for this entry.
String nameEntry = "Name: " + entry.getKey() + "\r\n";
print.print(nameEntry);
for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
print.print(att.getKey() + ": " + att.getValue() + "\r\n");
}
print.print("\r\n");
print.flush();
out.write(nameEntry.getBytes());
out.write(("SHA1-Digest: " + Base64.encode(md.digest()) + "\r\n\r\n").getBytes());
}
}
/**
* Generate output JAR-file and packages
*/
public void outputToJar() throws IOException {
// create the manifest
final Manifest manifest = new Manifest();
final java.util.jar.Attributes atrs = manifest.getMainAttributes();
atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION, "1.2");
final Map<String, Attributes> map = manifest.getEntries();
// create manifest
final String now = (new Date()).toString();
final java.util.jar.Attributes.Name dateAttr =
new java.util.jar.Attributes.Name("Date");
final File jarFile = new File(_destDir, _jarFileName);
final JarOutputStream jos =
new JarOutputStream(new FileOutputStream(jarFile), manifest);
for (JavaClass clazz : _bcelClasses) {
final String className = clazz.getClassName().replace('.', '/');
final java.util.jar.Attributes attr = new java.util.jar.Attributes();
attr.put(dateAttr, now);
map.put(className + ".class", attr);
jos.putNextEntry(new JarEntry(className + ".class"));
final ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
clazz.dump(out); // dump() closes it's output stream
out.writeTo(jos);
}
jos.close();
}
/**
* Generate output JAR-file and packages
*/
public void outputToJar() throws IOException {
// create the manifest
final Manifest manifest = new Manifest();
final java.util.jar.Attributes atrs = manifest.getMainAttributes();
atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION, "1.2");
final Map<String, Attributes> map = manifest.getEntries();
// create manifest
final String now = (new Date()).toString();
final java.util.jar.Attributes.Name dateAttr =
new java.util.jar.Attributes.Name("Date");
final File jarFile = new File(_destDir, _jarFileName);
final JarOutputStream jos =
new JarOutputStream(new FileOutputStream(jarFile), manifest);
for (JavaClass clazz : _bcelClasses) {
final String className = clazz.getClassName().replace('.', '/');
final java.util.jar.Attributes attr = new java.util.jar.Attributes();
attr.put(dateAttr, now);
map.put(className + ".class", attr);
jos.putNextEntry(new JarEntry(className + ".class"));
final ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
clazz.dump(out); // dump() closes it's output stream
out.writeTo(jos);
}
jos.close();
}
@Test
public void testGetManifest() throws Exception {
Manifest manifest = ArchiveHandler.getManifest(ArchiveHandlerTest.class.getResourceAsStream(SAMPLE_MTAR), MAX_MANIFEST_SIZE);
Map<String, Attributes> entries = manifest.getEntries();
assertEquals(4, entries.size());
assertTrue(entries.containsKey("web/web-server.zip"));
assertTrue(entries.containsKey("applogic/pricing.zip"));
assertTrue(entries.containsKey("db/pricing-db.zip"));
assertTrue(entries.containsKey("META-INF/mtad.yaml"));
}
@Test
public void testGetManifestFlat() throws Exception {
Manifest manifest = ArchiveHandler.getManifest(ArchiveHandlerTest.class.getResourceAsStream(SAMPLE_FLAT_MTAR), MAX_MANIFEST_SIZE);
Map<String, Attributes> entries = manifest.getEntries();
assertEquals(4, entries.size());
assertTrue(entries.containsKey("web/"));
assertTrue(entries.containsKey("applogic/"));
assertTrue(entries.containsKey("db/"));
assertTrue(entries.containsKey("META-INF/mtad.yaml"));
}
/** Copy all the files in a manifest from input to output. */
private static void copyFiles(Manifest manifest, JarFile in, JarArchiveOutputStream out, long timestamp)
throws IOException {
final byte[] buffer = new byte[4096];
int num;
final Map<String, Attributes> entries = manifest.getEntries();
final List<String> names = new ArrayList<>(entries.keySet());
Collections.sort(names);
for (final String name : names) {
final JarEntry inEntry = in.getJarEntry(name);
if (inEntry.getMethod() == JarArchiveEntry.STORED) {
// Preserve the STORED method of the input entry.
out.putArchiveEntry(new JarArchiveEntry(inEntry));
} else {
// Create a new entry so that the compressed len is recomputed.
final JarArchiveEntry je = new JarArchiveEntry(name);
je.setTime(timestamp);
out.putArchiveEntry(je);
}
final InputStream data = in.getInputStream(inEntry);
while ((num = data.read(buffer)) > 0) {
out.write(buffer, 0, num);
}
out.flush();
out.closeArchiveEntry();
}
}
protected static Map<String, Map<String, String>> extractEntries(Manifest mf) {
Map<String, Map<String, String>> mapMap = new HashMap<>();
Map<String, Attributes> entries = mf.getEntries();
for (Map.Entry<String, Attributes> entrySection : entries.entrySet()) {
Map<String, String> map = new HashMap<>();
for (Map.Entry<Object, Object> entry : entrySection.getValue().entrySet()) {
map.put(entry.getKey().toString(), entry.getValue().toString());
}
mapMap.put(entrySection.getKey(), map);
}
return mapMap;
}
/**
* Adds attributes of the specified manifest to this one. This manifest attributes are overrode by those of the specified
* one if same attribute exist.
*/
public JkManifest<T> merge(Manifest other) {
final Map<String, Attributes> otherEntryAttributes = other.getEntries();
for (final String entry : otherEntryAttributes.keySet()) {
final Attributes otherAttributes = otherEntryAttributes.get(entry);
final Attributes attributes = this.manifest.getAttributes(entry);
merge(attributes, otherAttributes);
}
merge(this.manifest.getMainAttributes(), other.getMainAttributes());
return this;
}
/**
* Write the signature file to the given output stream.
*/
private void generateSignatureFile(Manifest manifest, OutputStream out)
throws IOException, GeneralSecurityException {
out.write(("Signature-Version: 1.0\r\n").getBytes());
out.write(("Created-By: 1.0 (Android SignApk)\r\n").getBytes());
// BASE64Encoder base64 = new BASE64Encoder();
MessageDigest md = MessageDigest.getInstance("SHA1");
PrintStream print = new PrintStream(
new DigestOutputStream(new ByteArrayOutputStream(), md),
true, "UTF-8");
// Digest of the entire manifest
manifest.write(print);
print.flush();
out.write(("SHA1-Digest-Manifest: " + Base64.encode(md.digest()) + "\r\n\r\n").getBytes());
Map<String, Attributes> entries = manifest.getEntries();
for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
if (canceled) break;
progressHelper.progress(ProgressEvent.PRORITY_NORMAL, resourceAdapter.getString(ResourceAdapter.Item.GENERATING_SIGNATURE_FILE));
// Digest of the manifest stanza for this entry.
String nameEntry = "Name: " + entry.getKey() + "\r\n";
print.print(nameEntry);
for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
print.print(att.getKey() + ": " + att.getValue() + "\r\n");
}
print.print("\r\n");
print.flush();
out.write(nameEntry.getBytes());
out.write(("SHA1-Digest: " + Base64.encode(md.digest()) + "\r\n\r\n").getBytes());
}
}
/**
* Instantiates a new manifest info.
*
* @param mf the mf
*/
public ManifestInfo(Manifest mf) {
this.mf = mf;
if (mf != null) {
attr = mf.getAttributes("");
main = mf.getMainAttributes();
entries = mf.getEntries();
} else {
attr = null;
main = null;
entries = null;
}
}
/**
* Write a .SF file with a digest the specified manifest.
*/
private static byte[] writeSignatureFile(Manifest manifest, OutputStream out) throws IOException,
GeneralSecurityException {
final Manifest sf = new Manifest();
final Attributes main = sf.getMainAttributes();
main.putValue("Manifest-Version", MANIFEST_VERSION);
main.putValue("Created-By", CREATED_BY);
final MessageDigest md = MessageDigest.getInstance("SHA1");
final PrintStream print = new PrintStream(new DigestOutputStream(new ByteArrayOutputStream(), md), true, "UTF-8");
// Digest of the entire manifest
manifest.write(print);
print.flush();
main.putValue("SHA1-Digest-Manifest", base64encode(md.digest()));
final Map<String, Attributes> entries = manifest.getEntries();
for (final Map.Entry<String, Attributes> entry : entries.entrySet()) {
// Digest of the manifest stanza for this entry.
print.print("Name: " + entry.getKey() + "\r\n");
for (final Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
print.print(att.getKey() + ": " + att.getValue() + "\r\n");
}
print.print("\r\n");
print.flush();
final Attributes sfAttr = new Attributes();
sfAttr.putValue("SHA1-Digest", base64encode(md.digest()));
sf.getEntries().put(entry.getKey(), sfAttr);
}
final ByteArrayOutputStream sos = new ByteArrayOutputStream();
sf.write(sos);
String value = sos.toString();
String done = value.replace("Manifest-Version", "Signature-Version");
out.write(done.getBytes());
print.close();
sos.close();
return done.getBytes();
}
/** Write a .SF file with a digest of the specified manifest. */
private static void writeSignatureFile(Manifest manifest, OutputStream out,
int hash)
throws IOException, GeneralSecurityException {
Manifest sf = new Manifest();
Attributes main = sf.getMainAttributes();
main.putValue("Signature-Version", "1.0");
main.putValue("Created-By", "1.0 (Android SignApk)");
MessageDigest md = MessageDigest.getInstance(
hash == USE_SHA256 ? "SHA256" : "SHA1");
PrintStream print = new PrintStream(
new DigestOutputStream(new ByteArrayOutputStream(), md),
true, "UTF-8");
// Digest of the entire manifest
manifest.write(print);
print.flush();
main.putValue(hash == USE_SHA256 ? "SHA-256-Digest-Manifest" : "SHA1-Digest-Manifest",
new String(Base64.encode(md.digest()), "ASCII"));
Map < String, Attributes > entries = manifest.getEntries();
for (Map.Entry < String, Attributes > entry: entries.entrySet()) {
// Digest of the manifest stanza for this entry.
print.print("Name: " + entry.getKey() + "\r\n");
for (Map.Entry < Object, Object > att: entry.getValue().entrySet()) {
print.print(att.getKey() + ": " + att.getValue() + "\r\n");
}
print.print("\r\n");
print.flush();
Attributes sfAttr = new Attributes();
sfAttr.putValue(hash == USE_SHA256 ? "SHA-256-Digest" : "SHA1-Digest-Manifest",
new String(Base64.encode(md.digest()), "ASCII"));
sf.getEntries().put(entry.getKey(), sfAttr);
}
CountOutputStream cout = new CountOutputStream(out);
sf.write(cout);
// A bug in the java.util.jar implementation of Android platforms
// up to version 1.6 will cause a spurious IOException to be thrown
// if the length of the signature file is a multiple of 1024 bytes.
// As a workaround, add an extra CRLF in this case.
if ((cout.size() % 1024) == 0) {
cout.write('\r');
cout.write('\n');
}
}
private static String getManifestEntriesAttrs(JarFile jar) throws IOException {
StringBuilder sbManifest = new StringBuilder();
// Get current manifest
Manifest manifest = jar.getManifest();
// Write out entry attributes to manifest
if (manifest != null) {
// Get entry attributes
Map<String, Attributes> entries = manifest.getEntries();
boolean firstEntry = true;
// For each entry...
for (String entryName : entries.keySet()) {
// Get entry's attributes
Attributes entryAttrs = entries.get(entryName);
// Completely ignore entries that contain only a xxx-Digest
// attribute
if ((entryAttrs.size() == 1)
&& (entryAttrs.keySet().toArray()[0].toString().endsWith("-Digest"))) {
continue;
}
if (!firstEntry) {
// Entries subsequent to the first are split by a newline
sbManifest.append(CRLF);
}
// Get entry attributes as a string to preserve their order
String manifestEntryAttributes = getManifestEntryAttrs(jar, entryName);
// Write them out
sbManifest.append(manifestEntryAttributes);
// The next entry will not be the first entry
firstEntry = false;
}
}
return sbManifest.toString();
}