Package com.firefly.core.support.xml.parse

Source Code of com.firefly.core.support.xml.parse.BeanNodeParser

package com.firefly.core.support.xml.parse;

import static com.firefly.core.support.xml.parse.XmlNodeConstants.ARGUMENT_ELEMENT;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.CLASS_ATTRIBUTE;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.CONTRUCTOR_ELEMENT;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.ID_ATTRIBUTE;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.NAME_ATTRIBUTE;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.PROPERTY_ELEMENT;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.REF_ATTRIBUTE;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.TYPE_ATTRIBUTE;
import static com.firefly.core.support.xml.parse.XmlNodeConstants.VALUE_ATTRIBUTE;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.firefly.core.support.xml.ManagedRef;
import com.firefly.core.support.xml.ManagedValue;
import com.firefly.core.support.xml.XmlBeanDefinition;
import com.firefly.core.support.xml.XmlBeanReader;
import com.firefly.core.support.xml.XmlGenericBeanDefinition;
import com.firefly.core.support.xml.XmlManagedNode;
import com.firefly.utils.ReflectUtils;
import com.firefly.utils.StringUtils;
import com.firefly.utils.VerifyUtils;
import com.firefly.utils.dom.Dom;

public class BeanNodeParser extends AbstractXmlNodeParser implements XmlNodeParser {

  @Override
  public Object parse(Element ele, Dom dom) {
    // gets basic attribute
    String id = ele.getAttribute(ID_ATTRIBUTE);
    String className = ele.getAttribute(CLASS_ATTRIBUTE);
    XmlBeanDefinition xmlBeanDefinition = new XmlGenericBeanDefinition();
    xmlBeanDefinition.setId(id);
    xmlBeanDefinition.setClassName(className);

   
    Class<?> clazz = null;
    log.info("classes [{}]", className);
    try {
      clazz = XmlBeanReader.class.getClassLoader().loadClass(className);
    } catch (Throwable e) {
      error("loads class \"" + className + "\" error");
    }
   
    // gets bean's constructor
    List<Element> constructors = dom.elements(ele, CONTRUCTOR_ELEMENT);
    if(constructors != null && constructors.size() > 0) {
      Element constructorElement = constructors.get(0);
      List<Element> arguments = dom.elements(constructorElement, ARGUMENT_ELEMENT);
      if(arguments != null && arguments.size() >= 1) {
        List<Class<?>> argsClass = new ArrayList<Class<?>>();
        for(Element argument : arguments) {
          XmlManagedNode xmlManagedNode = parseXmlManagedNode(argument, dom);
          if(xmlManagedNode != null) {
            xmlBeanDefinition.getContructorParameters().add(xmlManagedNode);
          }
          String initArgsType = argument.getAttribute(TYPE_ATTRIBUTE);
          if(VerifyUtils.isNotEmpty(initArgsType)) {
            try {
              argsClass.add(XmlBeanReader.class.getClassLoader().loadClass(initArgsType));
            } catch (ClassNotFoundException e) {
              error("The '" + initArgsType + "' not found");
            }
          } else {
            error("The '" + className + "' constructor argument node MUST has type attribute");
          }
        }
        try {
          xmlBeanDefinition.setConstructor(clazz.getConstructor(argsClass.toArray(new Class<?>[0])));
        } catch (Throwable e) {
          error("The '" + className + "' gets constructor error");
        }
      } else {
        error("The '" + className + "' constructor node MUST be more than one argument node!");
      }
    } else {
      try {
        xmlBeanDefinition.setConstructor(clazz.getConstructor(new Class<?>[0]));
      } catch (Throwable e) {
        error("The '" + className + "' gets constructor error");
      }
    }

    // gets all interface name
    String[] names = ReflectUtils.getInterfaceNames(clazz);
    xmlBeanDefinition.setInterfaceNames(names);
    log.debug("class [{}] names size [{}]", className, names.length);

    // gets all properties
    List<Element> properties = dom.elements(ele, PROPERTY_ELEMENT);
    if (properties != null) {
      for (Element property : properties) {
        String name = property.getAttribute(NAME_ATTRIBUTE);
        XmlManagedNode xmlManagedNode = parseXmlManagedNode(property, dom);
        if(xmlManagedNode != null && VerifyUtils.isNotEmpty(name)) {
          xmlBeanDefinition.getProperties().put(name, xmlManagedNode);
        }
      }
    }
    return xmlBeanDefinition;
  }
 
  private XmlManagedNode parseXmlManagedNode(Element property, Dom dom) {
    boolean hasValueAttribute = property.hasAttribute(VALUE_ATTRIBUTE);
    boolean hasRefAttribute = property.hasAttribute(REF_ATTRIBUTE);

    // element types choose one of ref, value, list, etc.
    NodeList nl = property.getChildNodes();
    Element subElement = null;
    for (int i = 0; i < nl.getLength(); ++i) {
      Node node = nl.item(i);
      if (node instanceof Element) {
        if (subElement != null) {
          error("This element must not contain more than one sub-element");
        } else {
          subElement = (Element) node;
        }
      }
    }

    if (hasValueAttribute && hasRefAttribute ||
        ((hasValueAttribute || hasRefAttribute) && subElement != null)) {
      error("This element is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element");
    }

    if (hasValueAttribute) {
      // literal value
      String value = property.getAttribute(VALUE_ATTRIBUTE);
      if (!StringUtils.hasText(value)) {
        error("This element contains empty 'value' attribute");
      }
      return new ManagedValue(value);
    } else if (hasRefAttribute) {
      // bean reference
      String ref = property.getAttribute(REF_ATTRIBUTE);
      if (!StringUtils.hasText(ref)) {
        error("This element contains empty 'ref' attribute");
      }
      return new ManagedRef(ref);
    } else if (subElement != null) {
      // sub-elements
      return (XmlManagedNode)XmlNodeStateMachine.stateProcessor(subElement, dom);
    } else {
      error("This element must specify a ref or value");
      return null;
    }
  }
}
TOP

Related Classes of com.firefly.core.support.xml.parse.BeanNodeParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.