package er.woinstaller.archiver; import java.io.File; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class XarEntry extends HashMap<String, Object> { private static final XPath xpath = XPathFactory.newInstance().newXPath(); private static XPathExpression parentNodes, xpOffset, xpLength, xpName, xpType; private final Node data; private MessageDigest digest; static { try { parentNodes = xpath.compile("ancestor::node()/name[../type=\"directory\"]"); xpOffset = xpath.compile("./data/offset/text()"); xpLength = xpath.compile("./data/length/text()"); xpName = xpath.compile("./name"); xpType = xpath.compile("./type"); } catch (XPathExpressionException e) { e.printStackTrace(); } } public XarEntry(Node node) { data = node; try { NodeList nodes = (NodeList)parentNodes.evaluate(data, XPathConstants.NODESET); StringBuilder s = new StringBuilder(); for (int i = 0; i < nodes.getLength(); i++) { Node n = nodes.item(i); s.append(n.getTextContent()).append(File.separatorChar); } String name = xpName.evaluate(data); String type = xpType.evaluate(data); s.append(name); this.put("name", s.toString()); this.put("type", type); if (get("type").equals("file")) { this.put("offset", Long.valueOf(xpOffset.evaluate(data))); this.put("length", Long.valueOf(xpLength.evaluate(data))); } } catch (XPathExpressionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Map<String, XarEntry> getEntries(Document doc) { Map<String, XarEntry> result = new HashMap<String, XarEntry>(); try { Object nodelist = xpath.evaluate("//file[type=\"file\"]", doc, XPathConstants.NODESET); NodeList nodes = (NodeList) nodelist; for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); XarEntry entry = new XarEntry(node); result.put(entry.getName(), entry); } } catch (XPathExpressionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; } public String getName() { return (String) this.get("name"); } public Long getOffset() { return (Long) this.get("offset"); } public Long getLength() { return (Long) this.get("length"); } public String getCompression() { String compression = (String)getValue("data.encoding.@style"); if (compression == null) { return null; } if ("application/x-bzip2".equals(compression)) { return "bzip2"; } if ("application/x-gzip".equals(compression)) { return "gzip"; } return compression; } public String getExtractedChecksum() { return (String)getValue("data.extracted-checksum"); } public long getSize() { return Long.valueOf((String) getValue("data.size")); } public boolean hasChecksum() { String checksum = getExtractedChecksum(); return checksum != null && !"".equals(checksum); } private Object getValue(String key) { try { return xpath.evaluate("./" + key.replace(".", "/"), data); } catch (XPathExpressionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public MessageDigest getMessageDigest(String checksumAlg) { if (checksumAlg == null) { return digest; } try { digest = MessageDigest.getInstance(checksumAlg); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } return digest; } }