All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jangaroo.exml.configconverter.xml.XsdScanner Maven / Gradle / Ivy

There is a newer version: 0.9.5
Show newest version
/*
 * Copyright (c) 2009, CoreMedia AG, Hamburg. All rights reserved.
 */
package net.jangaroo.exml.configconverter.xml;

import net.jangaroo.exml.configconverter.ComponentSuiteRegistry;
import net.jangaroo.exml.configconverter.model.ComponentClass;
import net.jangaroo.exml.configconverter.model.ComponentSuite;
import net.jangaroo.exml.configconverter.model.ConfigAttribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;

public class XsdScanner {

  private static final String XML_SCHEMA_URL = "http://www.w3.org/2001/XMLSchema";
  private final Logger log = LoggerFactory.getLogger(XsdScanner.class);

  private ComponentSuite componentSuite;
  private XMLStreamReader parser = null;
  private Stack ccStack = new Stack();
  private ConfigAttribute currentAttr = null;
  private boolean isInsideComplexType = false;
  private boolean isInsideCfg = false;
  private ComponentSuiteRegistry componentSuiteRegistry;

  private static final String SCHEMA = "schema";
  private static final String COMPLEX_TYPE = "complexType";
  private static final String ELEMENT = "element";
  private static final String ATTRIBUTE = "attribute";
  private static final String EXTENSION = "extension";
  private static final String DOCUMENTATION = "documentation";

  public XsdScanner(ComponentSuiteRegistry componentSuiteRegistry) {
    this.componentSuiteRegistry = componentSuiteRegistry;
  }

  public ComponentSuite getComponentSuite() {
    return componentSuite;
  }

  private boolean isLocalName(String localName) {
    return localName.equals(parser.getLocalName());
  }

  private ComponentSuite createComponentSuite() {
    String targetNS = parser.getAttributeValue(null, "targetNamespace");
    String nsPrefix = parser.getNamespaceContext().getPrefix(targetNS);
    return new ComponentSuite(componentSuiteRegistry, targetNS, nsPrefix, null, null, null);
  }

  private ComponentClass createComponentClass() {
    String name = parser.getAttributeValue(null, "name");
    ComponentClass componentClass = new ComponentClass(null, name);
    ccStack.push(componentClass);
    return componentClass;
  }

  private void addXtypeToComponentClass() throws XMLStreamException {
    String xtype = parser.getAttributeValue(null, "id");
    if (xtype == null) {
      xtype = parser.getAttributeValue(null, "name");
    }

    String typeName = afterColon(parser.getAttributeValue(null, "type"));
    if (typeName.startsWith("ext.")) {
      xtype = xtype.toLowerCase();
    }

    ComponentClass componentClass = ccStack.lastElement();
    assert typeName.equals(componentClass.getFullClassName());
    componentClass.setXtype(xtype);
  }

  private String afterColon(String typeName) {
    return typeName.substring(typeName.indexOf(':') + 1);
  }

  private void addSupertypeToComponentClass() {
    String supertypeName = afterColon(parser.getAttributeValue(null, "base"));
    ComponentClass componentClass = ccStack.lastElement();
    componentClass.setSuperClassName(supertypeName);
  }

  private void addConfigElementAttribute() throws XMLStreamException {
    String name = parser.getAttributeValue(null, "name");
    ConfigAttribute attr = new ConfigAttribute(name, "Array");
    ccStack.lastElement().addCfg(attr);
    currentAttr = attr;
  }

  private void addConfigAttribute() throws XMLStreamException {
    String name = parser.getAttributeValue(null, "name");
    String type = parser.getAttributeValue(null, "type");
    ConfigAttribute attr = new ConfigAttribute(name, type);
    ccStack.lastElement().addCfg(attr);
    currentAttr = attr;
  }

  private void parseDocumentation() throws XMLStreamException {
    StringBuffer txt = new StringBuffer();
    while (parser.hasNext()) {
      parser.next();

      if (parser.hasText()) {
        txt.append(parser.getText());
      } else if (parser.isStartElement()) {
        txt.append("<").append(parser.getLocalName()).append(">");
      } else if (parser.isEndElement()) {
        if(isLocalName(DOCUMENTATION)) {
          break;
        } else {
          txt.append("");
        }
      }
    }
    if (currentAttr != null) {
      currentAttr.setDescription(txt.toString());
    } else {
      ccStack.lastElement().setDescription(txt.toString());
    }
  }

  public ComponentSuite scan(InputStream xsd) throws IOException {
    XMLInputFactory factory = XMLInputFactory.newInstance();

    try {
      parser = factory.createXMLStreamReader(xsd);
      while (parser.hasNext()) {
        int event = parser.next();
        if (XML_SCHEMA_URL.equals(parser.getNamespaceURI())) {
          dispatch(event);
        }
      }
    } catch (XMLStreamException e) {
      log.error("Error while parsing XSD", e);
    } finally {
      try {
        if (parser != null) {
          parser.close();
        }
      } catch (XMLStreamException e) {
        log.error("Error while parsing XSD", e);
      }
    }
    return componentSuite;
  }

  private void dispatch(int event) throws XMLStreamException {
    switch (event) {
      case XMLStreamConstants.START_ELEMENT:
        if (isLocalName(SCHEMA)) {
          componentSuite = createComponentSuite();
          break;
        } else if (!isInsideComplexType && isLocalName(COMPLEX_TYPE)) {
          isInsideComplexType = true;
          createComponentClass();
          break;
        } else if (isLocalName(ELEMENT)) {
          if (isInsideComplexType) {
            addConfigElementAttribute();
            isInsideCfg = true;
          } else {
            addXtypeToComponentClass();
          }
        } else if (isInsideComplexType && !isInsideCfg && isLocalName(EXTENSION)) {
          addSupertypeToComponentClass();
        } else if (isLocalName(ATTRIBUTE)) {
          addConfigAttribute();
        } else if (isLocalName(DOCUMENTATION)) {
          parseDocumentation();
        }
        break;
      case XMLStreamConstants.END_ELEMENT:
        if (isLocalName(SCHEMA)) {
          assert ccStack.isEmpty();
        } else if (isLocalName(COMPLEX_TYPE) && !isInsideCfg) {
          isInsideComplexType = false;
        } else if (isLocalName(ELEMENT)) {
          if (isInsideCfg) {
            isInsideCfg = false;
            currentAttr = null;
          } else {
            ComponentClass componentClass = ccStack.pop();
            componentSuite.addComponentClass(componentClass);
          }
        } else if(isLocalName(ATTRIBUTE)) {
          currentAttr = null;
        }

        break;
      case XMLStreamConstants.CHARACTERS:

        break;
      case XMLStreamConstants.CDATA:

        break;
    } // end switch
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy