/* * This file is part of Mosquito meta-loader. * * Mosquito meta-loader is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Mosquito meta-loader 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.github.geequery.codegen.pdm; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.EmptyStackException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Stack; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import com.github.geequery.codegen.pdm.model.MetaColumn; import com.github.geequery.codegen.pdm.model.MetaKey; import com.github.geequery.codegen.pdm.model.MetaModel; import com.github.geequery.codegen.pdm.model.MetaReference; import com.github.geequery.codegen.pdm.model.MetaTable; import jef.common.JefException; import jef.common.log.LogUtil; import jef.tools.IOUtils; import jef.tools.XMLUtils.XmlFixedReader; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class PDMetaLoader implements IMetaLoader { class ActualRefStack { private Stack<PDMReference> stk = new Stack<PDMReference>(); public PDMReference peek() throws EmptyStackException { return (PDMReference) stk.peek(); } public PDMReference pop() throws EmptyStackException { return (PDMReference) stk.pop(); } public PDMReference push(PDMReference aActualRef) { return (PDMReference) stk.push(aActualRef); } } class ActualXEStack { private Stack<XmlElem> stk = new Stack<XmlElem>(); public XmlElem peek() throws EmptyStackException { return (XmlElem) stk.peek(); } public XmlElem pop() throws EmptyStackException { return (XmlElem) stk.pop(); } public XmlElem push(XmlElem aXE) { return (XmlElem) stk.push(aXE); } public XmlElem underPeek() throws EmptyStackException { int len = stk.size(); if (len < 2) throw new EmptyStackException(); return (XmlElem) stk.elementAt(len - 2); } } /** * Stores xoe when when it is declared \ <nmsp:Elem Id="aKey"/> */ class HT_ID_XOE { private Hashtable<String, XmlElem> htId_XOE; public HT_ID_XOE(int ainitCap) { htId_XOE = new Hashtable<String, XmlElem>(ainitCap); } /** * @param aId * @return xoe */ public XmlElem get(String aId) { return (XmlElem) htId_XOE.get(aId); } /** * @param id * string (key) * @param xe * (value) * @return prev xe */ public XmlElem put(String aId, XmlElem aXOE) { return (XmlElem) htId_XOE.put(aId, aXOE); } } class PDMColumn extends PDMElement { protected String comment = ""; protected String datatype = ""; protected String defaultVal = ""; protected PDMColumn fkParent; protected String length = ""; protected String listOfVals = ""; protected boolean mandatory = false; protected String parentTable = ""; protected boolean partOfPK = false; protected String precision = ""; protected MetaColumn getCreateMetaColumn() throws SAXException { MetaColumn retVal = null; if ((retVal = getMetaColumnByPDMColId(id)) == null) { // IT DOESN'T EXIST. Creating ... int len = 0, prec = 0; try { len = Integer.parseInt(this.length); } catch (NumberFormatException nfe) { } try { prec = Integer.parseInt(this.precision); } catch (NumberFormatException nfe) { } String dataTypeName = new String(datatype); int index = dataTypeName.indexOf("("); if (index != -1) dataTypeName = dataTypeName.substring(0, index); // String matchDT = datatype. String jClassName = dataTypeName.trim(); // Fk MetaColumn parent is temporarly set to null // it will be resolved later MetaColumn fkMetaCol = null; retVal = new MetaColumn(this.code, this.name, this.parentTable, this.mandatory, fkMetaCol, jClassName, len, prec, comment); retVal.setDefaultVal(defaultVal); // list of values... if (!"".equals(listOfVals)) { String spEntries[] = listOfVals.split("\n"); for (int i = 0; i < spEntries.length; i++) { String spValueLabel[] = spEntries[i].trim().split("\t"); retVal.put(spValueLabel[0].trim(), spValueLabel[1].trim()); } } try { htCreatedMetaColumns_ID_MC.put(id, retVal); } catch (Exception e) { // if (id == null || retVal == null) throw new SAXException("Column already exists! id = " + id + e.getMessage()); } } return retVal; } } class PDMElement { protected String code = ""; protected String comment = ""; protected String id = ""; protected String name = ""; } class PDMKey extends PDMElement { ArrayList<String> alColumns = new ArrayList<String>(); public void addCol(String aColId) { alColumns.add(aColId); } public MetaKey createMetaKey(Hashtable<String, PDMElement> aIdResources) throws SAXException { MetaKey retVal = new MetaKey(name, code); Iterator<String> iKeyCols = alColumns.iterator(); while (iKeyCols.hasNext()) { String crntColId = iKeyCols.next(); try { PDMColumn col = (PDMColumn) aIdResources.get(crntColId); retVal.addColumn(col.getCreateMetaColumn()); } catch (Exception e) { LogUtil.error("Can't find MetaColumn to add " + "to MetaKey from id: " + crntColId + ". " + e.getMessage()); throw new SAXException("PDML: " + e.getMessage()); } } return retVal; } } class PDMModel extends PDMElement { ArrayList<String> alTableIds = new ArrayList<String>(); protected void addTable(String aPDMTableId) throws SAXException { alTableIds.add(aPDMTableId); } protected MetaModel createMetaModel(Hashtable<String, PDMElement> aIdResources) throws SAXException { MetaModel retVal = new MetaModel(code, name, comment); Iterator<String> iIdTables = alTableIds.iterator(); while (iIdTables.hasNext()) { String crntTableId = iIdTables.next(); try { PDMTable pdmTable = (PDMTable) aIdResources.get(crntTableId); retVal.addTable(pdmTable.createMetaTable(aIdResources)); } catch (Exception e) { LogUtil.exception(e); LogUtil.error("Can't create MetaTable from id: " + crntTableId + ". " + e.getMessage()); throw new SAXException("PDML: " + e.getMessage()); } } return retVal; } } class PDMReference extends PDMElement { private ArrayList<String> alRefJoins = new ArrayList<String>(); String parentTableId = ""; String sourceTableId = ""; String cardinality = ""; public void addRefJoin(String aRefJoin) { alRefJoins.add(aRefJoin); } public MetaReference createMetaReference(Hashtable<String, PDMElement> aIdResources) throws SAXException { MetaReference retVal = new MetaReference(name, code,cardinality); htCreatedRefs.put(id, retVal); /* * try{ retVal.setParentTable((MetaTable) * htCreatedMetaTables.get(parentTableId)); * retVal.setSourceTable((MetaTable) * htCreatedMetaTables.get(sourceTableId)); }catch(Exception e) { * logger.error("Can't find parent MetaTable to add " + "to * MetaReference id: " + parentTableId + ". " + e.getMessage()); * throw new SAXException("PDML: " + e.getMessage()); } Iterator * iJoins = alRefJoins.iterator(); while (iJoins.hasNext()) { String * currRefJoinId = (String) iJoins.next(); ReferenceJoin currRefJoin * = (ReferenceJoin) aIdResources.get(currRefJoinId); try { * MetaColumn col = getMetaColumnByPDMColId(currRefJoin.colId); * retVal.addColumn(col); } catch (Exception e) { * logger.error("Can't find MetaColumn to add " + "to MetaReference * from id: " + currRefJoin.colId + ". " + e.getMessage()); throw * new SAXException("PDML: " + e.getMessage()); } } */ return retVal; } } class PDMShortcut extends PDMElement { } class PDMTable extends PDMElement { private ArrayList<String> alColumns = new ArrayList<String>(); private ArrayList<String> alKeys = new ArrayList<String>(); private ArrayList<String> alRefs = new ArrayList<String>(); protected String comment = ""; protected void addCol(String aColId) throws SAXException { alColumns.add(aColId); } public void addKey(String aKeyId) { alKeys.add(aKeyId); } public void addRef(String aRefId) { alRefs.add(aRefId); } protected MetaTable createMetaTable(Hashtable<String, PDMElement> aIdResources) throws SAXException { MetaTable retVal = new MetaTable(code, name, comment); htCreatedTables.put(id, retVal); htCreatedTablesByCode.put(code, retVal); // create/add MetaKeys Iterator<String> iKeys = alKeys.iterator(); while (iKeys.hasNext()) { String crntPDMKeyId = (String) iKeys.next(); try { PDMKey crntPDMKey = (PDMKey) aIdResources.get(crntPDMKeyId); retVal.addKey(crntPDMKey.createMetaKey(aIdResources)); } catch (Exception e) { LogUtil.error("Can't create MetaKey from id: " + crntPDMKeyId + ". " + e.getMessage()); throw new SAXException("PDML: " + e.getMessage()); } } // create/add References Iterator<String> iRefs = alRefs.iterator(); while (iRefs.hasNext()) { String currRefId = (String) iRefs.next(); PDMReference currRef = (PDMReference) aIdResources.get(currRefId); try { retVal.addRef(currRef.createMetaReference(aIdResources)); } catch (Exception e) { LogUtil.error("Can't create MetaReference from id: " + currRefId + ". " + e.getMessage()); throw new SAXException("PDML: " + e.getMessage()); } } // create/add MetaColumns Iterator<String> iIdColumns = alColumns.iterator(); while (iIdColumns.hasNext()) { try { String crntColId = (String) iIdColumns.next(); PDMColumn pdmCol = (PDMColumn) aIdResources.get(crntColId); retVal.addCol(pdmCol.getCreateMetaColumn()); } catch (Exception e) { } } return retVal; } public Iterator<String> elements() { return alColumns.iterator(); } } class ReferenceJoin extends PDMElement { String colId = ""; String fkParentColId = ""; public void join(Hashtable<String, PDMElement> aIdResources) throws SAXException { try { PDMColumn pdmCol = (PDMColumn) aIdResources.get(colId); PDMColumn pdmFkCol = (PDMColumn) aIdResources.get(fkParentColId); pdmCol.fkParent = pdmFkCol; } catch (Exception e) { LogUtil.error("ReferenceJoin: Columns(" + colId + ", " + fkParentColId); //throw new SAXException("PDML: id=" + colId + e.getMessage()); } } } /** * PD's <o:Object Attr="o123"> Object := * {Model|Table|Column|RefernceJoin|Key} Attr := {Id|Ref} */ class XmlElem { public final static String A_CODE = "a:Code"; public final static String A_COMMENT = "a:Comment"; public final static String A_DATATYPE = "a:DataType"; public final static String A_DEFAULT = "a:DefaultValue"; public final static String A_DESCRIPTION = "a:Description"; public final static String A_LENGTH = "a:Length"; public final static String A_LISTOFVALS = "a:ListOfValues"; public final static String A_MANDATORY = "a:Mandatory"; public final static String A_CARDINALITY = "a:Cardinality"; public final static String A_NAME = "a:Name"; public final static String A_PRECISION = "a:Precision"; public final static String C_CHILD_TABLE = "c:ChildTable"; public final static String C_COLUMNS = "c:Columns"; public final static String C_KEY_COLUMNS = "c:Key.Columns"; public final static String C_KEYS = "c:Keys"; public final static String C_OBJECT_1 = "c:Object1"; public final static String C_OBJECT_2 = "c:Object2"; public final static String C_PARENT_TABLE = "c:ParentTable"; public final static String C_REFERENCES = "c:References"; public final static String C_TABLES = "c:Tables"; public final static String O_COLUMN = "o:Column"; public final static String O_KEY = "o:Key"; public final static String O_MODEL = "o:Model"; public final static String O_REFERECE_JOIN = "o:ReferenceJoin"; public final static String O_REFERENCE = "o:Reference"; public final static String O_SHORTCUT = "o:Shortcut"; public final static String O_TABLE = "o:Table"; protected String id = null; protected PDMElement pdmElement = null; protected String qName = null; public XmlElem(String aQName, String aId, PDMElement aPDMElement) { qName = aQName; id = aId; pdmElement = aPDMElement; } public boolean isACode() { return A_CODE.equals(qName); } public boolean isAComment() { return A_COMMENT.equals(qName); } public boolean isADataType() { return A_DATATYPE.equals(qName); } public boolean isADefaultVal() { return A_DEFAULT.equals(qName); } public boolean isADescription() { return A_DESCRIPTION.equals(qName); } public boolean isALength() { return A_LENGTH.equals(qName); } public boolean isAListOfVals() { return A_LISTOFVALS.equals(qName); } public boolean isAMandatory() { return A_MANDATORY.equals(qName); } public boolean isAName() { return A_NAME.equals(qName); } public boolean isAPrecision() { return A_PRECISION.equals(qName); } public boolean isCChildTable() { return C_CHILD_TABLE.equals(qName); } public boolean isCColumns() { return C_COLUMNS.equals(qName); } public boolean isCKeyColumns() { return C_KEY_COLUMNS.equals(qName); } public boolean isCKeys() { return C_KEYS.equals(qName); } public boolean isCObject1() { return C_OBJECT_1.equals(qName); } public boolean isCObject2() { return C_OBJECT_2.equals(qName); } public boolean isCReferences() { return C_REFERENCES.equals(qName); } public boolean isCTables() { return C_TABLES.equals(qName); } public boolean isOColumn() { return pdmElement instanceof PDMColumn; } public boolean isOKey() { return O_KEY.equals(qName); } public boolean isOModel() { return pdmElement instanceof PDMModel; } public boolean isOReference() { return O_REFERENCE.equals(qName); } public boolean isCParentTable() { return C_PARENT_TABLE.equals(qName); } public boolean isACardinality() { return A_CARDINALITY.equals(qName); } public boolean isOReferenceJoin() { return O_REFERECE_JOIN.equals(qName); } public boolean isOShortcut() { return O_SHORTCUT.equals(qName); } // public boolean isPackage() { // return objType == OT_PACKAGE; // } public boolean isOTable() { return pdmElement instanceof PDMTable; } } /** * Handles SAX2 events */ class XmlHandlerDelegate extends DefaultHandler { PDMColumn actualColumn = null; PDMKey actualKey = null; PDMReference actualRef = null; ReferenceJoin actualRJ = null; PDMShortcut actualShortcut = null; PDMTable actualTable = null; XmlElem actualXE = null; HT_ID_XOE htId_XE = new HT_ID_XOE(INIT_HT_CAP); XmlElem prevActualXE = null; ActualRefStack stkActualRef = new ActualRefStack(); ActualXEStack stkActualXE = new ActualXEStack(); /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { String sCh = (new String(ch, start, length)); XmlElem actualXE = null; XmlElem prevActualXE = null; try { actualXE = stkActualXE.peek(); prevActualXE = stkActualXE.underPeek(); } catch (EmptyStackException ese) { return; } try { actualRef = stkActualRef.peek(); } catch (EmptyStackException ese) { } if (prevActualXE == null || actualXE == null) return; // ok ... if (actualXE.isAName()) { // ________________________________________________________A_NAME if (prevActualXE.isOColumn()) { actualColumn.name += sCh; } else if (prevActualXE.isOKey()) { actualKey.name += sCh; } else if (prevActualXE.isOTable()) { actualTable.name += sCh; } else if (prevActualXE.isOModel()) { actualMModel.name += sCh; } else if (prevActualXE.isOReference()) { actualRef.name += sCh; } } else if (actualXE.isACode()) { // ________________________________________________________A_CODE if (prevActualXE.isOColumn()) { actualColumn.code += sCh; } else if (prevActualXE.isOKey()) { actualKey.code += sCh; } else if (prevActualXE.isOTable()) { actualTable.code += sCh; } else if (prevActualXE.isOModel()) { actualMModel.code += sCh; } else if (prevActualXE.isOReference()) { actualRef.code += sCh; } else if (prevActualXE.isOShortcut()) { actualShortcut.code += sCh; } } else if (actualXE.isADefaultVal()) { // _____________________________________________________A_DEFAULT if (prevActualXE.isOColumn()) { actualColumn.defaultVal += sCh; } } else if (actualXE.isADescription()) { // _________________________________________________A_DESCRIPTION if (prevActualXE.isOTable()) { actualTable.comment += sCh; } else if (prevActualXE.isOModel()) { actualMModel.comment += sCh; } } else if (actualXE.isAListOfVals()) { // __________________________________________________A_LISTOFVALS if (prevActualXE.isOColumn()) { actualColumn.listOfVals += sCh; } } else if (actualXE.isAMandatory()) { // ___________________________________________________A_MANDATORY if (prevActualXE.isOColumn()) { actualColumn.mandatory = ("1".equals(sCh)); } } else if (actualXE.isAComment()) { // _____________________________________________________A_COMMENT if (prevActualXE.isOColumn()) { actualColumn.comment += sCh; } else if (prevActualXE.isOTable()) { actualTable.comment += sCh; } else if (prevActualXE.isOModel()) { actualMModel.comment += sCh; } } else if (actualXE.isADataType()) { // ____________________________________________________A_DATATYPE if (prevActualXE.isOColumn()) { actualColumn.datatype += sCh; } } else if (actualXE.isALength()) { // ______________________________________________________A_LENGTH if (prevActualXE.isOColumn()) { actualColumn.length += sCh; } } else if (actualXE.isAPrecision()) { // ___________________________________________________A_PRECISION if (prevActualXE.isOColumn()) { actualColumn.precision += sCh; } } else if (actualXE.isACardinality()) { this.actualRef.cardinality+= sCh; } } /** * @see org.xml.sax.ContentHandler#endElement(java.lang.String, * java.lang.String, java.lang.String) */ public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equals(XmlElem.A_CODE)) { // In case of shortcut if (actualShortcut != null) { htShortcuts.put(actualShortcut.id, actualShortcut); } } else if (qName.equals(XmlElem.O_COLUMN)) { actualColumn = null; } else if (qName.equals(XmlElem.C_KEY_COLUMNS)) { } else if (qName.equals(XmlElem.O_REFERECE_JOIN)) { actualRJ = null; } else if (qName.equals(XmlElem.O_REFERENCE)) { try { stkActualRef.pop(); } catch (EmptyStackException e) { LogUtil.error("Invalid pdm file! Unbalanced Reference tags!"); throw new SAXException("Invalid pdm file! Unbalanced Reference tags!"); } } else if (qName.equals(XmlElem.O_SHORTCUT)) { actualShortcut = null; } else if (qName.equals(XmlElem.O_KEY)) { actualKey = null; } else if (qName.equals(XmlElem.C_COLUMNS)) { } else if (qName.equals(XmlElem.O_TABLE)) { actualTable = null; } else if (qName.equals(XmlElem.C_TABLES)) { } else if (qName.equals(XmlElem.O_MODEL)) { } try { stkActualXE.pop(); } catch (EmptyStackException ese) { // do nothing } } /** * @see org.xml.sax.ContentHandler#startDocument() */ public void startDocument() throws SAXException { } /** * @see org.xml.sax.ContentHandler#startElement(java.lang.String, * java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { try { prevActualXE = stkActualXE.peek(); } catch (EmptyStackException e) { prevActualXE = null; } actualXE = null; String id = attributes.getValue("Id"); String ref = attributes.getValue("Ref"); // CASE ELEMENT if (qName.equals(XmlElem.A_NAME)) { // ________________________________________________________A_NAME actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_CODE)) { // ________________________________________________________A_CODE actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_DEFAULT)) { // _____________________________________________________A_DEFAULT actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_DESCRIPTION)) { // _________________________________________________A_DESCRIPTION actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_LISTOFVALS)) { // __________________________________________________A_LISTOFVALS actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_MANDATORY)) { // ___________________________________________________A_MANDATORY actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_COMMENT)) { // _____________________________________________________A_COMMENT actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_DATATYPE)) { // ____________________________________________________A_DATATYPE actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_LENGTH)) { // ______________________________________________________A_LENGTH actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_CARDINALITY)) { // ______________________________________________________A_LENGTH actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.A_PRECISION)) { // ___________________________________________________A_PRECISION actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.O_COLUMN)) { // ______________________________________________________O_COLUMN String colIdToAdd = null; if (id != null) { PDMColumn newCol = new PDMColumn(); newCol.id = id; colIdToAdd = id; actualXE = new XmlElem(qName, id, newCol); htId_PDMObject.put(id, newCol); htId_XE.put(id, actualXE); actualColumn = newCol; } else if (ref != null) { colIdToAdd = ref; } if (colIdToAdd != null && prevActualXE != null) { XmlElem prevPrevActualXE = null; try { prevPrevActualXE = stkActualXE.underPeek(); } catch (EmptyStackException ese) { } // Ok, detecting context of <o:column> if (prevActualXE.isCColumns()) { try { actualTable.addCol(colIdToAdd); } catch (NullPointerException npe) { LogUtil.error(npe.getMessage()); throw new SAXException("PDML: Can't add column to " + "null table - actualTable == null"); } } else if (prevActualXE.isCKeyColumns()) { if (actualKey == null) { LogUtil.error("Can't initialize actualKey - it is null!"); throw new SAXException("PDML: Can't initialize actualKey - it is null!"); } actualKey.addCol(colIdToAdd); } else if (prevActualXE.isCObject1()) { if (actualRJ == null || prevPrevActualXE == null || !prevPrevActualXE.isOReferenceJoin()) { LogUtil.error("actualRJ is null or this is not " + "a context of ReferenceJoin/Object1/Columns"); throw new SAXException("PDML: actualRJ is null or this is not " + "a context of ReferenceJoin/Object1/Column"); } actualRJ.fkParentColId = colIdToAdd; } else if (prevActualXE.isCObject2()) { if (actualRJ == null || prevPrevActualXE == null || !prevPrevActualXE.isOReferenceJoin()) { LogUtil.error("actualRJ is null or this is not " + "a context of ReferenceJoin/Object2/Column"); throw new SAXException("PDML: actualRJ is null or this is not " + "a context of ReferenceJoin/Object2/Column"); } actualRJ.colId = colIdToAdd; } } } else if (qName.equals(XmlElem.C_OBJECT_1)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_CHILD_TABLE)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_PARENT_TABLE)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_OBJECT_1)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_OBJECT_2)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_KEY_COLUMNS)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_REFERENCES)) { actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.O_REFERENCE)) { String RefIdToAdd = null; if (id != null) { actualRef = new PDMReference(); actualRef.id = id; RefIdToAdd = id; htId_PDMObject.put(id, actualRef); } else if (ref != null) { RefIdToAdd = ref; actualRef = (PDMReference) htId_PDMObject.get(ref); } stkActualRef.push(actualRef); actualXE = new XmlElem(qName, id, actualRef); if (RefIdToAdd != null && prevActualXE != null && prevActualXE.isCReferences()) { try { alReferences.add(RefIdToAdd); } catch (Exception e) { // logger.error("alReference is null!"); throw new SAXException("PDML: alReference is null!"); } } } else if (qName.equals(XmlElem.O_REFERECE_JOIN)) { // _______________________________________________O_REFERECE_JOIN if (id != null) { // String refJoinIdToAdd = id; actualRJ = new ReferenceJoin(); actualXE = new XmlElem(qName, id, actualRJ); htId_PDMObject.put(id, actualRJ); alJoins.add(actualRJ); } else { // logger.error("ReferenceJoin without Id"); throw new SAXException("PDML: ReferenceJoin without Id"); } actualRef = null; try { actualRef = stkActualRef.peek(); } catch (EmptyStackException e) { } if (actualRef != null) { actualRef.addRefJoin(id); } else { // logger.error("ReferenceJoin without Reference"); throw new SAXException("PDML: ReferenceJoin without Reference"); } } else if (qName.equals(XmlElem.O_KEY)) { // _________________________________________________________O_KEY String keyIdToAdd = null; if (id != null) { actualKey = new PDMKey(); actualKey.id = id; htId_PDMObject.put(id, actualKey); keyIdToAdd = id; } else if (ref != null) { keyIdToAdd = ref; } actualXE = new XmlElem(qName, null, null); if (keyIdToAdd != null && prevActualXE != null && prevActualXE.isCKeys()) { if (actualTable == null) { // logger // .error("c:Keys section must be declared within the " // + "o:Table section. id = " + keyIdToAdd); throw new SAXException("c:Keys section must be declared within the " + "o:Table section. id = " + keyIdToAdd); } actualTable.addKey(keyIdToAdd); } } else if (qName.equals(XmlElem.C_KEYS)) { // ________________________________________________________C_KEYS actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.C_COLUMNS)) { // _____________________________________________________C_COLUMNS actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.O_TABLE) || qName.equals(XmlElem.O_SHORTCUT)) { // _______________________________________________________O_TABLE String tableIdToAdd = null; if (id != null) { tableIdToAdd = id; if (!qName.equals(XmlElem.O_SHORTCUT)) { PDMTable pdmTableToAdd = new PDMTable(); pdmTableToAdd.id = id; actualXE = new XmlElem(qName, id, pdmTableToAdd); htId_XE.put(id, actualXE); actualTable = pdmTableToAdd; htId_PDMObject.put(id, actualTable); } else { actualShortcut = new PDMShortcut(); actualShortcut.id = id; actualXE = new XmlElem(qName, id, actualShortcut); htId_XE.put(id, actualXE); } } else if (ref != null) { tableIdToAdd = ref; actualXE = htId_XE.get(ref); } if (tableIdToAdd != null && prevActualXE != null) { XmlElem prevPrevActualXE = null; try { prevPrevActualXE = stkActualXE.underPeek(); } catch (EmptyStackException ese) { } try { actualRef = stkActualRef.peek(); } catch (EmptyStackException ese) { } // Detecting context of <o:Table> if (prevActualXE.isCTables() && !qName.equals(XmlElem.O_SHORTCUT)) { try { actualMModel.addTable(tableIdToAdd); } catch (NullPointerException npe) { // logger.error(npe.getMessage()); throw new SAXException("PDML: Can't add table to " + "null MetaModel - actualMModel == null"); } } else if (prevActualXE.isCParentTable()) { if (actualRef == null || prevPrevActualXE == null || !prevPrevActualXE.isOReference()) { // logger.error("actualRef is null or this is not " // + "a context of Reference/Object1/Table"); throw new SAXException("PDML: actualRef is null or this is not " + "a context of Reference/Object1/Table"); } actualRef.parentTableId = tableIdToAdd; } else if (prevActualXE.isCChildTable()) { if (actualRef == null || prevPrevActualXE == null || !prevPrevActualXE.isOReference()) { // logger // .error("actualRef is null or this is not " // + "a context of Reference/Object2/Table. RefId=" // + tableIdToAdd); throw new SAXException("PDML: actualRef is null or this is not " + "a context of Reference/Object2/Table. RefId=" + tableIdToAdd); } actualRef.sourceTableId = tableIdToAdd; } } } else if (qName.equals(XmlElem.C_TABLES)) { // ______________________________________________________C_TABLES actualXE = new XmlElem(qName, null, null); } else if (qName.equals(XmlElem.O_MODEL)) { // _______________________________________________________O_MODEL if (id != null && actualMModel == null) { actualMModel = new PDMModel(); actualMModel.id = id; actualXE = new XmlElem(qName, id, actualMModel); htId_XE.put(id, actualXE); } } stkActualXE.push(actualXE); } } private final static int INIT_HT_CAP = 500; public static final String FILENAME = "file"; protected PDMModel actualMModel = null; private ArrayList<ReferenceJoin> alJoins = new ArrayList<ReferenceJoin>(); private ArrayList<String> alReferences = new ArrayList<String>(); protected Hashtable<String, MetaColumn> htCreatedMetaColumns_ID_MC = new Hashtable<String, MetaColumn>(); protected Hashtable<String, MetaReference> htCreatedRefs = new Hashtable<String, MetaReference>(); protected Hashtable<String, MetaTable> htCreatedTables = new Hashtable<String, MetaTable>(); protected Hashtable<String, MetaTable> htCreatedTablesByCode = new Hashtable<String, MetaTable>(); private final Hashtable<String, PDMElement> htId_PDMObject = new Hashtable<String, PDMElement>(5000); protected Hashtable<String, PDMShortcut> htShortcuts = new Hashtable<String, PDMShortcut>(); public PDMetaLoader() { super(); } public MetaColumn getMetaColumnByPDMColId(String aPDMColId) { MetaColumn retVal = null; try { retVal = (MetaColumn) htCreatedMetaColumns_ID_MC.get(aPDMColId); } catch (Exception e) { retVal = null; } return retVal; } /** * @param Configuration * properties of PDM. These are the mandatory properties: * <p> * <code><ul> * <li>file</li> * </ul></code> * </p> * . * * @see com.github.geequery.codegen.pdm.IMetaLoader#getMetaModel(java.util.Properties) */ public MetaModel getMetaModel(File file,String... options) throws JefException { MetaModel retVal = null; LogUtil.show("Retrieving model from the file: " + file); if (!file.canRead()) throw new JefException("File is locked or it doesn't exist"); try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); // logger.info("MODEL PARSING STARTED..."); InputSource is = new InputSource(new XmlFixedReader(IOUtils.getReader(file, "UTF-8"))); saxParser.parse(is, new XmlHandlerDelegate()); // resolve all PDMColumn fks this.resolveAllPDMColFks(); // resolve all PDMReferences resolveAllPDMReferences(); retVal = actualMModel.createMetaModel(htId_PDMObject); // resolve all MetaColumn fks this.resolveAllMetaColFks(); resolveAllMetaReferences(); htCreatedMetaColumns_ID_MC.clear(); htCreatedRefs.clear(); // logger.info("DONE."); } catch (FileNotFoundException fnfe) { throw new JefException(fnfe); } catch (IOException ioe) { throw new JefException(ioe); } catch (SAXException saxe) { throw new JefException(saxe); } catch (ParserConfigurationException pce) { throw new JefException(pce); } return retVal; } private void resolveAllMetaColFks() throws SAXException { Enumeration<String> eColIds = htCreatedMetaColumns_ID_MC.keys(); while (eColIds.hasMoreElements()) { String crntColId = eColIds.nextElement(); try { PDMColumn pdmCol = (PDMColumn) htId_PDMObject.get(crntColId); MetaColumn metaCol = pdmCol.getCreateMetaColumn(); MetaColumn fkMetaCol = pdmCol.fkParent.getCreateMetaColumn(); metaCol.setFkColParent(fkMetaCol); } catch (Exception e) { } } } private void resolveAllMetaReferences() throws SAXException { Enumeration<String> eRefs = htCreatedRefs.keys(); while (eRefs.hasMoreElements()) { String refId = (String) eRefs.nextElement(); try { PDMReference currRef = (PDMReference) htId_PDMObject.get(refId); MetaReference currMRef = (MetaReference) htCreatedRefs.get(refId); if (currMRef == null) { throw new SAXException("Reference not created!. RefId = " + refId); } MetaTable srcTable = (MetaTable) htCreatedTables.get(currRef.sourceTableId); if (srcTable == null) { String srcTableCode = ((PDMShortcut) htShortcuts.get(currRef.sourceTableId)).code; srcTable = (MetaTable) htCreatedTablesByCode.get(srcTableCode); } MetaTable parentTable = (MetaTable) htCreatedTables.get(currRef.parentTableId); if (parentTable == null) { String parentTableCode = ((PDMShortcut) htShortcuts.get(currRef.parentTableId)).code; parentTable = (MetaTable) htCreatedTablesByCode.get(parentTableCode); } if (srcTable == null || parentTable == null) { throw new SAXException("Invalid reference! Source or parent table is null. RefId = " + refId); } currMRef.setSourceTable(srcTable); currMRef.setParentTable(parentTable); parentTable.addExportRef(currMRef);//添加 Iterator<String> joins = currRef.alRefJoins.iterator(); while (joins.hasNext()) { String joinId = (String) joins.next(); ReferenceJoin join = (ReferenceJoin) htId_PDMObject.get(joinId); currMRef.addColumn(getMetaColumnByPDMColId(join.colId),getMetaColumnByPDMColId(join.fkParentColId)); } } catch (Exception e) { // logger.error(e.getMessage()); throw new SAXException(e.getMessage()); } } } private void resolveAllPDMColFks() throws SAXException { Iterator<ReferenceJoin> iRJoins = alJoins.iterator(); while (iRJoins.hasNext()) { ReferenceJoin rj = (ReferenceJoin) iRJoins.next(); rj.join(htId_PDMObject); } } private void resolveAllPDMReferences() throws SAXException { Iterator<String> itRefs = alReferences.iterator(); while (itRefs.hasNext()) { String currPDMRefId = (String) itRefs.next(); PDMReference currPDMRef = (PDMReference) htId_PDMObject.get(currPDMRefId); PDMTable srcTbl = (PDMTable) htId_PDMObject.get(currPDMRef.sourceTableId); if (srcTbl != null) { srcTbl.addRef(currPDMRef.id); } else { LogUtil.error("Invalid reference! Source table is null. RefId = " + currPDMRefId); itRefs.remove(); } } } }