I am using XPath to read the contents of an Xml file stored locally in internal storage.
I have two methods. Each gets data from the xml file. The first method runs fine and works. The second method is almost the same as the first except it looks for different data. However, this method errors with read failed: EBADF.
The line that generates the error is in the ProcessEscalationLevels method.
NodeList nodes = (NodeList) xPath.evaluate(expression, source,
XPathConstants.NODESET);
The two methods that get data plus the calling methods are below. Does anyone know what could be causing this error? I figure that it thinks the file stream is closed but am unable to work out why.
public void processSiteFile(File sitexml) throws IOException,
XPathExpressionException {
this.sitexml = sitexml;
FileInputStream stream = new FileInputStream(this.sitexml);
try {
InputSource source = new InputSource(stream);
XPath xPath = XPathFactory.newInstance().newXPath();
// emergency category names
processCategoryNames(xPath, source);
// Process escalation levels
processEscalationLevels(xPath, source);
} finally {
stream.close();
}
}
private void processEscalationLevels(XPath xPath, InputSource source)
throws XPathExpressionException, FileNotFoundException {
String expression = "/site_settings/group_category_permission_list"
+ "/group_category_permission";
NodeList nodes = (NodeList) xPath.evaluate(expression, source,
XPathConstants.NODESET);
if (nodes != null && nodes.getLength() > 0) {
for (int i = 0; i < nodes.getLength(); i++) {
Element entry = (Element) nodes.item(i);
// extract group id
String tmpGroupId = xPath.evaluate("group_id", entry);
int groupId = 0;
if (tmpGroupId != null) {
try {
groupId = Integer.valueOf(tmpGroupId);
} catch (NumberFormatException e) {
groupId = 0;
}
}
// extract category name
String categoryName = xPath.evaluate("category_name", entry);
if (categoryName == null)
categoryName = ClientData.DEFAULT_CATEGORY;
ClientData.GroupPermission permission =
new ClientData.GroupPermission(groupId, categoryName);
// extract escalation levels and add to permission
NodeList permissionNodes = (NodeList) xPath.evaluate(
"escalation_level_list/escalation_level", entry,
XPathConstants.NODESET);
for (int e = 0; e < permissionNodes.getLength(); e++) {
Element permEntry = (Element) permissionNodes.item(e);
// get seconds before escalating
String tmpSecsBeforeEscalating = xPath.evaluate(
"secs_before_escalating", permEntry);
int secsBeforeEscalating = 0;
if (tmpSecsBeforeEscalating == null) {
secsBeforeEscalating = ClientData.DEFAULT_ESCALATION_TIME;
} else {
secsBeforeEscalating = Integer
.valueOf(tmpSecsBeforeEscalating);
}
// get list of target group ids
NodeList targetGroupNodes = (NodeList) xPath.evaluate(
"target_group_id_list/target_group_ids", permEntry,
XPathConstants.NODESET);
Set<Integer> targetGroups = new HashSet<Integer>();
for (int o = 0; o < targetGroupNodes.getLength(); o++) {
Node groupEntry = (Node) targetGroupNodes.item(o);
targetGroups.add(Integer.valueOf(groupEntry
.getTextContent()));
}
permission.escalationLevels
.add(permission.new EscalationLevel(targetGroups,
secsBeforeEscalating));
}
// Add permission to permission list
ClientData.groupPermissions.add(permission);
}
}
}
private void processCategoryNames(XPath xPath, InputSource source)
throws XPathExpressionException {
String expression = "/site_settings/emergency_category_list"
+ "/emergency_category";
NodeList nodes = (NodeList) xPath.evaluate(expression, source,
XPathConstants.NODESET);
if (nodes != null && nodes.getLength() > 0) {
List<String> categories = new ArrayList<String>();
for (int i = 0; i < nodes.getLength(); i++) {
Node entry = nodes.item(i);
if (entry.getNodeName() == "name") {
categories.add(entry.getTextContent());
} else if (entry.getNodeName() == "secs_before_repeating") {
ClientData.secsBeforeRepeatingEmergency = Integer
.valueOf(entry.getTextContent());
}
}
// Write category list to ClientData
ClientData.emergencyCategory = (String[]) categories.toArray();
} else {
// Write a default category and repeat time
ClientData.emergencyCategory = new String[] {
ClientData.DEFAULT_CATEGORY
};
ClientData.secsBeforeRepeatingEmergency =
ClientData.DEFAULT_EMERGENCY_REPEAT_TIME;
}
}