package com.firefly.core.support.xml;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.BEAN_ELEMENT;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.IMPORT_ELEMENT;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.firefly.core.support.AbstractBeanReader;
import com.firefly.core.support.BeanDefinition;
import com.firefly.core.support.xml.parse.XmlNodeStateMachine;
import com.firefly.utils.VerifyUtils;
import com.firefly.utils.dom.DefaultDom;
import com.firefly.utils.dom.Dom;
/**
* Reading XML configuration file
*
* @author JJ Xu, Alvin Qiu
*/
public class XmlBeanReader extends AbstractBeanReader {
public XmlBeanReader() {
this(null);
}
public XmlBeanReader(String file) {
beanDefinitions = new ArrayList<BeanDefinition>();
Dom dom = new DefaultDom();
Set<String> errorMemo = new HashSet<String>(); // It's used for eliminating circular references
// all bean elements
List<Element> beansList = new ArrayList<Element>();
parseXml(dom, file, beansList, errorMemo);
if (beansList != null) {
for (Element ele : beansList) {
beanDefinitions.add((BeanDefinition) XmlNodeStateMachine.stateProcessor(ele, dom));
}
}
}
private void parseXml(Dom dom, String file, List<Element> beansList, Set<String> errorMemo) {
Document doc = dom.getDocument(file == null ? "firefly.xml" : file);
Element root = dom.getRoot(doc);
// all bean nodes
List<Element> list = dom.elements(root, BEAN_ELEMENT);
// all import nodes
List<Element> importList = dom.elements(root, IMPORT_ELEMENT);
if (importList != null) {
for (Element ele : importList) {
if (ele.hasAttribute("resource")) {
String resource = ele.getAttribute("resource");
if (errorMemo.contains(resource)) {
error("disallow cyclic references between two XML files");
return;
} else {
if (VerifyUtils.isEmpty(resource)) {
error("resource cannot be null");
return;
} else {
errorMemo.add(resource);
parseXml(dom, resource, beansList, errorMemo);
}
}
} else {
error("has no resource attribute");
return;
}
}
}
beansList.addAll(list);
}
}