/**
*针对某个Element进行操作
*/
public interface ElementReader {
/**
* 判断一个bean元素是否需要延迟加载
*/
boolean isLazy(Element element);
/**
* 获得一个bean元素下的constructor-arg
*/
List<Element> getConstructorElements(Element element);
/**
* 得到元素属性为name的属性值
*/
String getAttribute(Element element, String name);
/**
* 判断一个元素是否为单态
*/
boolean isSingleton(Element element);
/**
* 获得一个bean元素下所有property元素
*/
List<Element> getPropertyElements(Element element);
/**
* 返回一个bean元素对应的Autowire对象
*/
Autowire getAutowire(Element element);
/**
* 获取bean元素下所有constructor-arg的值(包括value和ref)
*/
List<DataElement> getConstructorValue(Element element);
/**
* 获取bean元素下所有property元素的值(包括value和ref)
*/
List<PropertyElement> getPropertyValue(Element element);
}
public class ElementLoaderImpl implements ElementLoader {
private Map<String, Element> elements = new HashMap<String, Element>();
/**
* 将某个DOC下的elements全都加进MAP中
*/
public void addElements(Document doc) {
List<Element> eles = doc.getRootElement().elements();
for (Element e : eles) {
String id = e.attributeValue("id");
elements.put(id, e);
}
}
/**
* 得到指定ID的ELEMENT
*/
public Element getElement(String id) {
return elements.get(id);
}
/**
* 得到ROOT下的所有ELEMENTS
*/
public Collection<Element> getElements() {
return this.elements.values();
}
}
beans 节点:根节点为 beans,beans 的属性有 default-lazy-init 和 autowire,这两个属性的默认值(不需要显式提供)为 false 和 no。
bean 节点:beans 下面有多个 bean 节点,bean 节点必须要显式提供 id 和 class 属性,可以不必显式提供 lazy-init,singleton 和 autowire 属性,lazy-init 的默认值为 default,表示该值由beans 的 default-lazy-init 来决定,singleton 的默认值为 true,而且只允许有 true 和 false 两个值,autowire 属性的默认值是 default,由 beans 的 default-autowire 来决定。
construct-arg 节点:ref、value 和 null 都可以作为该节点的子节点,该节点没有属性。 property 节点:ref、value 和 null 都可以作为该节点的子节点,property 节点有一个 name 属性,而且是必须指定的。
ref 节点:该节点没有子节点,只有一个必须指定的 bean 属性。
value 节点:value 节点只有一个 type 属性,用于指定该值的类型。
public class ElementReaderImpl implements ElementReader {
@Override
public boolean isLazy(Element element) {
String lazy = getAttribute(element, "lazy-init");
Element parent = element.getParent();
Boolean parentLazy = new Boolean(getAttribute(parent, "default-lazy-init"));
if(parentLazy){
if("false".equals(lazy))
return false;
else
return true;
}else{
if("true".equals(lazy))
return true;
return false;
}
}
@Override
public List<Element> getConstructorElements(Element element) {
List<Element> children = element.elements();
List<Element> result = new ArrayList<Element>();
for(Element e:children){
if("constructor-arg".equals(e.getName())){
result.add(e);
}
}
return result;
}
@Override
public String getAttribute(Element element, String name) {
String value = element.attributeValue(name);
return value;
}
@Override
public boolean isSingleton(Element element) {
Boolean singleton = new Boolean(getAttribute(element, "singleton"));
return singleton;
}
@Override
public List<Element> getPropertyElements(Element element) {
List<Element> children = element.elements();
List<Element> result = new ArrayList<Element>();
for(Element e:children){
if("property".equals(e.getName())){
result.add(e);
}
}
return result;
}
@Override
public Autowire getAutowire(Element element) {
String value = this.getAttribute(element, "autowire");
String parentValue = this.getAttribute(element.getParent(), "default-autowire");
if("no".equals(parentValue)){
if("byName".equals(value))
return new ByNameAutowire(value);
return new NoAutowire(value);
}
else if("byName".equals(parentValue)){
if("no".equals(value))
return new NoAutowire(value);
return new ByNameAutowire(value);
}
return new NoAutowire(value);
}
@Override
public List<DataElement> getConstructorValue(Element element) {
List<Element> cons = getConstructorElements(element);
List<DataElement> result = new ArrayList<DataElement>();
for(Element e:cons){
List<Element> els = e.elements();
DataElement dataElement = getDataElement(els.get(0));
result.add(dataElement);
}
return result;
}
private DataElement getDataElement(Element dataElement) {
String name = dataElement.getName();
if("value".equals(name)){
String classTypeName = dataElement.attributeValue("type");
String data = dataElement.getText();
return new ValueElement(getValue(classTypeName,data));
}else if("ref".equals(name)) {
return new RefElement(this.getAttribute(dataElement, "bean"));
}
return null;
}
private Object getValue(String classTypeName, String data) {
if(isType(classTypeName,"Integer"))
return Integer.parseInt(data);
else if(isType(classTypeName,"Boolean"))
return Boolean.parseBoolean(data);
else if(isType(classTypeName,"Long"))
return Long.parseLong(data);
else if(isType(classTypeName,"Short"))
return Short.parseShort(data);
else if(isType(classTypeName,"Double"))
return Double.parseDouble(data);
else if(isType(classTypeName,"Float"))
return Float.parseFloat(data);
else if(isType(classTypeName,"Character"))
return data.charAt(0);
else if(isType(classTypeName,"Byte"))
return Byte.parseByte(data);
else
return data;
}
private boolean isType(String classTypeName, String type) {
if (classTypeName.indexOf(type) != -1) return true;
return false;
}
@Override
public List<PropertyElement> getPropertyValue(Element element) {
List<Element> properties = getPropertyElements(element);
List<PropertyElement> result = new ArrayList<PropertyElement>();
for(Element e:properties){
List<Element> els = e.elements();
DataElement dataElement = getDataElement(els.get(0));
String propertyNameAtt = this.getAttribute(e, "name");
PropertyElement pe = new PropertyElement(propertyNameAtt,dataElement);
result.add(pe);
}
return result;
}
}
public class XmlDocumentHolder implements DocumentHolder {
private Map<String, Document> docs = new HashMap<String, Document>();
@Override
public Document getDocument(String filePath) {
Document doc = this.docs.get(filePath);
if(doc == null){
this.docs.put(filePath, readDocument(filePath));
}
return this.docs.get(filePath);
}
private Document readDocument(String filePath) {
try {
SAXReader reader = new SAXReader(true);
reader.setEntityResolver(new IoCEntityResolver());
File xmlFile = new File(filePath);
Document doc = reader.read(xmlFile);
return doc;
} catch (Exception e) {
e.printStackTrace();
throw new DocumentException(e.getMessage());
}
}
}