/* * 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.tokenizer.EDITokenizer; import com.berryworks.edireader.tokenizer.Tokenizer; import org.xml.sax.InputSource; import java.io.IOException; import java.io.Reader; /** * Creates a subclass of EDIReader appropriate for parsing a particular EDI * interchange. This class has just enough knowledge of the supported standards * make a decision based on observation of the first several characters of data. * This decision does not imply that data in well-formed with regard to the * chosen standard, but merely that we know which actual parser to use. */ public abstract class EDIReaderFactory { /** * Equivalent to createEDIReader(source, debugging=false) * * @param source EDI input * @return EDIReader * @throws IOException if problem reading EDI input * @throws EDISyntaxException if invalid EDI is detected */ public static EDIReader createEDIReader(InputSource source) throws EDISyntaxException, IOException { return createEDIReader(source, null, false); } /** * Factory method to create an instance of a subclass of EDIReader based on * examination of the first few characters of data. * * @param source EDI source * @param debug true to turn debug on, false to turn it off * @return created EDIReader instance * @throws IOException for problem reading EDI data * @throws EDISyntaxException if invalid EDI is detected */ public static EDIReader createEDIReader(InputSource source, boolean debug) throws EDISyntaxException, IOException { return createEDIReader(source, null, debug); } /** * Factory method to create an instance of a subclass of EDIReader based on * examination of the first few characters of data. The second argument * allows for an array of chars to be treated as data that appears before * the next char of input from source. This can be useful when the source * was used earlier and some buffered and unused chars were left over. * In other words, the second argument provides for a kind of "pushback" * feature for the data source. * * @param source EDI source * @param preRead chars of EDI input data to be used before reading from the source * @return created EDIReader instance * @throws IOException for problem reading EDI data * @throws EDISyntaxException if invalid EDI is detected */ public static EDIReader createEDIReader(InputSource source, char[] preRead) throws EDISyntaxException, IOException { return createEDIReader(source, preRead, false); } /** * Factory method to create an instance of a subclass of EDIReader based on * examination of the first few characters of data. * * @param source EDI source * @param preRead chars of EDI input data to be used before reading from the source * @param debug true to turn debug on, false to turn it off * @return created EDIReader instance * @throws IOException for problem reading EDI data * @throws EDISyntaxException if invalid EDI is detected */ public static EDIReader createEDIReader(InputSource source, char[] preRead, boolean debug) throws EDISyntaxException, IOException { Reader inputReader = EDIAbstractReader.createReader(source); Tokenizer tokenizer = (preRead == null || preRead.length == 0) ? new EDITokenizer(inputReader) : new EDITokenizer(inputReader, preRead); // Skip past any leading whitespace tokenizer.scanTerminatorSuffix(); if (tokenizer.isEndOfData()) return null; // Grab the first few characters char[] buf = tokenizer.lookahead(3); if (buf == null || buf.length < 3) throw new RuntimeException("tokenizer.lookahead() returned null"); // Get an appropriate parser, based on the first few characters String asString = new String(buf); EDIReader parser = ParserRegistry.get(asString); if (parser == null) throw new EDISyntaxException("<?xml ".startsWith(asString) ? ErrorMessages.XML_INSTEAD_OF_EDI : ErrorMessages.NO_STANDARD_BEGINS_WITH + asString); source.setCharacterStream(inputReader); parser.setTokenizer(tokenizer); parser.preview(); return parser; } }