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

org.milyn.edisax.unedifact.UNEdifactInterchangeParser Maven / Gradle / Ivy

The newest version!
/*
	Milyn - Copyright (C) 2006 - 2010

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License (version 2.1) as published by the Free Software
	Foundation.

	This library 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:
	http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.edisax.unedifact;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.xml.XMLConstants;

import org.milyn.assertion.AssertArgument;
import org.milyn.edisax.BufferedSegmentReader;
import org.milyn.edisax.EDIParser;
import org.milyn.edisax.interchange.ControlBlockHandler;
import org.milyn.edisax.interchange.ControlBlockHandlerFactory;
import org.milyn.edisax.interchange.InterchangeContext;
import org.milyn.edisax.model.internal.Delimiters;
import org.milyn.edisax.unedifact.handlers.r41.UNEdifact41ControlBlockHandlerFactory;
import org.milyn.edisax.registry.LazyMappingsRegistry;
import org.milyn.edisax.registry.MappingsRegistry;
import org.milyn.namespace.NamespaceDeclarationStack;
import org.milyn.namespace.NamespaceDeclarationStackAware;
import org.milyn.xml.hierarchy.HierarchyChangeListener;
import org.milyn.xml.hierarchy.HierarchyChangeReader;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;

/**
 * UN/EDIFACT Interchange Envelope parser.
 * 
 * @author [email protected]
 */
public class UNEdifactInterchangeParser implements XMLReader, NamespaceDeclarationStackAware, HierarchyChangeReader {

    private Map features = new HashMap();
	
	public static final Delimiters defaultUNEdifactDelimiters = new Delimiters().setSegment("'").setField("+").setComponent(":").setEscape("?").setDecimalSeparator(".");
	
	/**
	 * By default we are using {@link LazyMappingsRegistry} instance
	 */
	protected MappingsRegistry registry = new LazyMappingsRegistry();
	private ContentHandler contentHandler;
    private HierarchyChangeListener hierarchyChangeListener;
    private InterchangeContext interchangeContext;
    private NamespaceDeclarationStack namespaceDeclarationStack;

    public void parse(InputSource unedifactInterchange) throws IOException, SAXException {
		AssertArgument.isNotNull(unedifactInterchange, "unedifactInterchange");

        if(contentHandler == null) {
            throw new IllegalStateException("'contentHandler' not set.  Cannot parse EDI stream.");
        }

        if(registry == null) {
            throw new IllegalStateException("'mappingsRegistry' not set.  Cannot parse EDI stream.");
        }

        boolean endDocument = false;
        try {
            ControlBlockHandlerFactory handlerFactory = new UNEdifact41ControlBlockHandlerFactory(hierarchyChangeListener);
	        BufferedSegmentReader segmentReader = new BufferedSegmentReader(unedifactInterchange, defaultUNEdifactDelimiters);
	        boolean validate = getFeature(EDIParser.FEATURE_VALIDATE);
	        String segCode;
	        
	        segmentReader.mark();
	        segmentReader.setIgnoreNewLines(getFeature(EDIParser.FEATURE_IGNORE_NEWLINES));

	        contentHandler.startDocument();
	        AttributesImpl attrs = new AttributesImpl();
	        attrs.addAttribute(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, ControlBlockHandlerFactory.ENVELOPE_PREFIX, XMLConstants.XMLNS_ATTRIBUTE + ":" + ControlBlockHandlerFactory.ENVELOPE_PREFIX, "CDATA", handlerFactory.getNamespace());
            String envElementQName = ControlBlockHandlerFactory.ENVELOPE_PREFIX + ":unEdifact";
            contentHandler.startElement(handlerFactory.getNamespace(), "unEdifact", envElementQName, attrs);
	
	        while(true) {
		        segCode = segmentReader.peek(3, true);
		        if(segCode.length() == 3) {
                    interchangeContext = createInterchangeContext(segmentReader, validate, handlerFactory, namespaceDeclarationStack);
                    namespaceDeclarationStack = interchangeContext.getNamespaceDeclarationStack();

                    if(hierarchyChangeListener != null) {
                        hierarchyChangeListener.attachXMLReader(interchangeContext.getControlSegmentParser());
                    } else if (!interchangeContext.isContainerManagedNamespaceStack()) {
                        interchangeContext.getNamespaceDeclarationStack().pushReader(interchangeContext.getControlSegmentParser());
                    }

                    // Add the UN/EDIFACT namespace to the namespace stack...
                    namespaceDeclarationStack.pushNamespaces(envElementQName, handlerFactory.getNamespace(), attrs);

                    ControlBlockHandler handler = interchangeContext.getControlBlockHandler(segCode);

					interchangeContext.indentDepth.value++;
		        	handler.process(interchangeContext);
					interchangeContext.indentDepth.value--;
		        } else {
		        	break;
		        }
	        }
	        
	        contentHandler.characters(new char[] {'\n'}, 0, 1);
	        contentHandler.endElement(handlerFactory.getNamespace(), "unEdifact", envElementQName);
            endDocument = true;
        } finally {
            if (namespaceDeclarationStack != null) {
                namespaceDeclarationStack.popNamespaces();
                if(hierarchyChangeListener != null) {
                    hierarchyChangeListener.detachXMLReader();
                } else if (!interchangeContext.isContainerManagedNamespaceStack()) {
                    interchangeContext.getNamespaceDeclarationStack().popReader();
                }
            }
            if (endDocument) {
                contentHandler.endDocument();
            }
            contentHandler = null;
        }
	}

    protected InterchangeContext createInterchangeContext(BufferedSegmentReader segmentReader, boolean validate, ControlBlockHandlerFactory controlBlockHandlerFactory, NamespaceDeclarationStack namespaceDeclarationStack) {
        return new InterchangeContext(segmentReader, registry, contentHandler, getFeatures(), controlBlockHandlerFactory, namespaceDeclarationStack, validate);
    }

    public InterchangeContext getInterchangeContext() {
        return interchangeContext;
    }

    /**
	 * Set the EDI mapping model to be used in all subsequent parse operations.
	 * 

* The model can be generated through a call to the {@link EDIParser}. * * @param registry The mapping model registry. * @return This parser instance. */ public UNEdifactInterchangeParser setMappingsRegistry(MappingsRegistry registry) { AssertArgument.isNotNull(registry, "mappingsRegistry"); this.registry = registry; return this; } public ContentHandler getContentHandler() { return contentHandler; } public void setContentHandler(ContentHandler contentHandler) { this.contentHandler = contentHandler; } public void ignoreNewLines(boolean ignoreNewLines) { setFeature(EDIParser.FEATURE_IGNORE_NEWLINES, ignoreNewLines); } public void ignoreEmptyNodes(boolean ignoreEmptyNodes) { setFeature(EDIParser.FEATURE_IGNORE_EMPTY_NODES, ignoreEmptyNodes); } public void validate(boolean validate) { setFeature(EDIParser.FEATURE_VALIDATE, validate); } public Map getFeatures() { return features; } public void setFeature(String name, boolean value) { features.put(name, value); } public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { Boolean feature = features.get(name); if(feature == null) { return false; } return feature; } public void setNamespaceDeclarationStack(NamespaceDeclarationStack namespaceDeclarationStack) { this.namespaceDeclarationStack = namespaceDeclarationStack; } public void setHierarchyChangeListener(HierarchyChangeListener listener) { this.hierarchyChangeListener = listener; } /**************************************************************************** * * The following methods are currently unimplemnted... * ****************************************************************************/ public void parse(String systemId) throws IOException, SAXException { throw new UnsupportedOperationException("Operation not supports by this reader."); } public DTDHandler getDTDHandler() { return null; } public void setDTDHandler(DTDHandler arg0) { } public EntityResolver getEntityResolver() { return null; } public void setEntityResolver(EntityResolver arg0) { } public ErrorHandler getErrorHandler() { return null; } public void setErrorHandler(ErrorHandler arg0) { } public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { return null; } public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy