/** * @author Mauricio Araya (maray[at]inf.utfsm.cl) * @author Jorge Avarias (javarias[at]alumnos.inf.utfsm.cl) */ package cl.utfsm.acs.xml; import org.apache.xerces.parsers.DOMParser; import org.w3c.dom.*; import java.util.ArrayList; import cl.utfsm.acs.types.*; /** The common schema reads the COMMON_TYPES schema file, and setup general types definitions. * The main purpose of this class is to have the information of the schema files centralized in * a schema class. This object automatically parse the schema file and save all the simple and * complex types into an internal Arraylist. * @author Mauricio Araya (maray[at]inf.utfsm.cl) */ public class CommonSchema{ /** The common types schema filename */ static protected String COMMON_TYPES="commontypes.xsd"; /** The local DOM parser reference */ protected DOMParser parser; /** The DOM Document object. */ protected Document commonTypes; /** The list of types on the schema */ protected ArrayList<AcsType> typeList; /** Parse the schema file and initialize the class. Also adds basic types * from the classic schema definition. * <p> * TODO: add all the classic schema definitions */ public CommonSchema(){ parser = new DOMParser(); String acsroot = System.getProperty("ACS.acsroot"); // Parse the schema file. This is far away from optimal, but its done only once if (acsroot != null) { try { parser.parse(acsroot + "/idl/" + COMMON_TYPES); commonTypes=parser.getDocument(); } catch (Exception e) { e.getMessage(); // Improve this catch } } else { throw new NullPointerException( "Property 'ACS.acsroot' must be defined!"); } searchSimpleTypes(commonTypes,"common"); //Add some types from xs: typeList.add(new AcsSimpleType("xs","string","A string",null)); typeList.add(new AcsSimpleType("xs","boolean","A boolean",null)); searchComplexTypes(commonTypes,"common"); } /** Search for SimpleTypes in the parsed document and add them to the Arraylist. * @param doc The DOM document to search * @param namespace The namespace that those types should have */ public void searchSimpleTypes(Document doc,String namespace){ if (typeList==null) typeList=new ArrayList<AcsType>(); //Simple Types String documentation=""; NodeList sTypes=doc.getElementsByTagName("xs:simpleType"); for (int i=0;i<sTypes.getLength();i++){ Node item=sTypes.item(i); String name=item.getAttributes().getNamedItem("name").getNodeValue(); NodeList lvl1=item.getChildNodes(); // Get the documentation and the "restriction" for (int j=0;j<lvl1.getLength();j++){ Node one=lvl1.item(j); String oneName=one.getLocalName(); if (oneName != null && oneName.compareTo("annotation")==0){ documentation=readDocumentation(one); } //TODO: Add Restriction value } AcsSimpleType aType=new AcsSimpleType(namespace,name,documentation,null); typeList.add(aType); } } /** Read a DOM attribute node and return a new AcsAttribute object * @param node the DOM attribute node * @return A new AcsAttribute object from the node*/ public AcsAttribute readAttribute(Node one){ String atrUse=""; String atrName=one.getAttributes().getNamedItem("name").getNodeValue(); String atrType=one.getAttributes().getNamedItem("type").getNodeValue(); try{ atrUse=one.getAttributes().getNamedItem("use").getNodeValue(); } catch (java.lang.NullPointerException e){ atrUse=""; } AcsSimpleType simple; try{ simple = (AcsSimpleType)getType(atrType.split(":")[1]); }catch(IndexOutOfBoundsException ex){ simple = (AcsSimpleType)getType(atrType); } AcsAttribute atr = new AcsAttribute(atrName,simple,atrUse); return(atr); } /** Read a DOM annotation node with documentation, and return the string documentation. * @param anno the DOM node * @return The String with the documentation */ public String readDocumentation(Node anno){ String documentation=""; NodeList lvl=anno.getChildNodes(); for (int k=0;k<lvl.getLength();k++){ Node two=lvl.item(k); String twoName=two.getLocalName(); if (twoName == null) continue; if (twoName.compareTo("documentation")==0){ documentation=two.getFirstChild().getNodeValue(); } } return(documentation); } /** Search for ComplexTypes in the parsed document and add them to the Arraylist. * This class is unstable, and untested. I asure that works with the commontypes file only. * @param doc The DOM document to search * @param namespace The namespace that those types should have **/ public void searchComplexTypes(Document doc,String namespace){ if (typeList==null) typeList=new ArrayList<AcsType>(); //Complex Types NodeList cTypes=doc.getElementsByTagName("xs:complexType"); for (int i=0;i<cTypes.getLength();i++){ Node item=cTypes.item(i); String name=item.getAttributes().getNamedItem("name").getNodeValue(); NodeList lvl1=item.getChildNodes(); String documentation=""; // Get the documentation for (int j=0;j<lvl1.getLength();j++){ Node one=lvl1.item(j); String oneName=one.getLocalName(); if (oneName != null && oneName.compareTo("annotation")==0) documentation=readDocumentation(one); } AcsComplexType aType=new AcsComplexType(namespace,name,documentation); for (int j=0;j<lvl1.getLength();j++){ Node one=lvl1.item(j); String oneName=one.getLocalName(); if (oneName != null && oneName.compareTo("attribute")==0){ aType.addAttr(readAttribute(one)); } } typeList.add(aType); } } /** Get a type (simple or complex) by name. * @param name the name of the type * @return the type, or null if not found.*/ public AcsType getType(String name){ for (AcsType type : typeList){ if (type.name.compareTo(name)==0) return type; } return null; } }