📄 schemaloader.java
字号:
//==============================================================================//===//=== SchemaLoader//===//==============================================================================//=== Copyright (C) 2001-2007 Food and Agriculture Organization of the//=== United Nations (FAO-UN), United Nations World Food Programme (WFP)//=== and United Nations Environment Programme (UNEP)//===//=== This program is free software; you can redistribute it and/or modify//=== it under the terms of the GNU General Public License as published by//=== the Free Software Foundation; either version 2 of the License, or (at//=== your option) any later version.//===//=== This program is distributed in the hope that it will be useful, but//=== WITHOUT ANY WARRANTY; without even the implied warranty of//=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU//=== General Public License for more details.//===//=== You should have received a copy of the GNU General Public License//=== along with this program; if not, write to the Free Software//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA//===//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,//=== Rome - Italy. email: geonetwork@osgeo.org//==============================================================================package org.fao.geonet.kernel.schema;import java.util.*;import org.jdom.*;import java.io.File;import jeeves.utils.Xml;//==============================================================================public class SchemaLoader{ private Element elRoot; private HashMap hmElements = new HashMap(); private HashMap hmTypes = new HashMap(); private HashMap hmAttrGrp = new HashMap(); private HashMap hmAbsElems = new HashMap(); private HashMap hmSubsGrp = new HashMap(); private HashMap hmSubsLink = new HashMap(); private HashMap hmSubsNames = new HashMap(); private HashMap hmAttribs = new HashMap(); private HashMap hmGroups = new HashMap(); private String targetNS; private String targetNSPrefix; /** Restrictions for simple types (element restriction) */ private HashMap hmElemRestr = new HashMap(); /** Restrictions for simple types (type restriction) */ private HashMap hmTypeRestr = new HashMap(); //--------------------------------------------------------------------------- //--- //--- Constructor //--- //--------------------------------------------------------------------------- public SchemaLoader() {} //--------------------------------------------------------------------------- //--- //--- API methods //--- //--------------------------------------------------------------------------- public MetadataSchema load(String xmlSchemaFile) throws Exception { if (xmlSchemaFile.startsWith("_")) return new MetadataSchema(new Element("root")); //--- PHASE 1 : pre-processing //--- //--- the xml file is parsed and simplified. Xml schema subtrees are //--- wrapped in some classes ArrayList alElementFiles = loadFile(xmlSchemaFile, new HashSet()); parseElements(alElementFiles); //--- PHASE 2 : resolve abstract elements for(Iterator i=hmSubsGrp.keySet().iterator(); i.hasNext();) { String elem = (String) i.next(); ArrayList elements = (ArrayList) hmSubsGrp.get(elem); ArrayList subsNames = new ArrayList(); hmSubsNames.put(elem,subsNames); for(int j=0; j<elements.size(); j++) { ElementEntry ee = (ElementEntry) elements.get(j); if (ee.type == null) { ee.type = (String) hmAbsElems.get(elem); if (ee.type == null) throw new IllegalArgumentException("Type is null for 'element' : " + ee.name); } hmElements.put(ee.name, ee.type); subsNames.add(ee.name); } } //--- PHASE 3 : add elements MetadataSchema mds = new MetadataSchema(elRoot); for(Iterator i=hmElements.keySet().iterator(); i.hasNext();) { String elem = (String) i.next(); String type = (String) hmElements.get(elem); ArrayList elemRestr = (ArrayList) hmElemRestr.get(elem); ArrayList typeRestr = (ArrayList) hmTypeRestr.get(type); if (elemRestr == null) elemRestr = new ArrayList(); if (typeRestr != null) elemRestr.addAll(typeRestr); ArrayList elemSubs = (ArrayList) hmSubsNames.get(elem); if (elemSubs == null) elemSubs = new ArrayList(); ArrayList elemSubsLink = (ArrayList) hmSubsLink.get(elem); if (elemSubsLink == null) elemSubsLink = new ArrayList(); mds.addElement(elem, type, elemRestr, elemSubs, elemSubsLink); } //--- PHASE 4 : post-processing //--- //--- resolve abstract types, attribute/substitution groups and other stuff for(Iterator i=hmTypes.values().iterator(); i.hasNext();) { ComplexTypeEntry cte = (ComplexTypeEntry) i.next(); MetadataType mdt = new MetadataType(); mdt.setOrType(cte.isOrType); //--- generate attribs for(int j=0; j<cte.alAttribs.size(); j++) // RGFIX { AttributeEntry ae = (AttributeEntry) cte.alAttribs.get(j); mdt.addAttribute(buildMetadataAttrib(ae)); } if (cte.attribGroup != null) { ArrayList al = (ArrayList) hmAttrGrp.get(cte.attribGroup); if (al == null) throw new IllegalArgumentException("Attribute group not found : " + cte.attribGroup); for(int j=0; j<al.size(); j++) { AttributeEntry ae = (AttributeEntry) al.get(j); mdt.addAttribute(buildMetadataAttrib(ae)); } } //--- resolve inheritance & add attribs from complexContent if (cte.complexContent != null) { if (cte.complexContent.base != null) { cte.alElements = resolveInheritance(cte); ArrayList complexContentAttribs = resolveAttributeInheritance(cte); //--- add attribs from complexContent (if any) for(int j=0; j<complexContentAttribs.size(); j++) { AttributeEntry ae = (AttributeEntry) complexContentAttribs.get(j); mdt.addAttribute(buildMetadataAttrib(ae)); } } } //--- resolve inheritance & add attribs from simpleContent // RGFIX if (cte.simpleContent != null) { //--- add attribs from simpleContent (if any) for(int j=0; j<cte.simpleContent.alAttribs.size(); j++) { AttributeEntry ae = (AttributeEntry) cte.simpleContent.alAttribs.get(j); mdt.addAttribute(buildMetadataAttrib(ae)); } } if (cte.groupRef != null) { GroupEntry ge = (GroupEntry) hmGroups.get(cte.groupRef); if (ge == null) throw new IllegalArgumentException("Group ref not found for complex type :" +cte.groupRef); if (ge.isChoice) { ElementEntry ee = (ElementEntry) ge.alElements.get(0); String eeRefType = (String) hmElements.get(ee.ref); //--- if the ref type was not found and the element was in //--- the abstract elements hm then we have an abstract element if (eeRefType == null || hmAbsElems.containsKey(ee.ref)) { ArrayList al = (ArrayList) hmSubsGrp.get(ee.ref); if (al == null) throw new IllegalArgumentException("Abstract elem not found in substGroup : " +ee.ref); for(int k=0; k<al.size(); k++) { ElementEntry eeDer = (ElementEntry) al.get(k); mdt.addElementWithType(eeDer.name, cte.name, ee.min, ee.max); } } else throw new IllegalArgumentException("Found an element which is not abstract in choice type : " +ee.ref); } } //--- handle type's elements else for(int j=0; j<cte.alElements.size(); j++) { ElementEntry ee = (ElementEntry) cte.alElements.get(j); String type; boolean abstrElement = false;// Three situations:// 1. element is a reference to a global element so check if abstract if (ee.ref != null) { type = (String) hmElements.get(ee.ref); if (hmAbsElems.containsKey(ee.ref)) abstrElement = true; }// 2. element is a local element so get type else if (ee.name != null) { type = ee.type == null ? "string" : ee.type; mds.addElement(ee.name, type, new ArrayList(), new ArrayList(), new ArrayList());// 3. element is a choice element or an error } else { if (!ee.choiceElem) throw new IllegalArgumentException("Reference and name are null for element at position "+j+" in complexType "+cte.name); // Create a base name derived from cte.name and element position // because choice elements are anonymous - add CHOICEELEMENT and // an identifier to make it unique Integer baseChoiceNr = j; String baseChoiceName = cte.name+"CHOICE_ELEMENT"; type = ee.name = baseChoiceName+baseChoiceNr; // Traverse the list of elements in the choice element and // create an mdt with the chosen name and process any nested choices createTypeAndResolveNestedChoices(mds,ee.alChoiceElems, baseChoiceName,baseChoiceNr); mds.addElement(ee.name, type, new ArrayList(), new ArrayList(), new ArrayList()); } //--- if type is null or the element is a ref to an //--- abstract element then we have an abstract type to //--- process if (type == null || abstrElement) { ArrayList al = (ArrayList) hmSubsGrp.get(ee.ref); if (al == null) { al = (ArrayList) hmSubsLink.get(ee.ref); if (al != null) { Logger.log("WARNING: Adding abstract element "+ee.ref+" with substitution group "+al); mdt.addRefElementWithNoType(ee.ref, ee.min, ee.max); } } else { if (cte.alElements.size() == 1) { // This type has only one abstract element so make this type the choice type Integer elementsAdded = recursivelyDealWithAbstractElements(mdt,al); mdt.setOrType(elementsAdded > 1); } else { // This type has real elements and/or attributes so make a new choice type for this element only type = ee.ref+"CHOICE"+j; MetadataType mdtc = new MetadataType(); Integer elementsAdded = recursivelyDealWithAbstractElements(mdtc,al); mdtc.setOrType(elementsAdded > 1); mds.addType(type,mdtc); mds.addElement(ee.ref,type,new ArrayList(),new ArrayList(), new ArrayList()); mdt.addElementWithType(ee.ref,type,ee.min,ee.max); } } } else { if (ee.ref != null) mdt.addRefElementWithType(ee.ref,type,ee.min,ee.max); else mdt.addElementWithType(ee.name, type, ee.min, ee.max); } } mds.addType(cte.name, mdt); } return mds; } //--------------------------------------------------------------------------- //--- //--- Descend recursively to deal with nested choices (arggh) //--- //--------------------------------------------------------------------------- private void createTypeAndResolveNestedChoices(MetadataSchema mds, ArrayList al,String baseName,Integer baseNr) { if (al == null) return; MetadataType mdt = new MetadataType(); mdt.setOrType(true); for(int k=0; k<al.size(); k++) { ArrayList alElems = (ArrayList) al.get(k); for (int j=0;j<alElems.size();j++) { ElementEntry ee = (ElementEntry) alElems.get(j); if (ee.choiceElem) { Integer newBaseNr = baseNr+1; createTypeAndResolveNestedChoices(mds,ee.alChoiceElems,baseName,newBaseNr); ee.name = ee.type = baseName+newBaseNr; mds.addElement(ee.name,ee.type,new ArrayList(),new ArrayList(), new ArrayList()); mdt.addElementWithType(ee.name, ee.type, ee.min, ee.max); } else { if (ee.name != null) { mds.addElement(ee.name,ee.type,new ArrayList(),new ArrayList(), new ArrayList()); mdt.addElementWithType(ee.name, ee.type, ee.min, ee.max); } else { mdt.addRefElementWithNoType(ee.ref, ee.min, ee.max); } } } } mds.addType(baseName+baseNr,mdt); return; } //--------------------------------------------------------------------------- //--- //--- Descend recursively to deal with abstract elements //--- //--------------------------------------------------------------------------- private int recursivelyDealWithAbstractElements(MetadataType mdt,ArrayList al) { int number = 0; if (al == null) return number; for(int k=0; k<al.size(); k++) { ElementEntry ee = (ElementEntry) al.get(k); if (ee.abstrElem) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -