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

com.sta.cts.Parser Maven / Gradle / Ivy


package com.sta.cts;

import java.util.Vector;

import java.io.IOException;

import com.wutka.dtd.DTD;
import com.wutka.dtd.DTDAny;
import com.wutka.dtd.DTDItem;
import com.wutka.dtd.DTDName;
import com.wutka.dtd.DTDEmpty;
import com.wutka.dtd.DTDMixed;
import com.wutka.dtd.DTDChoice;
import com.wutka.dtd.DTDPCData;
import com.wutka.dtd.DTDElement;
import com.wutka.dtd.DTDCardinal;
import com.wutka.dtd.DTDSequence;

import com.sta.mlogger.MLogger;

/**
 * 

Name: Parser

*

Description: * Die Klasse Parser ist die zentrale Klasse im Demo-Converter. *

*

Copyright: Copyright (c) 2001-2004, 2014, 2016-2019, 2021

*

Company: >StA-Soft<

* @author StA * @version 1.0 */ public class Parser { /** * Der zu verwendende Scanner. */ private Scanner scanner; /** * Die aus dem DTD-File gelesene DTD-Struktur. */ private DTD dtd; /** * Der aktuelle XML-Generator. */ private XMLGenerator xg; /** * True, falls XDebug-Modus => mehr Infos. */ private boolean myXDebug; /** * Zur Instantiierung eines Parsers. */ public Parser() { } /** * Ausgabe von strg, falls myXDebug = true. * @param strg der Text, der ausgegeben werden soll. */ void print(String strg) { if (myXDebug) { MLogger.deb(strg); } } /** * Ausgabe von b, falls myXDebug = true. * @param b der Boolean-Wert, der ausgegeben werden soll. */ void print(boolean b) { if (myXDebug) { MLogger.deb("" + b); } } /** * Ausgabe von strg und CRLF, falls myXDebug = true. * @param strg der Text, der ausgegeben werden soll. */ void println(String strg) { if (myXDebug) { MLogger.deb(strg); } } /** * Ausgabe von CRLF, falls myXDebug = true. */ void println() { if (myXDebug) { MLogger.deb(""); } } /** * Basis-Parser-Routine f?r Elements/SubElements und Hierarchien. * Diese Basis-Parser-Routine soll alle Elements/SubElements in einer "Zeile" * einer EDIFACT-Nachricht (bzw. einer andere Datei, z. B. CSV) (Fall v != null) * bzw. ?bergeordnete Hierarchie-Ebenen (Fall v == null) parsen. * * Hier werden nur Tags erzeugt und keine Token gelesen. Die Tags f?r das * zu verarbeitende Item selbst werden au?erhalb, also in der ?bergeordneten * Routine/Rekursionsebene erzeugt. * * Rekursivit?t ist m?glich, es wird jedoch (im Fall v != null) nur eine * Rekursionsstufe ben?tigt. Aufgerufen werden entweder nur parseItems * (Fall v != null) oder parseStructure und parseItems (Fall v == null). * * Die H?ufigkeiten werden in parseItems schon beachtet (1?+*). * * Das Ergebnis ist "true", falls alles (!) Ok war (auch die H?ufigkeiten). * * Das Ergebnis ist "false", falls die Token nicht oder nicht richtig passen, * die H?ufigkeiten nicht stimmen oder ein genereller Fehler aufgetreten ist. * Die Idee: * je nach Typ(i): * DTDAny: * DTDEmpty: * DTDName: * Suche in Hash-Table * gefunden: * 1, +: parseElement, mu? true liefern * ?: parseElement, Ergebnis egal * +, *: parseElement, bis Ergebnis false * nicht gefunden: * DTDChoice: * DTDSequence: * F?r alle: parseItem * DTDMixed: * DTDPCDATA: * @param item ein DTDItem aus der DTD-Struktur * @param v ein Token (Vector) oder null, falls ?bergeordnete Struktur * @return true, falls Ok; false, falls Parse-Error * @exception IOException falls Schreibfehler im XML-Generator */ boolean parseItem(DTDItem item, Object v) throws IOException { String msg; boolean b = false; if (v == null) { msg = " Element: "; } else { msg = " Item: "; } if (item == null) { return false; } if (item instanceof DTDAny) { // Hier ist egal, was in v an Pos. i steht, es ist immer Ok. print(msg + "Any"); // wird zur Zeit nicht unterst?tzt b = false; } else if (item instanceof DTDEmpty) { // Hier darf nichts im Vector stehen. print(msg + "Empty"); // wird zur Zeit nicht unterst?tzt b = false; } else if (item instanceof DTDName) { // Hier mu? in der Hash-Tabelle gesucht werden. String name = ((DTDName) item).value; print(name); DTDElement e = (DTDElement) dtd.elements.get(name); if (e != null) { if (v != null) { if (v instanceof Vector) { if (((Vector) v).size() > 0) { Object v1 = ((Vector) v).elementAt(0); if (v1 != null) { xg.openTag(name); b = parseItems(e.content, v1); xg.closeTag(name); if (b) { if (v1 instanceof Vector) { b = (((Vector) v1).size() == 0); } /* else { // b = (((String) v1) == ""); } */ if (b) { ((Vector) v).remove(0); } } } } } else { xg.openTag(name); b = parseItems(e.content, v); /* if (b) { // b = (((String) v) == ""); } */ xg.closeTag(name); } } else { // Pr?fe, ob wenigstens noch ein Token kommt, sonst braucht man // wahrscheinlich auch das Tag nicht zu ?ffnen... Object o = scanner.getToken(); scanner.ungetToken(o); if (o != null) { xg.openTag(name); b = parseStructure(e); xg.closeTag(name); } } } /* >>> alt >>> xg.openTag(name); if (v == null) { b = parseStructure(e); } else { b = parseItems(e.content, v); } xg.closeTag(name); <<< alt <<< */ print(b); print(" "); } else if (item instanceof DTDChoice) { print("("); DTDItem[] items = ((DTDChoice) item).getItems(); b = false; for (int i = 0; i < items.length; i++) { if (i > 0) { print("|"); } if (!b) { b = parseItems(items[i], v); } } print(")"); } else if (item instanceof DTDSequence) { print("("); DTDItem[] items = ((DTDSequence) item).getItems(); b = true; for (int i = 0; i < items.length; i++) { if (i > 0) { print(","); } boolean b1 = parseItems(items[i], v); b = b & b1; } print(")"); } else if (item instanceof DTDMixed) { print("("); DTDItem[] items = ((DTDMixed) item).getItems(); b = true; for (int i = 0; i < items.length; i++) { if (i > 0) { print(","); } boolean b1 = parseItems(items[i], v); b = b & b1; } print(")"); } else if (item instanceof DTDPCData) { // Hier mu? das Element im Vector ein String sein // (bzw. ein Vector mit einem (einzigen) String b = false; print("#PCDATA"); if (v != null) { print("."); if (v instanceof Vector) { print("*"); if (((Vector) v).size() >= 1) { print(">=1"); Object s = ((Vector) v).elementAt(0); if (s != null) { if (s instanceof String) { print(" [ " + s + " ] "); xg.putContent((String) s); b = true; } else { print(" no string "); } } else { print(" null "); } ((Vector) v).remove(0); } else { print(" no elements "); } } else if (v instanceof String) { print(" [ " + v + " ] "); xg.putContent((String) v); // v = ""; b = true; } else { print(" type error. "); } } else { print(" null "); } // print(" [ " + item. + " ] "); } return b; } /** * Parser-Routine f?r H?ufigkeiten/Kardinalit?ten. * Diese Parser-Routine realisiert die Problematik "H?ufigkeiten" (1?+*). * * Angewendet werden kann sie sowohl f?r Hierarchie-Ebenen (Fall v == null) als auch Element-Ebene(n) (fall v != null). * * Aufgerufen wird parseItem mit item und v. * @param item ein DTDItem aus der DTD-Struktur * @param v ein Token (Vector) oder null, falls ?bergeordnete Struktur * @return true, falls Ok; false, falls Parse-Error * @exception IOException falls Schreibfehler im XML-Generator */ boolean parseItems(DTDItem item, Object v) throws IOException { String msg; boolean b; if (v == null) { msg = "Elements: "; } else { msg = "Items: "; } b = false; if (item.cardinal == DTDCardinal.NONE) { b = parseItem(item, v); print(msg + "1"); } else if (item.cardinal == DTDCardinal.OPTIONAL) { parseItem(item, v); print(msg + "?"); b = true; } else if (item.cardinal == DTDCardinal.ONEMANY) { b = parseItem(item, v); if (b) { while (b) { b = parseItem(item, v); } b = true; } print(msg + "+"); } else if (item.cardinal == DTDCardinal.ZEROMANY) { while (parseItem(item, v)) { b = true; } print(msg + "*"); b = true; } return b; } /** * Diese Routine Parser-Routine pr?ft, ob das n?chste Token mit dem Namen des * ?bergebenen Elements beginnt. * * Falls ja, wird der Name aus dem Token entfernt und parseItems mit dem * Inhalt des DTD-Elements und dem Rest-Token aufgerufen. Es soll also das * Rest-Token verarbeitet werden. * * Falls nein, wird das Token zur?ckgelegt und parseItems mit dem Inhalt des * DTD-Elements und "null" als Rest-Token aufgerufen. Es soll also eine * weitere generelle Hierarchiestufe verarbeitet werden. * * Die begrenzenden Tags werden erzeugt. * @param e ein DTD-Element aus der DTD-Struktur * @return true, falls Ok; false, falls Parse-Error * @exception IOException falls Schreibfehler im XML-Generator */ boolean parseStructure(DTDElement e) throws IOException { Object o; Object o1; boolean run; boolean b; if (e == null) { return false; } o = scanner.getToken(); // if (o == null) // { // return false; // } // Falls o ein Vector ist und // mindestens 1 Element enth?lt und // dieses nicht null sondern ein String und // noch dazu = dem Namen des Elements ist, run = false; if (o instanceof Vector) { if (((Vector) o).size() > 0) { o1 = ((Vector) o).elementAt(0); if (o1 != null) { if (o1 instanceof String) { if (o1.equals(e.name)) { run = true; } } } } } // dann entferne das erste Element des Vectors und // rufe parseItems mit diesem Rest-Vector auf, // sonst lege den Vector zur?ck und // rufe parseItems mit null auf. // print(" [ <" + e.name + "> ] "); if (run) { ((Vector) o).remove(0); b = parseItems(e.content, o); } else { scanner.ungetToken(o); b = parseItems(e.content, null); } // print(" [ ] "); return b; } /** * Diese "oberste" Parser-Routine l?st einen Namen via Hash-Tabelle auf und * ruft damit parseStructure auf. * neu: * zus?tzliche Parameter: * * Pfad/Name der Zieldatei(en) [PathName] * * Typ der Zieldatei(en) [FileType] * Der (die) komplette(n) Dateiname(n) der Zieldatei(en) ergibt (ergeben) sich * dann aus PathName + i + FileType, wobei i eine laufende Nummer ist (0..). * Bei i = 0 kann i weggelassen werden. * Notwendig ist dies, falls aus einer Quell-(EDIFACT-)Datei mehrere * XML-Dateien erzeugt werden m?ssen. * @param pDTD eine DTD-Struktur, die in der Regel aus einem DTD-File * gelesen wurde. * @param pRootName der Name des Root-Tags * @param pScanner der zu verwendende Scanner * @param pDstFilePath der Pfad (incl. Basis-Dateiname excl. Typ) der * Ziel-Datei. * @param pDstFileType der Typ (Extension) der Ziel-Datei(en) * @return Anzahl der erzeugten (und g?ltigen) Zieldateien oder 0, falls * ein Fehler aufgetreten ist und/oder keine Datei erzeugt wurde. * @exception IOException falls Lesefehler im Scanner (Quelldatei) oder * Schreibfehler im XML-Generator (Zieldatei) */ public int convert(DTD pDTD, String pRootName, Scanner pScanner, String pDstFilePath, String pDstFileType) throws IOException { DTDElement e; boolean b; String aTmpName; int i; Object o; dtd = pDTD; scanner = pScanner; MLogger.deb("Parser: convert..."); // long time = System.currentTimeMillis(); e = (DTDElement) dtd.elements.get(pRootName); if (e == null) { MLogger.err("Parser: convert: Error: Can't get root element."); return 0; } xg = new XMLGenerator(); i = 0; do { if (i == 0) { aTmpName = ""; } else { aTmpName = Integer.toString(i); } // XML-Generator initialisieren und damit XML-File erstellen xg.createXML(pDstFilePath + aTmpName + "." + pDstFileType); // Root-Tag ?ffnen xg.openTag(pRootName); // Struktur parsen b = parseStructure(e); println(); // Root-Tag schlie?en xg.closeTag(pRootName); // XML-File schlie?en xg.closeXML(); if (b) { i++; } o = scanner.getToken(); scanner.ungetToken(o); } while ((o != null) & (b)); // time = System.currentTimeMillis() - time; if (b) { MLogger.deb("Parser: convert: Ok."); } else { MLogger.err("Parser: convert: Error."); } return i; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy