a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* opensso/legal/CDDLv1.0.txt
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* at opensso/legal/CDDLv1.0.txt.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster* $Id: FilesDigester.java,v 1.2 2008/09/04 22:26:12 kevinserwin Exp $
f948ca04a28ccfeed9633bf4b0fb0d2c59c37478David Luna*/
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpackage com.sun.identity.tools.manifest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.File;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.FileInputStream;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.InputStream;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.IOException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.security.MessageDigest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.security.NoSuchAlgorithmException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Enumeration;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.LinkedList;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.jar.JarEntry;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.jar.JarFile;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.jar.JarInputStream;
f948ca04a28ccfeed9633bf4b0fb0d2c59c37478David Lunaimport java.util.Properties;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
f948ca04a28ccfeed9633bf4b0fb0d2c59c37478David Lunapublic class FilesDigester implements ManifestConstants {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected LinkedList includePattern;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected LinkedList excludePattern;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected char wildCard;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected boolean recursive;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * FileDigester constructor
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param includePattern A list of patterns of file name should be included.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param excludePattern A list of patterns of file name should be excluded.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param wildCard The wildcard character which is used in the pattern.
*/
public FilesDigester(LinkedList includePattern, LinkedList excludePattern,
char wildCard, boolean recursive) {
this.includePattern = includePattern;
this.excludePattern = excludePattern;
this.wildCard = wildCard;
this.recursive = recursive;
}
/**
* This function calculate the hash value of a war file.
*
* This function will calculate the manifest according to the decompressed
* files contained in the war file.
*
* @param hashAlg The algorithm to be used for calculating the hash.
* @param digestResult The Properties to store the results.
* @param wfile The war file to be processed.
* @param intoJar The flat to indicate whether to handle jar file by using
* its decompressed contents.
*/
protected void digestWarFile(String hashAlg, Properties digestResult,
JarFile wfile, boolean intoJar){
Enumeration wEnum = wfile.entries();
byte[] digestCode = null;
String wename = null;
InputStream in = null;
try {
while (wEnum.hasMoreElements()) {
JarEntry we = (JarEntry) wEnum.nextElement();
if (!we.isDirectory()) {
wename=we.getName();
if (wename.endsWith(JAR_FILE_EXT) && (intoJar)) {
in=wfile.getInputStream(we);
digestCode = digestJarFile(hashAlg, in);
in.close();
} else{
in = wfile.getInputStream(we);
digestCode = Utils.getHash(hashAlg, in);
in.close();
}
appendResult(digestResult, wename, digestCode);
}
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignored) {
}
in = null;
}
}
}
/**
* This function calculate the hash value of a jar file.
*
* This function handles the jar file as a concatenation of the decompressed
* files it contains.
*
* @param hashAlg The algorithm to be used for calculating the hash.
* @param in The InputStream of the jar file to be processed.
*/
protected byte[] digestJarFile(String hashAlg, InputStream in){
JarInputStream jin = null;
try {
jin=new JarInputStream(in);
JarEntry je = null;
MessageDigest md = MessageDigest.getInstance(hashAlg);
while ((je=jin.getNextJarEntry()) != null) {
if (!je.isDirectory()) {
md = Utils.hashing(md, jin);
}
jin.closeEntry();
}
jin.close();
return md.digest();
} catch (IOException ex) {
ex.printStackTrace();
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
} finally {
if (jin != null) {
try {
jin.close();
} catch (IOException ignored) {
}
jin = null;
}
}
return null;
}
/**
* This function calculate the hash value of a file.
*
* @param hashAlg The algorithm to be used for calculating the hash.
* @param file The file to be processed.
* @param digestResult The Properties to store the results.
* @param ignoredPath The parent's path to ignore when printing the
* manifest entries.
* @param intoJar The flag to indicate whether to specially handle
* jar file.
* @param intoWar The flag to indicate whether to specially handle
* war file.
*/
public void digest(String hashAlg, File file, Properties digestResult,
String ignoredPath, boolean intoJar, boolean intoWar){
if (file.exists()) {
if (file.isDirectory()) {
if (recursive) {
File[] tempFiles = null;
if (includePattern != null) {
tempFiles = file.listFiles(new GeneralFileFilter(
includePattern));
} else{
tempFiles = file.listFiles();
}
for (int i = 0; i < tempFiles.length; i++) {
if (tempFiles[i].isDirectory()) {
digest(hashAlg, tempFiles[i], digestResult,
ignoredPath, intoJar, intoWar);
} else{
if (excludePattern != null) {
if (!Utils.isMatch(tempFiles[i].getName(),
excludePattern, wildCard)) {
digest(hashAlg, tempFiles[i], digestResult,
ignoredPath, intoJar, intoWar);
}
} else{
digest(hashAlg, tempFiles[i], digestResult,
ignoredPath, intoJar, intoWar);
}
}
}
}
} else{
if (file.getName().endsWith(WAR_FILE_EXT) && (intoWar)) {
try {
digestWarFile(hashAlg, digestResult, new JarFile(file),
intoJar);
} catch (IOException ex) {
ex.printStackTrace();
}
} else{
byte[] digestedbyte = null;
if ((file.getName().endsWith(JAR_FILE_EXT)) && (intoJar)) {
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
digestedbyte = digestJarFile(hashAlg, fin);
fin.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException ignored) {
}
fin = null;
}
}
} else{
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
digestedbyte = Utils.getHash(hashAlg, fin);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException ignored) {
}
fin = null;
}
}
}
String tempPath=file.getPath();
tempPath=tempPath.substring(tempPath.indexOf(ignoredPath) +
ignoredPath.length()).replaceAll("\\\\",
FILE_SEPARATOR);
if (tempPath.startsWith(FILE_SEPARATOR)) {
tempPath=tempPath.substring(1);
}
appendResult(digestResult, tempPath, digestedbyte);
}
}
}
}
/**
* This function append the result to the StringBuffer.
*
* @param result The properties to store the results.
* @param path The path of the entry.
* @param digestedbyte The byte array which contains the digested result.
*/
protected void appendResult(Properties result, String path,
byte[] digestedbyte){
result.setProperty(path, Utils.translateHashToString(digestedbyte));
}
}