/**
* **************************************************************************
*
* Contributor(s):
* C. Heazel (WiSC): Added Fortify adjudication changes
*
***************************************************************************
*/
package com.occamlab.te.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
* Provides various utility methods (general collection).
*
* @author jparrpearson
*/
public class Utils {
private static Logger jlogger = Logger
.getLogger("com.occamlab.te.util.Utils");
/**
* Returns a random string of a certain length
*
*/
public static String randomString(int len, Random random) {
if (len < 1) {
return "";
}
int start = ' ';
int end = 'z' + 1;
StringBuffer buffer = new StringBuffer();
int gap = end - start;
while (len-- != 0) {
char ch;
ch = (char) (random.nextInt(gap) + start);
if (Character.isLetterOrDigit(ch)) {
buffer.append(ch);
} else {
len++;
}
}
return buffer.toString();
}
/**
* Uses MD5 to create a hash value for the given String
*
*/
public static String generateMD5(String text) {
byte[] md5hash = null;
try {
MessageDigest md;
md = MessageDigest.getInstance("MD5");
md5hash = new byte[8];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
md5hash = md.digest();
} catch (Exception e) {
jlogger.log(Level.SEVERE,
"Error generating MD5: " + e.getMessage(), e);
System.out.println("Error generating MD5: " + e.getMessage());
return "";
}
return convertToHex(md5hash);
}
/**
* Converts a String to Hex digits
*
*/
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9)) {
buf.append((char) ('0' + halfbyte));
} else {
buf.append((char) ('a' + (halfbyte - 10)));
}
halfbyte = data[i] & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}
/**
* Converts an XPointer to XPath and evaulates the result (JAXP)
*
*/
public static String evaluateXPointer(String xpointer, InputStream is) {
String results = "";
// Parse the XPointer into usable namespaces and XPath expressions
int xmlnsStart = xpointer.indexOf("xmlns(") + "xmlns(".length();
int xmlnsEnd = xpointer.indexOf(")", xmlnsStart);
int xpathStart = xpointer.indexOf("xpointer(") + "xpointer(".length();
int xpathEnd = xpointer.indexOf(")", xpathStart);
String xmlnsStr = xpointer.substring(xmlnsStart, xmlnsEnd);
String xpathStr = xpointer.substring(xpathStart, xpathEnd);
// System.out.println("xmlnsStr: "+xmlnsStr+" xpathStr: "+xpathStr);
try {
XPath xpath = XPathFactory.newInstance().newXPath();
String[] namespaces = xmlnsStr.split(",");
// Add namespaces to XPath element
MyNamespaceContext context = new MyNamespaceContext();
for (int i = 0; i < namespaces.length; i++) {
String[] xmlnsParts = namespaces[i].split("=");
context.setNamespace(xmlnsParts[0], xmlnsParts[1]);
xpath.setNamespaceContext(context);
}
InputSource src = new InputSource(is);
results = (String) xpath.evaluate(xpathStr, src);
// System.out.println("results: "+results);
} catch (Exception e) {
jlogger.log(Level.SEVERE,
"Error in evaluating XPointer. " + e.getMessage(), e);
System.out.println("Error in evaluating XPointer. "
+ e.getMessage());
}
return results;
}
public static String evaluateXPointer(String xpointer, Document doc) {
InputStream is = null;
try {
is = IOUtils.DocumentToInputStream(doc);
} catch (IOException e) {
jlogger.log(Level.SEVERE, "evaluateXPointer", e);
}
return evaluateXPointer(xpointer, is);
}
public static String evaluateXPointer(String xpointer, byte[] bytes) {
Document doc = null;
try {
ByteArrayInputStream baip = new ByteArrayInputStream(bytes);
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
// Fortify Mod: prevent external entity injection
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(baip);
} catch (Exception e) {
jlogger.log(Level.SEVERE, "evaluateXPointer", e);
}
return evaluateXPointer(xpointer, doc);
}
/**
* Custom namespace class for adding additional namespaces for XPath
* evaluation
*
*/
public static class MyNamespaceContext implements NamespaceContext {
private Map<String, String> map;
public MyNamespaceContext() {
map = new HashMap<String, String>();
}
public void setNamespace(String prefix, String namespaceURI) {
map.put(prefix, namespaceURI);
}
public String getNamespaceURI(String prefix) {
return (String) map.get(prefix);
}
public String getPrefix(String namespaceURI) {
Set keys = map.keySet();
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
String prefix = (String) iterator.next();
String uri = (String) map.get(prefix);
if (uri.equals(namespaceURI))
return prefix;
}
return null;
}
public Iterator getPrefixes(String namespaceURI) {
List<String> prefixes = new ArrayList<String>();
Set keys = map.keySet();
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
String prefix = (String) iterator.next();
String uri = (String) map.get(prefix);
if (uri.equals(namespaceURI))
prefixes.add(prefix);
}
return prefixes.iterator();
}
}
}