Package xbird.xquery.dm.coder

Source Code of xbird.xquery.dm.coder.XQEventDecoder

/*
* @(#)$Id: XQEventDecoder.java 3619 2008-03-26 07:23:03Z yui $
*
* Copyright 2006-2008 Makoto YUI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
*     Makoto YUI - initial implementation
*/
package xbird.xquery.dm.coder;

import static xbird.xquery.dm.coder.XQEventEncoder.FORCE_UTF;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.List;

import xbird.xquery.XQueryException;
import xbird.xquery.dm.instance.DocumentTableModel.DTMNodeBase;
import xbird.xquery.dm.value.AtomicValue;
import xbird.xquery.dm.value.Item;
import xbird.xquery.dm.value.Sequence;
import xbird.xquery.dm.value.XQNode;
import xbird.xquery.dm.value.sequence.ValueSequence;
import xbird.xquery.meta.DynamicContext;
import xbird.xquery.misc.QNameTable.QualifiedName;

/**
*
* <DIV lang="en"></DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
*/
public final class XQEventDecoder {

    private final ObjectInput _input;
    private final SerializationContext _serContext = new SerializationContext();

    public XQEventDecoder(ObjectInput input) {
        this._input = input;
    }

    // TODO support pipeline processing
    public XQEventDecoder(ObjectInputStream input) {
        this._input = input;
    }

    public ObjectInput getInput() {
        return _input;
    }

    public Sequence<Item> decode() throws IOException, XQueryException {
        final XDMTreeBuilder handler = new XDMTreeBuilder();
        final List<Item> items = new ArrayList<Item>(256);
        boolean prevNodeStart = false;
        final ObjectInput input = _input;
        while(true) {
            final byte ev = input.readByte();
            if(ev == XQEventEncoder.EV_EOF) {
                handler.endItem(true);
                break;
            }
            switch(ev) {
                case XQEventEncoder.EV_ATOM: {
                    final AtomicValue atom;
                    try {
                        atom = AtomicValue.readAtomicValue(input);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    handler.evAtomicValue(atom);
                    items.add(atom);
                    break;
                }
                case XQEventEncoder.EV_DTM_NODE: {
                    final DTMNodeBase dtmNode;
                    try {
                        dtmNode = DTMNodeBase.readFrom(input, _serContext);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    items.add(dtmNode);
                    break;
                }
                case XQEventEncoder.EV_NODE_START:
                    prevNodeStart = true;
                    continue;
                case XQEventEncoder.EV_NODE_END: {
                    prevNodeStart = false;
                    handler.reset();
                    break;
                }
                case XQEventEncoder.EV_END_ITEM:
                    handler.endItem(false);
                    break;
                case XQEventEncoder.EV_START_DOC:
                    handler.evStartDocument();
                    break;
                case XQEventEncoder.EV_END_DOC:
                    handler.evEndDocument();
                    break;
                case XQEventEncoder.EV_START_ELEM: {
                    String prefix = readString(input);
                    String localName = readString(input);
                    String namespaceURI = readString(input);
                    handler.evStartElement(prefix, localName, namespaceURI);
                    break;
                }
                case XQEventEncoder.EV_END_ELEM: {
                    String prefix = readString(input);
                    String localName = readString(input);
                    String namespaceURI = readString(input);
                    handler.evEndElement(prefix, localName, namespaceURI);
                    break;
                }
                case XQEventEncoder.EV_ATTR: {
                    QualifiedName qname = QualifiedName.readFrom(input);
                    String value = readString(input);
                    handler.evAttribute(qname, value);
                    break;
                }
                case XQEventEncoder.EV_NAMESPACE: {
                    String prefix = readString(input);
                    String uri = readString(input);
                    handler.evNamespace(prefix, uri);
                    break;
                }
                case XQEventEncoder.EV_TEXT: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evText(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_CDATA: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evCData(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_COMMENT: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evComment(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_PI: {
                    String target = readString(input);
                    String data = readString(input);
                    handler.evProcessingInstruction(target, data);
                    break;
                }
                default:
                    throw new IllegalStateException("Illegal event: " + ev);
            }
            if(prevNodeStart) {// harvest nodes
                XQNode node = handler.harvest();
                if(node != null) {
                    items.add(node);
                    prevNodeStart = false;
                }
            }
        }
        if(items.isEmpty()) {
            return ValueSequence.EMPTY_SEQUENCE;
        }
        if(items.size() == 1) {
            return items.get(0);
        }
        return new ValueSequence(items, DynamicContext.DUMMY);
    }

    /**
     * @param null if there are no items.
     */
    public Item decodeItem(final XDMTreeBuilder handler) throws IOException, XQueryException {
        final ObjectInput input = _input;
        while(true) {
            final byte ev = input.readByte();
            switch(ev) {
                case XQEventEncoder.EV_ATOM: {
                    final AtomicValue atom;
                    try {
                        atom = AtomicValue.readAtomicValue(input);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    return atom;
                }
                case XQEventEncoder.EV_DTM_NODE: {
                    final DTMNodeBase dtmNode;
                    try {
                        dtmNode = DTMNodeBase.readFrom(input, _serContext);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    return dtmNode;
                }
                case XQEventEncoder.EV_NODE_START:
                    final XQNode node = decodeNode(input, handler, _serContext);
                    return node;
                case XQEventEncoder.EV_TEXT: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evText(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_END_ITEM:
                    break; // ignorable
                case XQEventEncoder.EV_EOF:
                    return null;
                default:
                    throw new IllegalStateException("Illegal event: " + ev);
            }
        }
    }

    private static XQNode decodeNode(final ObjectInput input, final XDMTreeBuilder handler, final SerializationContext serContext)
            throws IOException, XQueryException {
        while(true) {
            final byte ev = input.readByte();
            switch(ev) {
                case XQEventEncoder.EV_NODE_END: {
                    final XQNode node = handler.harvest();
                    handler.reset();
                    return node;
                }
                case XQEventEncoder.EV_DTM_NODE: {
                    final DTMNodeBase dtmNode;
                    try {
                        dtmNode = DTMNodeBase.readFrom(input, serContext);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    return dtmNode;
                }
                case XQEventEncoder.EV_START_DOC:
                    handler.evStartDocument();
                    break;
                case XQEventEncoder.EV_END_DOC:
                    handler.evEndDocument();
                    break;
                case XQEventEncoder.EV_START_ELEM: {
                    String prefix = readString(input);
                    String localName = readString(input);
                    String namespaceURI = readString(input);
                    handler.evStartElement(prefix, localName, namespaceURI);
                    break;
                }
                case XQEventEncoder.EV_END_ELEM: {
                    String prefix = readString(input);
                    String localName = readString(input);
                    String namespaceURI = readString(input);
                    handler.evEndElement(prefix, localName, namespaceURI);
                    break;
                }
                case XQEventEncoder.EV_ATTR: {
                    QualifiedName qname = QualifiedName.readFrom(input);
                    String value = readString(input);
                    handler.evAttribute(qname, value);
                    break;
                }
                case XQEventEncoder.EV_NAMESPACE: {
                    String prefix = readString(input);
                    String uri = readString(input);
                    handler.evNamespace(prefix, uri);
                    break;
                }
                case XQEventEncoder.EV_TEXT: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evText(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_CDATA: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evCData(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_COMMENT: {
                    final int length = input.readInt();
                    final char[] ch = new char[length];
                    for(int i = 0; i < length; i++) {
                        ch[i] = input.readChar();
                    }
                    handler.evComment(ch, 0, length);
                    break;
                }
                case XQEventEncoder.EV_PI: {
                    String target = readString(input);
                    String data = readString(input);
                    handler.evProcessingInstruction(target, data);
                    break;
                }
                default:
                    throw new IllegalStateException("Illegal event: " + ev);
            }
        }
    }

    public void redirectTo(ObjectOutput out) throws IOException {
        final ObjectInput input = _input;
        while(true) {
            final byte ev = input.readByte();
            out.writeByte(ev);
            if(ev == XQEventEncoder.EV_EOF) {
                return;
            }
            switch(ev) {
                case XQEventEncoder.EV_ATOM: {
                    final AtomicValue atom;
                    try {
                        atom = AtomicValue.readAtomicValue(input);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    AtomicValue.writeAtomicValue(atom, out);
                    break;
                }
                case XQEventEncoder.EV_DTM_NODE: {
                    try {
                        DTMNodeBase.redirect(input, out);
                    } catch (ClassNotFoundException e) {
                        throw new IllegalStateException(e);
                    }
                    break;
                }
                case XQEventEncoder.EV_NODE_START:
                    break;
                case XQEventEncoder.EV_NODE_END:
                    break;
                case XQEventEncoder.EV_START_DOC:
                    break;
                case XQEventEncoder.EV_END_DOC:
                    break;
                case XQEventEncoder.EV_START_ELEM: {
                    redirectString(input, out);
                    redirectString(input, out);
                    redirectString(input, out);
                    break;
                }
                case XQEventEncoder.EV_END_ELEM: {
                    redirectString(input, out);
                    redirectString(input, out);
                    redirectString(input, out);
                    break;
                }
                case XQEventEncoder.EV_ATTR: {
                    QualifiedName qname = QualifiedName.readFrom(input);
                    qname.writeExternal(out);
                    redirectString(input, out);
                    break;
                }
                case XQEventEncoder.EV_NAMESPACE:
                    redirectString(input, out);
                    redirectString(input, out);
                    break;
                case XQEventEncoder.EV_TEXT: {
                    final int length = input.readInt();
                    out.writeInt(length);
                    for(int i = 0; i < length; i++) {
                        char c = input.readChar();
                        out.writeChar(c);
                    }
                    break;
                }
                case XQEventEncoder.EV_CDATA: {
                    final int length = input.readInt();
                    out.writeInt(length);
                    for(int i = 0; i < length; i++) {
                        char c = input.readChar();
                        out.writeChar(c);
                    }
                    break;
                }
                case XQEventEncoder.EV_COMMENT: {
                    final int length = input.readInt();
                    out.writeInt(length);
                    for(int i = 0; i < length; i++) {
                        char c = input.readChar();
                        out.writeChar(c);
                    }
                    break;
                }
                case XQEventEncoder.EV_PI:
                    redirectString(input, out);
                    redirectString(input, out);
                    break;
                case XQEventEncoder.EV_END_ITEM:
                    break;
                default:
                    throw new IllegalStateException("Illegal event: " + ev);
            }
        }
    }

    public void close() {
        try {
            _input.close();
        } catch (IOException e) {
            ;
        }
    }

    private static String readString(final ObjectInput in) throws IOException {
        if(FORCE_UTF) {
            return in.readUTF();
        }
        final int len = in.readInt();
        final char[] chrs = new char[len];
        for(int i = 0; i < len; i++) {
            chrs[i] = in.readChar();
        }
        return new String(chrs);
    }

    private static void redirectString(final ObjectInput in, final ObjectOutput out)
            throws IOException {
        if(FORCE_UTF) {
            String s = in.readUTF();
            out.writeUTF(s);
        }
        final int len = in.readInt();
        out.writeInt(len);
        for(int i = 0; i < len; i++) {
            char c = in.readChar();
            out.writeChar(c);
        }
    }
}
TOP

Related Classes of xbird.xquery.dm.coder.XQEventDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.