/*
* Copyright 2005-2015 by BerryWorks Software, LLC. All rights reserved.
*
* This file is part of EDIReader. You may obtain a license for its use directly from
* BerryWorks Software, and you may also choose to use this software under the terms of the
* GPL version 3. Other products in the EDIReader software suite are available only by licensing
* with BerryWorks. Only those files bearing the GPL statement below are available under the GPL.
*
* EDIReader 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 3 of
* the License, or (at your option) any later version.
*
* EDIReader 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 EDIReader. If not,
* see <http://www.gnu.org/licenses/>.
*/
package com.berryworks.edireader;
import com.berryworks.edireader.error.ErrorMessages;
import com.berryworks.edireader.plugin.PluginControllerFactoryInterface;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import java.io.IOException;
/**
* Reads and parses an EDI interchange in any of the supported EDI standards.
* Once a specific EDI standard is identified, EDIReader delegates the actual
* parsing to a subclass of EDIReader that it creates. This delegation technique
* allows an application to use EDIReader just as it would an XMLReader and
* without having to configure or otherwise signal for a particular standard to
* be used. Another advantage of this approach is that it provides a framework
* for additional EDIReader subclasses to be developed and integrated with
* little impact.
*/
public class EDIReader extends EDIAbstractReader implements ErrorMessages {
/**
* If debug is set to true, then a parser may emit diagnostic information to
* System.err
*/
public static boolean debug;
private EDIReader theReader;
private XMLTags xmlTags;
private PluginControllerFactoryInterface pluginControllerFactory;
public EDIReader() {
if (Boolean.getBoolean("edireader.debug"))
setDebug(true);
}
/**
* Read enough of the EDI interchange to establish which characters are used
* for segment terminators, element delimiters, etc. Each subclass of
* EDIReader overrides this method with logic specific to a particular EDI
* standard. Upon return, the input stream has been re-positioned so that
* the interchange will be parsed from the beginning by <code>parse()</code>.
*/
@Override
public void preview() throws EDISyntaxException, IOException {
throw new EDISyntaxException("EDIReader.preview() called unexpectedly");
}
/**
* Parse an EDI interchange from the input source.
*/
public void parse(InputSource source) throws SAXException, IOException {
startXMLDocument();
char[] leftOver = null;
while (true) {
if (theReader == null) {
theReader = EDIReaderFactory.createEDIReader(source, leftOver);
if (theReader == null) {
if (debug)
trace("EDIReader.parse(InputSource) hit end of input");
break;
}
if (debug)
trace("EDIReader.parse(InputSource) created an EDIReader of type "
+ theReader.getClass().getName());
theReader.setExternalXmlDocumentStart(true);
theReader.setAcknowledgment(getAckStream());
theReader.setAlternateAcknowledgment(getAlternateAckStream());
theReader.setContentHandler(getContentHandler());
theReader.setSyntaxExceptionHandler(getSyntaxExceptionHandler());
theReader.setNamespaceEnabled(isNamespaceEnabled());
}
theReader.setXMLTags(xmlTags);
if (pluginControllerFactory != null) {
theReader.setPluginControllerFactory(pluginControllerFactory);
}
theReader.parse(source);
setDelimiter(theReader.getDelimiter());
setSubDelimiter(theReader.getSubDelimiter());
setTerminator(theReader.getTerminator());
setTerminatorSuffix(theReader.getTerminatorSuffix());
leftOver = theReader.getTokenizer().getBuffered();
theReader = null;
}
endXMLDocument();
}
public void setXMLTags(XMLTags tags) {
xmlTags = tags;
}
public XMLTags getXMLTags() {
if (xmlTags == null)
xmlTags = DefaultXMLTags.getInstance();
return xmlTags;
}
public void setPluginControllerFactory(PluginControllerFactoryInterface pluginControllerFactory) {
this.pluginControllerFactory = pluginControllerFactory;
}
/**
* Sets debug on or off.
*
* @param d true to turn debug on, false to turn it off
*/
public static void setDebug(boolean d) {
if (debug && d) {
trace("Debug already on");
} else if (!debug && d) {
trace("Debug turned on");
} else if (debug && !d) {
trace("Debug turned off");
}
debug = d;
}
protected void startXMLDocument() throws SAXException {
AttributesImpl attrList = new AttributesImpl();
attrList.clear();
final ContentHandler contentHandler = getContentHandler();
if (contentHandler == null) {
throw new SAXException("No ContentHandler configured for EDIReader");
}
contentHandler.startDocument();
String rootTag = getXMLTags().getRootTag();
if (isNamespaceEnabled()) {
contentHandler.startElement(BERRYWORKS_NAMESPACE, rootTag, rootTag, attrList);
} else {
startElement(rootTag, attrList);
}
}
protected void endXMLDocument() throws SAXException {
endElement(getXMLTags().getRootTag());
getContentHandler().endDocument();
}
protected void startElement(String tag, Attributes attributes)
throws SAXException {
getContentHandler().startElement("", tag, tag, attributes);
}
protected void endElement(String tag) throws SAXException {
getContentHandler().endElement("", tag, tag);
}
}