if (!getState())
return null;
// Real stuff starts here
AttributeList attrs = null;
// returns null to indicate file does not exist
File file = checkFileForRead(id);
if (file != null) {
// parse the saved XML doc
Document doc = parseXmlFile(file);
// top level - look for AL_ROOT_ELEMENT
NodeList docList = doc.getChildNodes();
Element root = null;
for (int i = 0; i < docList.getLength(); i++) {
Node node = docList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE &&
node.getNodeName().equals(AL_ROOT_ELEMENT)) {
root = (Element)node;
break; // found
}
}
// root element must be there
if (root == null) {
throw new Exception("Expected XML element: " + AL_ROOT_ELEMENT);
}
else {
// proceed iterating over AL_ATTRIBUTE_ELEMENT elements
// and fill the AttributeList
attrs = new AttributeList();
NodeList rootList = root.getChildNodes();
for (int i = 0; i < rootList.getLength(); i++) {
Node node = rootList.item(i);
// only interested in ELEMENT nodes
if (node.getNodeType() == Node.ELEMENT_NODE &&
node.getNodeName().equals(AL_ATTRIBUTE_ELEMENT)) {
Element element = (Element)node;
// name attribute must always be there
String name = element.getAttribute(AL_NAME_ATTRIBUTE);
if (!(name.length() > 0)) {
throw new Exception("Attribute '" + AL_NAME_ATTRIBUTE +
"' must be specified for element '" + AL_ATTRIBUTE_ELEMENT + "'");
}
// Process the attribute depending on how the attributes are set
if (element.getAttribute(AL_NULL_ATTRIBUTE).toLowerCase().equals(AL_TRUE_VALUE)) {
// (a) null value - just add it to the AttributeList
attrs.add(new Attribute(name, null));
}
else if (element.getAttribute(AL_SERIALIZED_ATTRIBUTE).toLowerCase().equals(AL_TRUE_VALUE)) {
// (b) serialized value - decode the HexString
String hexStr = getElementContent(element);
Serializable obj = decodeFromHexString(hexStr);
if (obj == null) {
throw new Exception("Failed to deserialize attribute '" + name + "'");
}
else {
attrs.add(new Attribute(name, obj));
}
}
else {
String type = element.getAttribute(AL_TYPE_ATTRIBUTE);
// type must be specified
if (!(type.length() > 0)) {
throw new Exception("Attribute '" + AL_TYPE_ATTRIBUTE +
"' must be specified for name='" + name + "'");
}
if (type.equals("org.w3c.dom.Element")) {
// (c) org.w3c.dom.Element - deep copy first Element child node found
NodeList nlist = element.getChildNodes();
Element el = null;
for (int j = 0; j < nlist.getLength(); j++) {
Node n = nlist.item(j);
if (n.getNodeType() == Node.ELEMENT_NODE)
{
el = (Element)n;
break;
}
}
if (el != null) {
attrs.add(new Attribute(name, el.cloneNode(true)));
}
else {
attrs.add(new Attribute(name, null));
}
}
else {
// Get the classloader for loading attribute classes.
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class clazz = null;
try {
clazz = cl.loadClass(type);
}
catch (ClassNotFoundException e) {
throw new Exception("Class not found for attribute '" + name +
"' of type '" + type + "'");
}
PropertyEditor peditor = PropertyEditorManager.findEditor(clazz);
if (peditor != null) {
// (d) use a PropertyEditor - extract the value
String value = getElementContent(element);
peditor.setAsText(value);
attrs.add(new Attribute(name, peditor.getValue()));
}
else {
throw new Exception("Cannot find a way to load attribute '" + name +
"' of type '" + type + "'");
}